Skip to content

Commit f83750a

Browse files
authored
Add list-ops exercise (#387)
Finishes the abandoned pr #170
1 parent 69e96b7 commit f83750a

File tree

4 files changed

+235
-0
lines changed

4 files changed

+235
-0
lines changed

config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,12 @@
411411
"difficulty": 1,
412412
"topics": [
413413
]
414+
},
415+
{
416+
"slug": "list-ops",
417+
"difficulty": 1,
418+
"topics": [
419+
]
414420
}
415421
],
416422
"deprecated": [

exercises/list-ops/example.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
def map_clone(function, xs):
2+
return (function(elem) for elem in xs)
3+
4+
5+
def length(xs):
6+
return sum(1 for x in xs)
7+
8+
9+
def filter_clone(function, xs):
10+
return (x for x in xs if function(x))
11+
12+
13+
def reverse(xs):
14+
if not xs:
15+
return []
16+
else:
17+
return xs[::-1]
18+
19+
20+
def append(xs, y):
21+
xs[len(xs):] = [y]
22+
return xs
23+
24+
25+
def foldl(function, xs, acc):
26+
if(len(xs) == 0):
27+
return acc
28+
else:
29+
return foldl(function, xs[1:], function(acc, xs[0]))
30+
31+
32+
def foldr(function, xs, acc):
33+
if(len(xs) == 0):
34+
return acc
35+
else:
36+
return function(xs[0], foldr(function, xs[1:], acc))
37+
38+
39+
def flat(xs):
40+
out = []
41+
for item in xs:
42+
if isinstance(item, (list, tuple)):
43+
out.extend(flat(item))
44+
else:
45+
out.append(item)
46+
return out
47+
48+
49+
def concat(xs, ys):
50+
if not ys:
51+
return xs
52+
else:
53+
for item in ys:
54+
xs.append(item)
55+
return xs

exercises/list-ops/list_ops.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Please, do not use the built-in python functions like map, reduce, len, etc.
2+
# that solve the same problems and try to solve it yourself instead.
3+
4+
5+
def map_clone(function, xs):
6+
return xs
7+
8+
9+
def length(xs):
10+
return xs
11+
12+
13+
def filter_clone(function, xs):
14+
return xs
15+
16+
17+
def reverse(xs):
18+
return xs
19+
20+
21+
def append(xs, y):
22+
return xs
23+
24+
25+
def foldl(function, xs, acc):
26+
return xs
27+
28+
29+
def foldr(function, xs, acc):
30+
return xs
31+
32+
33+
def flat(xs):
34+
return xs
35+
36+
37+
def concat(xs, ys):
38+
return xs

exercises/list-ops/list_ops_test.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import unittest
2+
import operator
3+
4+
import list_ops
5+
6+
7+
class ListOpsTest(unittest.TestCase):
8+
9+
# tests for map
10+
def test_map_square(self):
11+
self.assertEqual(
12+
(1, 4, 9, 16, 25, 36, 49, 64, 81, 100),
13+
tuple(list_ops.map_clone(
14+
lambda x: x**2, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
15+
)
16+
)
17+
18+
def test_map_cube(self):
19+
self.assertEqual(
20+
(-1, 8, -27, 64, -125, 216, -343, 512, -729, 1000),
21+
tuple(list_ops.map_clone(
22+
lambda x: x**3, (-1, 2, -3, 4, -5, 6, -7, 8, -9, 10))
23+
)
24+
)
25+
26+
def test_map_absolute(self):
27+
self.assertEqual(
28+
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
29+
tuple(list_ops.map_clone(
30+
lambda x: abs(x), (-1, 2, -3, 4, -5, 6, -7, 8, -9, 10))
31+
)
32+
)
33+
34+
def test_map_empty(self):
35+
self.assertEqual([], list(list_ops.map_clone(operator.index, [])))
36+
37+
# tests for length
38+
def test_pos_leng(self):
39+
self.assertEqual(10, list_ops.length((-1, 2, -3, 4, -5, 6, -7, 8, -9, 10)))
40+
41+
def test_empty_len(self):
42+
self.assertEqual(0, list_ops.length([]))
43+
44+
# tests for filter
45+
def test_filter_odd(self):
46+
self.assertEqual(
47+
(1, 3, 5),
48+
tuple(list_ops.filter_clone(lambda x: x % 2 != 0, [1, 2, 3, 4, 5, 6]))
49+
)
50+
51+
def test_filter_even(self):
52+
self.assertEqual(
53+
(2, 4, 6),
54+
tuple(list_ops.filter_clone(lambda x: x % 2 == 0, [1, 2, 3, 4, 5, 6]))
55+
)
56+
57+
# tests for reverse
58+
def test_reverse_small(self):
59+
self.assertEqual([1, 2, 3], list_ops.reverse([3, 2, 1]))
60+
61+
def test_reverse_mixed_types(self):
62+
self.assertEqual(
63+
(1, "cat", 4.0, "xyz"),
64+
list_ops.reverse(("xyz", 4.0, "cat", 1))
65+
)
66+
67+
def test_reverse_empty(self):
68+
self.assertEqual([], list_ops.reverse(()))
69+
70+
# tests for append
71+
def test_append_tuple(self):
72+
self.assertEqual(
73+
["10", "python", "hello"],
74+
list_ops.append(["10", "python"], "hello")
75+
)
76+
77+
def test_append_range(self):
78+
self.assertEqual([100, range(1000)], list_ops.append([100], range(1000)))
79+
80+
def test_append_to_empty(self):
81+
self.assertEqual([42], list_ops.append([], 42))
82+
83+
# tests for foldl
84+
def test_foldl_sum(self):
85+
self.assertEqual(21, list_ops.foldl(operator.add, [1, 2, 3, 4, 5, 6], 0))
86+
87+
def test_foldl_product(self):
88+
self.assertEqual(720, list_ops.foldl(operator.mul, [1, 2, 3, 4, 5, 6], 1))
89+
90+
def test_foldl_div(self):
91+
self.assertEqual(0, list_ops.foldl(operator.floordiv, [1, 2, 3, 4, 5, 6], 1))
92+
93+
def test_foldl_sub(self):
94+
self.assertEqual(-15, list_ops.foldl(operator.sub, [1, 2, 3, 4, 5], 0))
95+
96+
# tests for foldr
97+
def test_foldr_sub(self):
98+
self.assertEqual(3, list_ops.foldr(operator.sub, [1, 2, 3, 4, 5], 0))
99+
100+
def test_foldr_add_str(self):
101+
self.assertEqual(
102+
"exercism!",
103+
list_ops.foldr(operator.add, ["e", "x", "e", "r", "c", "i", "s", "m"], "!"))
104+
105+
# tests for flatten
106+
def test_flatten_nested(self):
107+
self.assertEqual([1, 2, 3, 4], list_ops.flat([[[1, 2], [3]], [[4]]]))
108+
109+
def test_flatten_once(self):
110+
self.assertEqual(["x", "y", "z"], list_ops.flat([["x", "y", "z"]]))
111+
112+
def test_flatten_empty(self):
113+
self.assertEqual([], list_ops.flat([]))
114+
115+
# tests for concat
116+
def test_concat_two(self):
117+
self.assertEqual(
118+
[1, 3, 5, 8, 9, 4, 5, 6],
119+
list_ops.concat([1, 3, 5, 8], [9, 4, 5, 6])
120+
)
121+
122+
def test_concat_nothing(self):
123+
self.assertEqual(
124+
["orange", "apple", "banana"],
125+
list_ops.concat(['orange', 'apple', 'banana'], None)
126+
)
127+
128+
def test_concat_empty(self):
129+
self.assertEqual(
130+
[],
131+
list_ops.concat([], [])
132+
)
133+
134+
135+
if __name__ == '__main__':
136+
unittest.main()

0 commit comments

Comments
 (0)