Python and Viv · Lists and growable arrays
Sorting
What to notice
- Viv's
sort(a)sorts in place and gives back nothing, like Python'sa.sort(). For a sorted copy (sorted(nums)), copy first:ordered = copy(nums), thensort(ordered)on its own line. sorted(nums, reverse=true)is a sorted copy, largest first, as Python'sreverse=Truesorts: equal elements keep their order.sortedworks on a list of strings in Viv, as in Python.- Viv's keys are numbers or strings, not tuples. Sorting one list by another takes two stable sorts where Python passes
key=lambda i: (-scores[i], names[i]): first by name (argsortgives the positions), then by score; a stable sort keeps the name order among equal scores. list(a)as a copy iscopy(a). Writing into an array parameter writes into the caller's array in Viv, so the copy matters there as it does in Python.
Python sorting.py · 39 lines
Viv sorting.viv · 50 lines
py2viv refuses sorting.py
1 a sorted copy
4nums = [5.5, -1.0, 3.25, 9.0, 0.0, 3.25]
5ordered = sorted(nums)
6print(ordered)
7print(nums)
2nums = [5.5, -1.0, 3.25, 9.0, 0.0, 3.25]
3ordered = copy(nums)
4sort(ordered)
5print(fmt(ordered))
6print(fmt(nums))
py2viv refuses this program:
sorting.py:20:16: not numeric Python: range outside a for loop
order = sorted(range(len(names)), key=lambda i: (-scores[i], names[i]))
^^^^^^^^^^^^^^^^^
Use np.arange(n) for an array of indices.
sorting.py:21:10: not numeric Python: iterating over a value of unknown type
for i in order:
^^^^^
Loop over `range(len(a))` and index.
2 constructs outside the numeric subset (tools/py2viv/SUBSET.md) 2 sort in place, largest first
10nums.sort(reverse=True)
11print(nums)
9nums = sorted(nums, reverse=true)
10print(fmt(nums))
(refused)
3 sort strings
14words = ["pear", "Apple", "fig", "banana"]
15print(sorted(words))
13words = ["pear", "Apple", "fig", "banana"]
14print(sorted(words))
(refused)
4 sort one list by another
18names = ["ann", "bob", "cy", "dee"]
19scores = [72, 95, 88, 72]
20order = sorted(range(len(names)), key=lambda i: (-scores[i], names[i]))
21for i in order:
22 print(f"{names[i]:4} {scores[i]}")
17names = ["ann", "bob", "cy", "dee"]
18scores = [72, 95, 88, 72]
19order = argsort(names, key=fn(name) -> name)
20order = sorted(order, key=fn(i) -> -scores[i])
21for i in order {
22 print(f"{names[i]:4} {scores[i]:d}")
23}
(refused)
5 insertion sort by hand
25def insertion_sort(a):
26 a = list(a)
27 for i in range(1, len(a)):
28 v = a[i]
29 j = i
30 while j > 0 and a[j - 1] > v:
31 a[j] = a[j - 1]
32 j -= 1
33 a[j] = v
34 return a
35
36print(insertion_sort([3, 1, 4, 1, 5, 9, 2, 6]))
26def insertion_sort(a) {
27 a = copy(a)
28 for i from 1 to len(a) {
29 v = a[i]
30 j = i
31 while j > 0 and a[j - 1] > v {
32 a[j] = a[j - 1]
33 j -= 1
34 }
35 a[j] = v
36 }
37 return a
38}
39
40print(insertion_sort([3, 1, 4, 1, 5, 9, 2, 6]))
(refused)
6 checks
39assert insertion_sort(nums) == sorted(nums)
43test "sorting" {
44 expect = copy(nums)
45 sort(expect)
46 assert_true(all(insertion_sort(nums) == expect))
47}
(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 sorting.py
[-1.0, 0.0, 3.25, 3.25, 5.5, 9.0][5.5, -1.0, 3.25, 9.0, 0.0, 3.25][9.0, 5.5, 3.25, 3.25, 0.0, -1.0]['Apple', 'banana', 'fig', 'pear']bob 95cy 88ann 72dee 72[1, 1, 2, 3, 4, 5, 6, 9]
$ viv run sorting.viv
[-1.0, 0.0, 3.25, 3.25, 5.5, 9.0][5.5, -1.0, 3.25, 9.0, 0.0, 3.25][9.0, 5.5, 3.25, 3.25, 0.0, -1.0]['Apple', 'banana', 'fig', 'pear']bob 95cy 88ann 72dee 72[1, 1, 2, 3, 4, 5, 6, 9]PASS sorting