This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

Python and Viv · Strings

Numbers from text

What to notice

Open the Viv in the workbench The atlas of the Viv py2viv refuses this Python (the reason is in its column).
Python parse_numbers.py · 41 lines
Viv parse_numbers.viv · 49 lines
py2viv refuses parse_numbers.py
1 the input, one reading per line
4LOG = [
5 "station=north temp=21.5 rain=0",
6 "station=south temp=18.25 rain=12",
7 "station=east temp=-3.0 rain=4",
8 "# a comment line",
9 "station=west temp=1e1 rain=7",
10]
2LOG = [
3 "station=north temp=21.5 rain=0",
4 "station=south temp=18.25 rain=12",
5 "station=east temp=-3.0 rain=4",
6 "# a comment line",
7 "station=west temp=1e1 rain=7"
8]
py2viv refuses this program:
parse_numbers.py:16:22: not numeric Python: unpacking a list of strings (lifted by R5)
            key, value = part.split("=")
                         ^^^^^^^^^^^^^^^
  Only several returned values, a vector (its rows for a matrix are not unpacked) and a shape unpack.
parse_numbers.py:28:18: not numeric Python: appending a value of unknown type to a list (lifted by R17)
        names.append(f["station"])
                     ^^^^^^^^^^^^
  A list py2viv grows holds numbers, or rows of numbers (a new list, a copy, or a tuple).
parse_numbers.py:29:18: not numeric Python: appending a value of unknown type to a list (lifted by R17)
        temps.append(float(f["temp"]))
                     ^^^^^^^^^^^^^^^^
  A list py2viv grows holds numbers, or rows of numbers (a new list, a copy, or a tuple).
3 constructs outside the numeric subset (tools/py2viv/SUBSET.md)
2 read the fields of one line
13def parse(line):
14 fields = {}
15 for part in line.split():
16 key, value = part.split("=")
17 fields[key] = value
18 return fields
11def parse(line) {
12 fields = map()
13 for part in line.split() {
14 key, value = part.split("=")
15 fields[key] = value
16 }
17 return fields
18}
(refused)
3 convert the numbers
21names = []
22temps = []
23total_rain = 0
24for line in LOG:
25 if line.startswith("#"):
26 continue
27 f = parse(line)
28 names.append(f["station"])
29 temps.append(float(f["temp"]))
30 total_rain += int(f["rain"])
21names = []
22temps = []
23total_rain = 0
24for line in LOG {
25 if line.startswith("#") {
26 continue
27 }
28 f = parse(line)
29 names = append(names, f["station"])
30 temps = append(temps, float(f["temp"]))
31 total_rain += int(f["rain"])
32}
(refused)
4 report
33for name, t in zip(names, temps):
34 print(f"{name:>6}: {t:6.2f}")
35print(f"mean temperature {sum(temps) / len(temps):.3f}")
36print(f"total rain {total_rain:d}")
37print(int("ff", 16), float(" 2.5e-3 "), float("inf"))
35for name, t in zip(names, temps) {
36 print(f"{name:>6}: {t:6.2f}")
37}
38print(f"mean temperature {sum(temps) / len(temps):.3f}")
39print(f"total rain {total_rain:d}")
40print(int("ff", 16), fmt(float(" 2.5e-3 ")), float("inf"))
(refused)
5 checks
40assert len(names) == 4
41assert temps[1] == 18.25
43test "parsed" {
44 assert_true(len(names) == 4)
45 assert_true(temps[1] == 18.25)
46}
(refused)

What they print

identical — the two programs print the same text.

Dimmed lines are left out of the comparison. Each Viv test block prints one PASS line; the Python checks the same facts with assert, which prints nothing.

$ python3 parse_numbers.py

north: 21.50
south: 18.25
east: -3.00
west: 10.00
mean temperature 11.688
total rain 23
255 0.0025 inf

$ viv run parse_numbers.viv

north: 21.50
south: 18.25
east: -3.00
west: 10.00
mean temperature 11.688
total rain 23
255 0.0025 inf
PASS parsed