Skip to content

Releases: AmritD/HippoDatamus

HippoDatamus 0.7.0

Choose a tag to compare

@AmritD AmritD released this 17 Sep 20:26

Output changes

  • A Gaussian column produced different values on Windows and on Linux. The same
    configuration and the same seed gave different bytes depending on the operating system, which
    is the one thing this product promises will not happen. It affected roughly 1 row in 125, and
    only that column type.

    The cause was the Box-Muller transform, which needs a sine. .NET forwards Math.Sin, and
    Math.Log and Math.Exp with it, to the platform's own C maths library, and the results
    differ by one unit in the last place. Math.Sqrt does not - IEEE-754 defines it exactly.

    A Gaussian column is now drawn by the Marsaglia polar method, which needs no sine, over a
    logarithm computed from IEEE-exact arithmetic rather than from the platform. The distribution
    is unchanged.

    A Gaussian column therefore produces different values than it did in 0.6.0, for the same
    configuration and seed.
    No other column type is affected: the two operating systems were
    already byte-identical on the other 63 columns of the all-column-types sample, and are now
    identical on all 64.

Fixed

  • The application closed itself when two columns had the same name. Adding a second column
    and pressing Generate was enough to do it: every new column arrived named "New Column", and
    the dependency graph built a lookup keyed on the name, so the second one raised a duplicate-key
    error. It surfaced as the window vanishing with no message, and nothing was written.

    This is what failed Microsoft Store certification for 0.6.0, under 10.1.2.10 Functionality:
    "the product crashes after trying to create a file."

    Three things were wrong and all three are fixed. New columns are now named "New Column 2",
    "New Column 3" and so on, so the case is not created by using the application normally. Two
    columns given the same name deliberately are now reported as a validation error that names the
    column, rather than raising an exception - as are two columns sharing an internal id, which is
    what a configuration file gets when a column block is copied by hand. And checking a
    configuration can no longer take the application down: that step ran before the error handling
    that covers the run itself, so anything unexpected in it reached the dispatcher and terminated
    the process, where it now reports what went wrong and leaves the application usable.

HippoDatamus 0.6.0

Choose a tag to compare

@AmritD AmritD released this 15 Sep 20:31

Added

  • File, Open Sample opens one of the sample schemas that ship with the application, without
    going through a file dialog. On a Store install the samples live inside the package, which
    Windows does not let you browse, so they were shipped and unreachable. The list shows each
    sample's column and row count, simplest first.

Output changes

  • Names now come from every English locale, not just the American one. First names go from
    3,007 to 3,954 and last names from 473 to 911 - last names nearly double, because the
    Australian, Indian, Nigerian, and South African lists overlap the American one far less than
    their first names do. A Full Name column's domain grows from 1.4 million to 3.6 million.

    A First Name, Last Name, or Full Name column therefore produces different values than it
    did in 0.5.0, for the same configuration and seed.
    Nothing else about those columns changes:
    the count, the seed derivation, and the uniqueness guarantee are all as they were.

    Duplicates between locales are dropped, ignoring case, so the pool does not hold both
    McCullough and Mccullough. en_AU_ocker and en_BORK are left out as joke locales.

Fixed

  • Choosing a source file for a File Column now happens from a Browse... button beside
    the Path field, as it would on a web form. It used to be a single button beneath the whole
    settings panel, which for this column type sits below six settings and their captions - off
    the bottom of the window until you scrolled, for the control most people reach for first.
  • A Full Name column drew from two different sets depending on its Unique setting: the
    random draw came from Bogus's own composed name while the indexed one walked the first and
    last name lists. Both now use the lists.
  • Privacy page wording, on the website only.

HippoDatamus 0.5.0

Choose a tag to compare

@AmritD AmritD released this 24 Aug 03:23

First public release.

Added

  • Desktop application for building a schema column by column, each showing its type and
    settings at a glance.
  • Command-line tool taking a .yaml configuration, for scripted and CI use.
  • 59 column types across identifiers, names, addresses, finance, internet, commerce, text,
    numbers, dates, and structure. Full inventory in
    docs/column-types-review.md.
  • Reproducible output. The same configuration and the same seed always produce the same
    data, on any machine. Column ids take part in seed derivation, so sharing a dataset means
    sharing the .yaml rather than the seed.
  • CSV, JSON, and Excel output. Every value is formatted through one invariant-culture path,
    and each format's line ending is written explicitly - CRLF for CSV, as RFC 4180 defines a
    record, and LF for JSON. A given configuration and seed therefore produce the same bytes on
    every platform, so a checksum of generated output is worth taking.
  • Pick lists with a per-row count: a cell can hold several distinct values, joined by a
    separator in CSV and Excel and written as a real array in JSON.
  • File-backed columns that draw values from a column of an existing spreadsheet or delimited
    file, with the same per-row options as a pick list. Paths are stored relative to the
    configuration and use forward slashes, so a schema and its sources move together across
    operating systems.
  • Column import from a spreadsheet's header row, so an existing file becomes a starting
    schema.
  • Template columns composing values from other columns, with .NET format strings
    ({price:0.00}) applied in the invariant culture.
  • Unique constraints, single-column and composite, validated against the domain size before
    a run starts rather than failing partway through.
  • Helper columns excluded from the output while still driving templates and constraints.
  • Configuration bundles (.hippo) sealing a schema together with every file it reads, so a
    scenario can be handed over as one artefact. The command-line tool takes a bundle directly.
  • Dates without a time component, and Excel date cells that render as dates rather than
    serial numbers.
  • Email addresses that cannot be delivered. Email uses real domains by default, because
    that is what makes generated data convincing. Turning on UseFixedDomain puts every address
    on one domain, pre-filled with example.com - reserved by IANA and guaranteed never to accept
    mail - so the option is enough on its own without knowing which domains are safe. Only the
    domain changes; the local part is generated the same way either way.
  • An MCP server exposing the application to an agent, so the UI can be driven and asserted
    on without a human at the keyboard.

