Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9c756e2c4 | |||
| 98938e6126 | |||
| 396ae3bcd2 | |||
| 86eb55d564 |
+1
-1
@@ -32,7 +32,7 @@ replacement, and each removed path, column or flag.
|
|||||||
and built from SCB, GeoNames, Trafikverket NVDB and the US Census Bureau, and an
|
and built from SCB, GeoNames, Trafikverket NVDB and the US Census Bureau, and an
|
||||||
`address` record over one consistent draw of them. `sv_SE.address` and
|
`address` record over one consistent draw of them. `sv_SE.address` and
|
||||||
`en_US.address` read those records, so `en_US.address.street` no longer carries
|
`en_US.address` read those records, so `en_US.address.street` no longer carries
|
||||||
`name` and `suffix`, and a locale folder loads only beside `geo`.
|
`name` and `suffix`, and a locale folder loads only beside `geo`.
|
||||||
- `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or
|
- `{date(from,to,'layout')}` and `{time('layout')}`: a second between two days, or
|
||||||
within one, in a quoted Go layout. `sv_SE.date`, `en_US.date`, `sv_SE.time` and
|
within one, in a quoted Go layout. `sv_SE.date`, `en_US.date`, `sv_SE.time` and
|
||||||
`en_US.time` render through them, so `date.year`, `date.month`, `date.day` and
|
`en_US.time` render through them, so `date.year`, `date.month`, `date.day` and
|
||||||
|
|||||||
@@ -540,7 +540,8 @@ between the two days is reachable, so a layout with a clock draws the time too.
|
|||||||
The quotes delimit a layout outside a selector only, so `[O'Fallon]` in an
|
The quotes delimit a layout outside a selector only, so `[O'Fallon]` in an
|
||||||
argument stays a name. Rejected at `New`: a bound that is no calendar date, or not
|
argument stays a name. Rejected at `New`: a bound that is no calendar date, or not
|
||||||
before the other; an unquoted layout, naming the quoted one; a layout naming no field, which is text;
|
before the other; an unquoted layout, naming the quoted one; a layout naming no field, which is text;
|
||||||
and for `time` a layout naming a date field, naming `date`. `{seq()}` spans `Fake`
|
for `date` a layout naming no date field, naming `time`; and for `time` a layout
|
||||||
|
naming a date field, naming `date`. `{seq()}` spans `Fake`
|
||||||
calls and `repeat`, resets with a new generator, and is the natural primary key for
|
calls and `repeat`, resets with a new generator, and is the natural primary key for
|
||||||
the SQL example above.
|
the SQL example above.
|
||||||
|
|
||||||
@@ -617,7 +618,7 @@ its groups by name; the unnamed group spans them all.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{ "format": "{payer} pays {payee}; signed {signature}",
|
{ "format": "{payer} pays {payee}; signed {signature}",
|
||||||
"payer": { "format": "{/sv_SE.person.first} {/sv_SE.person.last}", "drawGroup": "payer" },
|
"payer": { "format": "{/sv_SE.person.first} {/sv_SE.person.last}", "drawGroup": "payer" },
|
||||||
"payee": "{/sv_SE.person.first} {/sv_SE.person.last}",
|
"payee": "{/sv_SE.person.first} {/sv_SE.person.last}",
|
||||||
"signature": { "format": "{/sv_SE.person.last}", "drawGroup": "payer" } }
|
"signature": { "format": "{/sv_SE.person.last}", "drawGroup": "payer" } }
|
||||||
```
|
```
|
||||||
@@ -1079,11 +1080,13 @@ renamed or retyped line is a major.
|
|||||||
load, since nothing could then select it.
|
load, since nothing could then select it.
|
||||||
- **The Swedish ids draw Skatteverket's test series.** A Luhn-valid personnummer
|
- **The Swedish ids draw Skatteverket's test series.** A Luhn-valid personnummer
|
||||||
over a random birth number may be a living person's; 238 and 239 after any date
|
over a random birth number may be a living person's; 238 and 239 after any date
|
||||||
are blocked from assignment, so the shipped `personnummer` and
|
are blocked from assignment, so the shipped `personnummer` and
|
||||||
`samordningsnummer` use those. They sit in a `birth-number` table under `sex`
|
`samordningsnummer` use those. They sit in a `birth-number` table under `sex`
|
||||||
rather than as a column of it: the render's shared draw of the family is what
|
rather than as a column of it: the render's shared draw of the family is what
|
||||||
makes the number and the name agree on sex, and `sex` stays one shape across
|
makes the number and the name agree on sex, and `sex` stays one shape across
|
||||||
locales instead of collecting every sex-keyed id fact.
|
locales instead of collecting every sex-keyed id fact. A samordningsnummer's
|
||||||
|
day, the birthday plus 60, is drawn from 61 to 88, valid in every month, rather
|
||||||
|
than computed from the date drawn.
|
||||||
- **The US given names come from a mirror of the SSA file.** ssa.gov refuses a
|
- **The US given names come from a mirror of the SSA file.** ssa.gov refuses a
|
||||||
client outside the US, so `names-us.py` reads a GitHub copy that ends at 2020,
|
client outside the US, so `names-us.py` reads a GitHub copy that ends at 2020,
|
||||||
which a count over the births since 1930 barely feels; `--names` takes the
|
which a count over the births since 1930 barely feels; `--names` takes the
|
||||||
|
|||||||
+6
-6
@@ -26,12 +26,12 @@ func benchPath(b *testing.B, dir, path string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPerson(b *testing.B) { benchPath(b, "data", "sv_SE.person") }
|
func BenchmarkPerson(b *testing.B) { benchPath(b, "data", "sv_SE.person") }
|
||||||
func BenchmarkAddress(b *testing.B) { benchPath(b, "data", "sv_SE.address") }
|
func BenchmarkAddress(b *testing.B) { benchPath(b, "data", "sv_SE.address") }
|
||||||
func BenchmarkWord(b *testing.B) { benchPath(b, "data", "sv_SE.word") }
|
func BenchmarkWord(b *testing.B) { benchPath(b, "data", "sv_SE.word") }
|
||||||
func BenchmarkCreditcard(b *testing.B) { benchPath(b, "data", "misc.creditcard") }
|
func BenchmarkCreditcard(b *testing.B) { benchPath(b, "data", "misc.creditcard") }
|
||||||
func BenchmarkSSN(b *testing.B) { benchPath(b, "data", "sv_SE.personnummer") }
|
func BenchmarkPersonnummer(b *testing.B) { benchPath(b, "data", "sv_SE.personnummer") }
|
||||||
func BenchmarkUUIDv7(b *testing.B) { benchPath(b, "data", "misc.uuid") }
|
func BenchmarkUUIDv7(b *testing.B) { benchPath(b, "data", "misc.uuid") }
|
||||||
|
|
||||||
func tmpData(b *testing.B, name, body string) string {
|
func tmpData(b *testing.B, name, body string) string {
|
||||||
b.Helper()
|
b.Helper()
|
||||||
|
|||||||
+12
-9
@@ -472,17 +472,14 @@ func iban(r rng, cc string) string {
|
|||||||
|
|
||||||
const dayLayout = "2006-01-02"
|
const dayLayout = "2006-01-02"
|
||||||
|
|
||||||
// The two instants a layout is proved against: alike in nothing, so a layout that
|
// Alike in no field; layoutDay differs from layoutProbe in its date fields only.
|
||||||
// formats them alike names no field, and one that tells their days apart at the same
|
|
||||||
// clock names a date field.
|
|
||||||
var (
|
var (
|
||||||
layoutProbe = time.Date(2001, 2, 3, 4, 5, 6, 0, time.UTC)
|
layoutProbe = time.Date(2001, 2, 3, 4, 5, 6, 0, time.UTC)
|
||||||
layoutProbe2 = time.Date(2010, 11, 12, 13, 14, 15, 0, time.UTC)
|
layoutProbe2 = time.Date(2010, 11, 12, 13, 14, 15, 0, time.UTC)
|
||||||
layoutDay = time.Date(2010, 11, 12, 4, 5, 6, 0, time.UTC)
|
layoutDay = time.Date(2010, 11, 12, 4, 5, 6, 0, time.UTC)
|
||||||
)
|
)
|
||||||
|
|
||||||
// layoutArg is the Go layout a quoted arg holds; unquoted, it is refused naming the
|
// layoutArg is the Go layout a quoted arg holds, refused when unquoted or constant.
|
||||||
// quoted spelling, since a layout may carry the comma that splits args.
|
|
||||||
func layoutArg(a string) (string, error) {
|
func layoutArg(a string) (string, error) {
|
||||||
if len(a) < 2 || a[0] != '\'' || a[len(a)-1] != '\'' {
|
if len(a) < 2 || a[0] != '\'' || a[len(a)-1] != '\'' {
|
||||||
return "", fmt.Errorf("layout %s is not quoted; write '%s'", a, strings.Trim(a, "'"))
|
return "", fmt.Errorf("layout %s is not quoted; write '%s'", a, strings.Trim(a, "'"))
|
||||||
@@ -503,8 +500,8 @@ func layoutOf(a string) string {
|
|||||||
return layout
|
return layout
|
||||||
}
|
}
|
||||||
|
|
||||||
// layoutArity checks a call that ends in a layout takes n args; an unquoted layout
|
// layoutArity checks a call ending in a layout takes n args, naming the quoted
|
||||||
// carrying a comma splits into more, so the error names its quoted spelling.
|
// layout when an unquoted one split into more.
|
||||||
func layoutArity(name string, n int, a []string) error {
|
func layoutArity(name string, n int, a []string) error {
|
||||||
if len(a) == n {
|
if len(a) == n {
|
||||||
return nil
|
return nil
|
||||||
@@ -531,8 +528,14 @@ func dateArgs(_ map[string]node, a []string) error {
|
|||||||
if !from.Before(to) {
|
if !from.Before(to) {
|
||||||
return fmt.Errorf("date(from,to,layout): from %s is not before to %s", a[0], a[1])
|
return fmt.Errorf("date(from,to,layout): from %s is not before to %s", a[0], a[1])
|
||||||
}
|
}
|
||||||
_, err = layoutArg(a[2])
|
layout, err := layoutArg(a[2])
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if layoutProbe.Format(layout) == layoutDay.Format(layout) {
|
||||||
|
return fmt.Errorf("date(from,to,layout): '%s' names no date field; write time('%s')", layout, layout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func timeArg(_ map[string]node, a []string) error {
|
func timeArg(_ map[string]node, a []string) error {
|
||||||
|
|||||||
@@ -310,6 +310,7 @@ func TestBuiltinDateArgs(t *testing.T) {
|
|||||||
`"{time(15:04)}"`: "'15:04'",
|
`"{time(15:04)}"`: "'15:04'",
|
||||||
`"{time('2006-01-02 15:04')}"`: "date(",
|
`"{time('2006-01-02 15:04')}"`: "date(",
|
||||||
`"{time('x')}"`: "text",
|
`"{time('x')}"`: "text",
|
||||||
|
`"{date(1990-01-01,1990-12-31,'15:04')}"`: "time('15:04')",
|
||||||
} {
|
} {
|
||||||
_, err := compile(parse(t, tmpl))
|
_, err := compile(parse(t, tmpl))
|
||||||
if err == nil || !strings.Contains(err.Error(), want) {
|
if err == nil || !strings.Contains(err.Error(), want) {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ CACHE = Path(__file__).resolve().parent / "cache"
|
|||||||
SHEETS = {"f": "Tilltalsnamn kvinnor", "m": "Tilltalsnamn män"}
|
SHEETS = {"f": "Tilltalsnamn kvinnor", "m": "Tilltalsnamn män"}
|
||||||
SURNAMES = "Efternamn"
|
SURNAMES = "Efternamn"
|
||||||
NAME = re.compile(r"^[^\W\d_]{2,}([ '-][^\W\d_]{2,})*$")
|
NAME = re.compile(r"^[^\W\d_]{2,}([ '-][^\W\d_]{2,})*$")
|
||||||
PARTICLES = {"af", "av", "de", "den", "der", "di", "du", "la", "le", "van", "von"}
|
PARTICLES = {"af", "av", "da", "de", "del", "den", "der", "di", "dos", "du", "la", "le", "van", "von"}
|
||||||
|
|
||||||
|
|
||||||
def cased(name):
|
def cased(name):
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ SURNAMES = "https://www2.census.gov/topics/genealogy/2010surnames/names.zip"
|
|||||||
OUT = Path(__file__).resolve().parent.parent / "data" / "en_US"
|
OUT = Path(__file__).resolve().parent.parent / "data" / "en_US"
|
||||||
CACHE = Path(__file__).resolve().parent / "cache"
|
CACHE = Path(__file__).resolve().parent / "cache"
|
||||||
MC = re.compile(r"^Mc([a-z])")
|
MC = re.compile(r"^Mc([a-z])")
|
||||||
|
PLACEHOLDERS = {"Baby", "Female", "Infant", "Male", "Notnamed", "Unknown", "Unnamed"}
|
||||||
|
|
||||||
|
|
||||||
def csv_or_zip_rows(data, member):
|
def csv_or_zip_rows(data, member):
|
||||||
@@ -41,7 +42,7 @@ def csv_or_zip_rows(data, member):
|
|||||||
def given(data, from_year):
|
def given(data, from_year):
|
||||||
counts = collections.Counter()
|
counts = collections.Counter()
|
||||||
for r in csv_or_zip_rows(data, r"yob\d{4}\.txt"):
|
for r in csv_or_zip_rows(data, r"yob\d{4}\.txt"):
|
||||||
if len(r) >= 4 and r[3].isdigit() and int(r[3]) >= from_year:
|
if len(r) >= 4 and r[3].isdigit() and int(r[3]) >= from_year and r[0] not in PLACEHOLDERS:
|
||||||
counts[(r[0], r[1].lower())] += int(r[2])
|
counts[(r[0], r[1].lower())] += int(r[2])
|
||||||
return counts
|
return counts
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,6 @@ Ayla f 23690
|
|||||||
Aylin f 12970
|
Aylin f 12970
|
||||||
Azalea f 7052
|
Azalea f 7052
|
||||||
Azariah m 3910
|
Azariah m 3910
|
||||||
Baby m 6059
|
|
||||||
Bailee f 14798
|
Bailee f 14798
|
||||||
Bailey f 102509
|
Bailey f 102509
|
||||||
Bailey m 20062
|
Bailey m 20062
|
||||||
@@ -468,6 +467,7 @@ Bobbie f 78660
|
|||||||
Bobbie m 14570
|
Bobbie m 14570
|
||||||
Bobby f 8180
|
Bobby f 8180
|
||||||
Bobby m 299694
|
Bobby m 299694
|
||||||
|
Bode m 3348
|
||||||
Bodhi m 8375
|
Bodhi m 8375
|
||||||
Bodie m 4314
|
Bodie m 4314
|
||||||
Bonita f 35102
|
Bonita f 35102
|
||||||
@@ -1674,7 +1674,6 @@ Imran m 3415
|
|||||||
Ina f 15116
|
Ina f 15116
|
||||||
India f 21903
|
India f 21903
|
||||||
Inez f 22303
|
Inez f 22303
|
||||||
Infant m 4133
|
|
||||||
Ingrid f 25835
|
Ingrid f 25835
|
||||||
Ira m 33974
|
Ira m 33974
|
||||||
Irene f 150081
|
Irene f 150081
|
||||||
@@ -2615,6 +2614,7 @@ Lynn f 180561
|
|||||||
Lynn m 44787
|
Lynn m 44787
|
||||||
Lynne f 61433
|
Lynne f 61433
|
||||||
Lynnette f 15029
|
Lynnette f 15029
|
||||||
|
Lynwood m 3349
|
||||||
Lyric f 17861
|
Lyric f 17861
|
||||||
Lyric m 3810
|
Lyric m 3810
|
||||||
Mabel f 24359
|
Mabel f 24359
|
||||||
@@ -3274,6 +3274,7 @@ Ricky m 221617
|
|||||||
Rico m 9313
|
Rico m 9313
|
||||||
Ridge m 5086
|
Ridge m 5086
|
||||||
Rigoberto m 11018
|
Rigoberto m 11018
|
||||||
|
Rihanna f 5970
|
||||||
Rikki f 6846
|
Rikki f 6846
|
||||||
Riley f 117947
|
Riley f 117947
|
||||||
Riley m 92931
|
Riley m 92931
|
||||||
@@ -3804,6 +3805,7 @@ Tylor m 7980
|
|||||||
Tyquan m 3547
|
Tyquan m 3547
|
||||||
Tyra f 14416
|
Tyra f 14416
|
||||||
Tyree m 13959
|
Tyree m 13959
|
||||||
|
Tyrel m 3354
|
||||||
Tyrell m 15575
|
Tyrell m 15575
|
||||||
Tyrese m 8673
|
Tyrese m 8673
|
||||||
Tyron m 7456
|
Tyron m 7456
|
||||||
@@ -3814,8 +3816,6 @@ Tyson m 44397
|
|||||||
Ulises m 10786
|
Ulises m 10786
|
||||||
Ulysses m 13923
|
Ulysses m 13923
|
||||||
Unique f 7103
|
Unique f 7103
|
||||||
Unknown f 9225
|
|
||||||
Unknown m 8912
|
|
||||||
Uriah m 9786
|
Uriah m 9786
|
||||||
Uriel m 17743
|
Uriel m 17743
|
||||||
Urijah m 3365
|
Urijah m 3365
|
||||||
|
|||||||
|
@@ -243,7 +243,7 @@ func (t *table) proveNamesInsideParent() error {
|
|||||||
for r := 0; r < t.rows(); r++ {
|
for r := 0; r < t.rows(); r++ {
|
||||||
k := t.cell(r, t.parent) + "\t" + t.cell(r, t.name)
|
k := t.cell(r, t.parent) + "\t" + t.cell(r, t.name)
|
||||||
if first, dup := inside[k]; dup {
|
if first, dup := inside[k]; dup {
|
||||||
return fmt.Errorf("%s line %d: name %q repeats line %d inside %s %q; a name selects one row inside its parent", t.file, r+2, t.cell(r, t.name), first+2, t.columns[t.parent], t.cell(r, t.parent))
|
return fmt.Errorf("%s line %d: name %q repeats line %d inside %s %q; a name selects one row inside its parent; drop one, or add a key column", t.file, r+2, t.cell(r, t.name), first+2, t.columns[t.parent], t.cell(r, t.parent))
|
||||||
}
|
}
|
||||||
inside[k] = r
|
inside[k] = r
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user