Fixed

Found by a review that verified behaviour rather than reading code, and fixed before release:

  • Generating straight after launch failed on a Store install. The default output path was the
    working directory, which for a packaged app is the read-only package folder. Unpacked from a zip
    it is wherever you put the folder, so this only ever affected the packaged build, and only until
    you chose an output path yourself. It now defaults to your Documents folder.

  • A template read NULL from any column declared below it. Building the dependency graph
    reset each column's edge list as it went, discarding the edges a template earlier in the schema
    had already added. The template then generated before the columns it reads. It looked like
    "references only work if the column is above the template", but it was less predictable than
    that: whether a given reference survived depended on where the discarded edge left that column
    in the queue, so one schema could resolve one reference and null another. Templates now resolve
    their columns wherever those columns are declared, including through a chain of templates, and a
    circular reference is reported rather than producing data.

  • Generation was far slower than it needed to be. A hundred thousand rows of a
    twelve-column order table took 102 seconds; the same run now takes 0.66 seconds, and a
    million rows of CSV takes about four. Output is byte-identical to before - verified against a
    baseline generated by the old code - so nothing about the data changed, only the speed.
    Measured numbers are published at hippodatamus.com/docs/performance.

  • A template's number format followed the machine's locale. {price:0.00} produced 1.50
    on one machine and 1,50 on another where the locale uses a decimal comma - the same
    configuration and seed giving different data. Number formats are now locale-independent, like
    everything else written out.

  • Password's maximum length did nothing. Every password came out exactly MinLength
    characters; MinLength: 12, MaxLength: 40 produced twelve, every row. Each row now draws a
    length from the range.

  • A unique combination containing a column with unbounded values was silently unenforced. A
    combination needs every column in it to have a countable set of values, and one that does not
    cannot take part - but the rule was accepted without comment and then applied by nothing at
    all. It is now reported before the run. Marking such a column unique on its own still works,
    as it always did.

  • Currency Code could produce a constant column. Used inside a unique combination it
    returned USD for every row, and the combination itself came out with duplicates, while
    validation reported the request as satisfiable. It is now rejected with a message instead.
    Ordinary use was never affected and always produced real codes.

  • Generated line endings followed the platform. The same configuration produced CRLF on
    Windows and LF on Linux, which made a checksum of output unportable. Both formats now write
    their line endings explicitly.

Changed

  • Excel reading and writing was rebuilt on a different library, for licence reasons. The
    binaries are about 6 MB smaller each as a result, and every component HippoDatamus ships is
    now under a permissive licence. The full list travels in THIRD-PARTY-NOTICES.txt inside
    every download.
  • The legacy .xls format is no longer supported, for reading or writing. No permissively
    licensed library handles it. Use .xlsx, or CSV for anything larger than a worksheet holds.

Known limitations

  • Pre-release. The configuration format and generated output may change below 1.0.
  • Windows and Linux only. No macOS build.
  • The portable Windows download is unsigned, so Windows may warn that the publisher is
    unrecognised. The Microsoft Store build does not.
  • Currency Code cannot be marked unique, on its own or in a combination. Its values cannot
    be enumerated, so distinct ones cannot be produced on demand. This is now reported rather than
    silently producing duplicates.
  • Base62 Id is sequential, not random. It is derived from the row number, so row 0 is 0
    and two Base62 columns in one schema hold the same values. Use Nano Id or Guid for
    something unpredictable.
  • Email still defaults to real domains such as gmail.com, because realistic data is the
    common case. Turn on UseFixedDomain when the data might reach something that sends mail.
    Domain, URL and Username have no equivalent option - nothing can be delivered to them.

Windows: the Microsoft Store build is signed by Microsoft and installs without a warning. The portable zip below is not signed, so SmartScreen will say the publisher is unrecognised.

Verify a download against SHA256SUMS.txt:

sha256sum -c SHA256SUMS.txt --ignore-missing