summaryrefslogtreecommitdiff
path: root/python/problems/lists_and_for
diff options
context:
space:
mode:
authorJure Žabkar <jure.zabkar@fri.uni-lj.si>2015-10-12 14:19:07 +0200
committerJure Žabkar <jure.zabkar@fri.uni-lj.si>2015-10-12 14:19:07 +0200
commit0a88716110994f789f764704a96791fdfb5fa288 (patch)
tree788c16ab578cf76eda358abc1d0587503d413a87 /python/problems/lists_and_for
parent1a7678b37a25a76aeaef7ebb225f85406b19f928 (diff)
parent5a01c2bb184152c6ccc3c536e9b857d247bc55ad (diff)
Merge branch 'master' of ssh://212.235.189.51:22122/codeq-problems
Conflicts: robot/problems/introduction/forward/en.py robot/problems/introduction/forward/sl.py
Diffstat (limited to 'python/problems/lists_and_for')
-rw-r--r--python/problems/lists_and_for/calculator_polish/common.py96
-rw-r--r--python/problems/lists_and_for/calculator_polish/en.py16
-rw-r--r--python/problems/lists_and_for/calculator_polish/sl.py61
-rw-r--r--python/problems/lists_and_for/common.py2
-rw-r--r--python/problems/lists_and_for/contains_42/common.py15
-rw-r--r--python/problems/lists_and_for/contains_42/en.py1
-rw-r--r--python/problems/lists_and_for/contains_42/sl.py28
-rw-r--r--python/problems/lists_and_for/contains_multiples/common.py82
-rw-r--r--python/problems/lists_and_for/contains_multiples/en.py16
-rw-r--r--python/problems/lists_and_for/contains_multiples/sl.py30
-rw-r--r--python/problems/lists_and_for/contains_string/common.py11
-rw-r--r--python/problems/lists_and_for/contains_string/en.py1
-rw-r--r--python/problems/lists_and_for/contains_string/sl.py21
-rw-r--r--python/problems/lists_and_for/counting/common.py1
-rw-r--r--python/problems/lists_and_for/counting/en.py1
-rw-r--r--python/problems/lists_and_for/counting/sl.py18
-rw-r--r--python/problems/lists_and_for/divisors/common.py3
-rw-r--r--python/problems/lists_and_for/divisors/en.py1
-rw-r--r--python/problems/lists_and_for/divisors/sl.py12
-rw-r--r--python/problems/lists_and_for/divisors_sum/common.py110
-rw-r--r--python/problems/lists_and_for/divisors_sum/en.py16
-rw-r--r--python/problems/lists_and_for/divisors_sum/sl.py101
-rw-r--r--python/problems/lists_and_for/every_third/common.py77
-rw-r--r--python/problems/lists_and_for/every_third/en.py16
-rw-r--r--python/problems/lists_and_for/every_third/sl.py80
-rw-r--r--python/problems/lists_and_for/perfect_numbers/common.py113
-rw-r--r--python/problems/lists_and_for/perfect_numbers/en.py16
-rw-r--r--python/problems/lists_and_for/perfect_numbers/sl.py96
-rw-r--r--python/problems/lists_and_for/places/common.py80
-rw-r--r--python/problems/lists_and_for/places/en.py16
-rw-r--r--python/problems/lists_and_for/places/sl.py77
-rw-r--r--python/problems/lists_and_for/prefix/common.py66
-rw-r--r--python/problems/lists_and_for/prefix/en.py16
-rw-r--r--python/problems/lists_and_for/prefix/sl.py31
-rw-r--r--python/problems/lists_and_for/split_word/common.py65
-rw-r--r--python/problems/lists_and_for/split_word/en.py16
-rw-r--r--python/problems/lists_and_for/split_word/sl.py31
-rw-r--r--python/problems/lists_and_for/substrings/common.py68
-rw-r--r--python/problems/lists_and_for/substrings/en.py16
-rw-r--r--python/problems/lists_and_for/substrings/sl.py33
40 files changed, 1520 insertions, 36 deletions
diff --git a/python/problems/lists_and_for/calculator_polish/common.py b/python/problems/lists_and_for/calculator_polish/common.py
new file mode 100644
index 0000000..cb89a50
--- /dev/null
+++ b/python/problems/lists_and_for/calculator_polish/common.py
@@ -0,0 +1,96 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 224
+number = 10
+visible = True
+
+solution = '''\
+operacije = ["*", "+", "-", "/", "%"]
+
+while True:
+ izraz = input("Izraz: ").split()
+ if not izraz:
+ break
+
+ sklad = []
+ for e in izraz:
+ sklad.append(e)
+ if sklad[-1] in operacije:
+ operacija = sklad.pop()
+ o2 = int(sklad.pop())
+ o1 = int(sklad.pop())
+ if operacija == "+":
+ rezultat = o1 + o2
+ elif operacija == "-":
+ rezultat = o1 - o2
+ elif operacija == "*":
+ rezultat = o1 * o2
+ elif operacija == "/":
+ rezultat = o1 // o2
+ elif operacija == "%":
+ rezultat = o1 % o2
+ sklad.append(rezultat)
+
+ print("Rezultat:", sklad[0])
+ print()
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ (['6 3 +'], [9]),
+ (['6 3 -'], [3]),
+ (['6 3 /'], [2]),
+ (['7 3 /'], [2]),
+ (['6 3 *'], [18]),
+ (['6 3 %'], [0]),
+ (['1 2 +', '2 3 +', '1 2 3 4 5 * * * *'], [3, 5, 120]),
+ (['1 2 + 3 +'], [6]),
+ (['1 2 3 + +'], [6]),
+ (['1 2 + 3 4 + *'], [21]),
+ (['1 2 3 * 4 + +'], [11]),
+ (['3 5 + 2 * 10 2 1 - * -'], [6]),
+ (['11 22 33 * * 7 + 2 / 100 % 1 2 - -'], [97]),
+ ]
+
+ test_in = [(None, '\n'.join(s[0])+'\n') for s in in_out]
+ test_out = [s[1] for s in in_out]
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct = 0
+ tin = None
+ for i, (output, correct) in enumerate(zip(outputs, test_out)):
+ if all(string_almost_equal(output, c, prec=2) for c in correct):
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = correct
+
+ passed = n_correct == len(test_in)
+
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/calculator_polish/en.py b/python/problems/lists_and_for/calculator_polish/en.py
new file mode 100644
index 0000000..f0618e8
--- /dev/null
+++ b/python/problems/lists_and_for/calculator_polish/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 224
+name = 'Reverse polish potation calculator'
+slug = 'Reverse polish potation calculator'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/calculator_polish/sl.py b/python/problems/lists_and_for/calculator_polish/sl.py
new file mode 100644
index 0000000..b7ff8a1
--- /dev/null
+++ b/python/problems/lists_and_for/calculator_polish/sl.py
@@ -0,0 +1,61 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 224
+name = 'Kalkulator v inverzni poljski notaciji'
+slug = 'Kalkulator v inverzni poljski notaciji'
+
+
+description = '''\
+<p>
+V <a href="http://en.wikipedia.org/wiki/Reverse_Polish_notation">inverzni poljski ali postfiksni notaciji</a> ne potrebujemo oklepajev:
+računska operacija sledi številoma in se vedno izvede takoj ter zamenja predhodni števili in operacijo z rezultatom operacije.
+
+Poglejmo si računanje <code>(3 + 5) * 2 - 10 * (2 - 1)</code> ali postfiksno <code>3 5 + 2 * 10 2 1 - * -</code>:
+
+<ul>
+<li> Beremo vhod do prve operacije. </li>
+<li> <code>3 5 + </code>; izvede se seštevanje, tri elemente zamenja rezultat 8, beremo dalje. </li>
+<li> <code>8 2 * </code>; rezultat je 16, beremo dalje.</li>
+<li> <code>16 10 2 1 -</code>; rezultat 1, beremo dalje.</li>
+<li> <code>16 10 1 *</code>; rezultat 10, beremo dalje.</li>
+<li> <code>16 10 -</code>; rezultat 6, beremo dalje.</li>
+<li> <code>6</code>; vhoda je konec zato se se računanje ustavi.</li>
+</ul>
+Napišite kalkulator s celoštevilskimi operacijami seštevanja, odštevanja, množenja, deljenja in izračunom ostanka,
+ki prejme vhod v inverzni poljski notaciji. Ko uporabnik ne poda ničesar (pritisne le enter), naj se program zaključi.
+Števila ter operande ločujte s presledkom.
+<pre>
+Izraz: 3 5 +
+Rezultat: 8
+
+Izraz: 16 5 %
+Rezultat: 1
+
+Izraz: 16 5 /
+Rezultat: 3
+
+Izraz: 3 3 3 + +
+Rezultat: 9
+
+Izraz: 3 5 + 2 * 10 2 1 - * -
+Rezultat: 6
+
+Izraz:
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/common.py b/python/problems/lists_and_for/common.py
new file mode 100644
index 0000000..fe6aa94
--- /dev/null
+++ b/python/problems/lists_and_for/common.py
@@ -0,0 +1,2 @@
+id = 16
+number = 3 \ No newline at end of file
diff --git a/python/problems/lists_and_for/contains_42/common.py b/python/problems/lists_and_for/contains_42/common.py
index f91465f..fb2089e 100644
--- a/python/problems/lists_and_for/contains_42/common.py
+++ b/python/problems/lists_and_for/contains_42/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 193
-group = 'lists_and_for'
number = 1
visible = True
@@ -25,10 +24,15 @@ hint_type = {
'for_loop': Hint('for_loop'),
'if_clause': Hint('if_clause'),
'printing': Hint('printing'),
- 'print_out_for': Hint('print_out_for')
+ 'print_out_for': Hint('print_out_for'),
+ 'seen_42': Hint('seen_42'),
+ 'final_hint': Hint('final_hint'),
+ 'final_hint_nobreak': Hint('final_hint_nobreak')
}
def test(python, code):
+ tokens = get_tokens(code)
+
test_xs = [[42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2],
[42, 5, 4, -7, 2, 12, -3, -4, 11, 2],
[5, 4, -7, 2, 12, -3, -4, 11, 2],
@@ -71,6 +75,11 @@ def test(python, code):
hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_xs)}}]
if tin:
hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ else:
+ if has_token_sequence(tokens, ['break']):
+ hints.append({'id' : 'final_hint'})
+ else:
+ hints.append({'id' : 'final_hint_nobreak'})
return passed, hints
def hint(python, code):
@@ -101,5 +110,7 @@ def hint(python, code):
if not has_token_sequence(tokens, ['\n', 'print']):
return [{'id' : 'print_out_for'}]
+ if not has_token_sequence(tokens, ['=', 'True']):
+ return [{'id' : 'seen_42'}]
return None
diff --git a/python/problems/lists_and_for/contains_42/en.py b/python/problems/lists_and_for/contains_42/en.py
index 805b37c..7794063 100644
--- a/python/problems/lists_and_for/contains_42/en.py
+++ b/python/problems/lists_and_for/contains_42/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 193
name = 'Contains 42'
slug = 'Contains 42'
diff --git a/python/problems/lists_and_for/contains_42/sl.py b/python/problems/lists_and_for/contains_42/sl.py
index fe6b57e..65353a7 100644
--- a/python/problems/lists_and_for/contains_42/sl.py
+++ b/python/problems/lists_and_for/contains_42/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 193
name = 'Vsebuje'
slug = 'Vsebuje'
@@ -21,10 +20,10 @@ Seveda mora program delati za poljubne sezname in ne samo za seznam iz primera.<
for_loop = ['''\
<p>Pregledati bo treba vse elemente v seznamu <code>xs</code>''',
'''\
-<p>Najlažje bo s <b>for</b> zanko.
+<p>Najlažje bo s <code>for</code> zanko.
''',
'''\
-<p>Poskusii naslednji dve vrstici:</p>
+<p>Poskusi naslednji dve vrstici:</p>
<pre>
for x in xs:
print (x)
@@ -36,9 +35,9 @@ Kaj naj Python naredi s to spremenljivko, je zapisano v zamaknjenih vrsticah.
Tokrat vrednost le izpišemo.</p>''']
if_clause = ['''\
-<p><code>Preveri, ali imamo število 42?</code></p>''',
+<p>Preveri, ali imamo število 42?</p>''',
'''\
-<p>Uporabi pogojni stavek <b>if</b>!</p>''',
+<p>Uporabi pogojni stavek <code>if</code>!</p>''',
'''\
<pre>
if x == 42:
@@ -57,7 +56,7 @@ videl42 = False
<p>in jo tekom zanke ustrezno spremenimo.''']
plan = ['''\
-<p><b>Plan.</b> Kako bi se tega lotil ročno? Nekako takole: </p>
+<p>Kako bi se tega lotil ročno? Nekako takole: </p>
<pre>
Za vsak element v seznamu
Poglej, ali je 42?
@@ -82,6 +81,21 @@ hint = {
<p>Izpiši rezultat.</p>'''],
'print_out_for': ['''\
-<p>Pazi, da izpišeš rezultat izven zanke!</p>''']
+<p>Pazi, da izpišeš rezultat izven zanke!</p>'''],
+ 'seen_42': seen_42,
+
+ 'final_hint': ['''\
+<p>Program deluje pravilno!</p>'''],
+
+ 'final_hint_nobreak': ['''\
+<p>Program deluje pravilno! <br>
+Namig za bolj učinkovit program: ni vedno potrebno, da se program pregleda vse elemente. Če najdemo vrednost 42, nam ni
+potrebno več naprej iskati - zanko lahko prekinemo z ukazom <code>break</code> </p>'''],
+
+ 'problematic_test_case': ['''\
+<p>Program ne dela pravilno!<br>
+Poskusi xs = [%=testin%] <br>
+pravilen rezultat: [%=testout%]</p>
+'''],
}
diff --git a/python/problems/lists_and_for/contains_multiples/common.py b/python/problems/lists_and_for/contains_multiples/common.py
new file mode 100644
index 0000000..59a5743
--- /dev/null
+++ b/python/problems/lists_and_for/contains_multiples/common.py
@@ -0,0 +1,82 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 219
+number = 5
+visible = True
+
+solution = '''\
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+
+vsebuje = False
+for x in xs:
+ if x % 42 == 0:
+ vsebuje = True
+print(vsebuje)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ([], False),
+ ([0], True),
+ ([42], True),
+ ([42 * 43], True),
+ ([4, 2], False),
+ ([42, 42], True),
+ ([1, 2, 3, 4, 5, 5, 4, 3, 2, 1], False),
+ ([1, 2, 3, 4, 5, 5, 4, 3, 2, 1, -42], True),
+ ([1, 2, 3, 4, 5, 42 * 3, 5, 4, 3, 2, 1], True),
+ ([1, 2, 42, 4, 5, 42 * 5, 5, 4, 42 * 3, 2, 1], True),
+ ([42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2], True)
+ ]
+
+
+ test_in = [t[0] for t in in_out]
+ test_out = [t[1] for t in in_out]
+
+ n_correct = 0
+ tin = None
+ for xs_i, xs in enumerate(test_in):
+ # change code to contain new xs instead of the one
+ # given by user
+ tcode = re.sub(r'^xs\s*=\s*\[.*?\]',
+ 'xs = ' + str(xs),
+ code,
+ flags = re.DOTALL | re.MULTILINE)
+
+ # use python session to call tcode
+ answers = python(code=tcode, inputs=[(None, None)], timeout=1.0)
+ output = answers[0][1]
+
+ if str(test_out[xs_i]) in output and \
+ str((not test_out[xs_i])) not in output:
+ n_correct += 1
+ else:
+ tin = test_in[xs_i]
+ tout = test_out[xs_i]
+ passed = n_correct == len(test_in)
+
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/contains_multiples/en.py b/python/problems/lists_and_for/contains_multiples/en.py
new file mode 100644
index 0000000..47bf004
--- /dev/null
+++ b/python/problems/lists_and_for/contains_multiples/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 219
+name = 'Contains multiples'
+slug = 'Contains multiples'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/contains_multiples/sl.py b/python/problems/lists_and_for/contains_multiples/sl.py
new file mode 100644
index 0000000..7345370
--- /dev/null
+++ b/python/problems/lists_and_for/contains_multiples/sl.py
@@ -0,0 +1,30 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 219
+name = 'Vsebuje večkratnik'
+slug = 'Vsebuje večkratnik'
+
+
+description = '''\
+<p>
+Napiši program, ki izpiše <code>True</code>, če se v seznamu števil pojavi večkratnik števila
+<code>42</code>, sicer izpiše <code>False</code>.
+Seznam <code>xs</code> definiraj na vrhu programa.
+</p>'''
+
+
+
+plan = ['''\
+<p>Popolnoma enaka naloga kot naloga "Vsebuje", le pri pogoju poglej, ali je število deljivo z 42.</p>
+''',
+ mod.general_msg["modulo"]]
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/contains_string/common.py b/python/problems/lists_and_for/contains_string/common.py
index 29bc9f2..62fef4e 100644
--- a/python/problems/lists_and_for/contains_string/common.py
+++ b/python/problems/lists_and_for/contains_string/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 194
-group = 'lists_and_for'
number = 2
visible = True
@@ -25,7 +24,8 @@ hint_type = {
'for_loop': Hint('for_loop'),
'if_clause': Hint('if_clause'),
'printing': Hint('printing'),
- 'print_out_for': Hint('print_out_for')
+ 'print_out_for': Hint('print_out_for'),
+ 'final_hint': Hint('final_hint')
}
def test(python, code):
@@ -36,12 +36,12 @@ def test(python, code):
[],
['Waldo']]
test_out = [
+ False,
True,
True,
True,
False,
- True,
- False
+ True
]
n_correct = 0
@@ -69,6 +69,9 @@ def test(python, code):
hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_xs)}}]
if tin:
hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+
return passed, hints
def hint(python, code):
diff --git a/python/problems/lists_and_for/contains_string/en.py b/python/problems/lists_and_for/contains_string/en.py
index fa17867..b57be95 100644
--- a/python/problems/lists_and_for/contains_string/en.py
+++ b/python/problems/lists_and_for/contains_string/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 194
name = 'Contains string'
slug = 'Contains string'
diff --git a/python/problems/lists_and_for/contains_string/sl.py b/python/problems/lists_and_for/contains_string/sl.py
index d177463..7061c59 100644
--- a/python/problems/lists_and_for/contains_string/sl.py
+++ b/python/problems/lists_and_for/contains_string/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 194
name = 'Vsebuje niz'
slug = 'Vsebuje niz'
@@ -20,7 +19,7 @@ xs = ['foo', 'bar', 'baz', 'Waldo', 'foobar']
for_loop = ['''\
<p>Pregledati bo treba vse elemente v seznamu <code>xs</code>''',
'''\
-<p>Najlažje bo s <b>for</b> zanko.
+<p>Najlažje bo s <code>for</code> zanko.
''',
'''\
<p>Poskusii naslednji dve vrstici:</p>
@@ -43,7 +42,7 @@ if x == 'Waldo':
plan = ['''\
-<p><b>Plan</b> je enak kot pri prvi nalogi:
+<p>Plan je enak kot pri prvi nalogi:
<pre>
Za vsak element v seznamu
Poglej, ali je element enak 'Waldo'?
@@ -66,6 +65,20 @@ hint = {
<p>Izpiši rezultat!</p>'''],
'print_out_for': ['''\
-<p>Pazi, da izpišeš rezultat izven zanke!</p>''']
+<p>Pazi, da izpišeš rezultat izven zanke!</p>'''],
+
+ 'problematic_test_case': ['''\
+<p>Program ne dela pravilno!<br>
+Poskusi xs = [%=testin%] <br>
+pravilen rezultat: [%=testout%]</p>
+'''],
+
+ 'final_hint': ['''\
+<p>Program deluje pravilno! <br>
+Nalogo lahko rešiš hitreje z operatorjem <code>in</code></p>
+<pre>
+xs = ['foo', 'bar', 'baz', 'Waldo', 'foobar']
+print('Waldo' in xs)
+</pre>'''],
}
diff --git a/python/problems/lists_and_for/counting/common.py b/python/problems/lists_and_for/counting/common.py
index 2d59182..73d0071 100644
--- a/python/problems/lists_and_for/counting/common.py
+++ b/python/problems/lists_and_for/counting/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 203
-group = 'lists_and_for'
number = 3
visible = True
diff --git a/python/problems/lists_and_for/counting/en.py b/python/problems/lists_and_for/counting/en.py
index 19568e3..223a611 100644
--- a/python/problems/lists_and_for/counting/en.py
+++ b/python/problems/lists_and_for/counting/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 203
name = 'Counting'
slug = 'Counting'
diff --git a/python/problems/lists_and_for/counting/sl.py b/python/problems/lists_and_for/counting/sl.py
index 67dc323..926d2c6 100644
--- a/python/problems/lists_and_for/counting/sl.py
+++ b/python/problems/lists_and_for/counting/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 203
name = 'Štej'
slug = 'Štej'
@@ -80,11 +79,18 @@ hint = {
'print_out_for': ['''\
<p>Pazi, da izpišeš rezultat izven zanke!</p>'''],
- 'final_hint:': ['''\
- <p>Nalogo lahko rešiš bistveno hitreje, če poznaš metodo <code>count</code></p>
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+Nalogo lahko rešiš hitreje, če poznaš metodo <code>count</code></p>
<pre>
- xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
- print('Število 42 se v seznamu pojavi', xs.count(42), 'krat.')
-</pre>''']
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+print('Število 42 se v seznamu pojavi', xs.count(42), 'krat.')
+</pre>'''],
+
+ 'problematic_test_case': ['''\
+<p>Program ne dela pravilno!<br>
+Poskusi xs = [%=testin%] <br>
+pravilen rezultat: [%=testout%]</p>
+'''],
}
diff --git a/python/problems/lists_and_for/divisors/common.py b/python/problems/lists_and_for/divisors/common.py
index 4f440e4..a99246b 100644
--- a/python/problems/lists_and_for/divisors/common.py
+++ b/python/problems/lists_and_for/divisors/common.py
@@ -6,8 +6,7 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 204
-group = 'lists_and_for'
-number = 4
+number = 20
visible = True
solution = '''\
diff --git a/python/problems/lists_and_for/divisors/en.py b/python/problems/lists_and_for/divisors/en.py
index e98e9a7..8f4dbeb 100644
--- a/python/problems/lists_and_for/divisors/en.py
+++ b/python/problems/lists_and_for/divisors/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 204
name = 'Divisors'
slug = 'Divisors'
diff --git a/python/problems/lists_and_for/divisors/sl.py b/python/problems/lists_and_for/divisors/sl.py
index 5ba36e1..f79875a 100644
--- a/python/problems/lists_and_for/divisors/sl.py
+++ b/python/problems/lists_and_for/divisors/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 204
name = 'Delitelji'
slug = 'Delitelji'
@@ -74,15 +73,16 @@ hint = {
'last_number': ['''\
<p>Število deli samega sebe!</p>'''],
- 'final_hint:': ['''\
+ 'final_hint': ['''\
<p>Naloga rešena!</p>
- <p>Dejansko ne potrebujemo pregledati vseh števil med <code>1</code> in </code>n-1</code>,
- dovolj bo če gremo do kvadratnega korena od števila <code>n</code>:</p>
+ <p>Dejansko ne potrebujemo pregledati vseh števil med <code>1</code> in <code>n-1</code>,
+ dovolj bo če gremo do kvadratnega korena števila <code>n</code>:</p>
<pre>
-from math import sqrt
+from math import *
+
n = int(input('Vnesi število: '))
-for i in range(1, sqrt(n)+1):
+for i in range(1, int(sqrt(n)+1)):
if n % i == 0:
print(i, n/i)
</pre>'''],
diff --git a/python/problems/lists_and_for/divisors_sum/common.py b/python/problems/lists_and_for/divisors_sum/common.py
new file mode 100644
index 0000000..1d11410
--- /dev/null
+++ b/python/problems/lists_and_for/divisors_sum/common.py
@@ -0,0 +1,110 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 216
+number = 21
+visible = True
+
+solution = '''\
+n = int(input('Vnesi število: '))
+vsota = 0
+for i in range(1, n):
+ if n % i == 0:
+ vsota += i
+print(vsota)
+'''
+
+hint_type = {
+ 'input_clause': Hint('input_clause'),
+ 'range_function': Hint('range_function'),
+ 'printing': Hint('printing'),
+ 'divisor': Hint('divisor'),
+ 'final_hint': Hint('final_hint'),
+ 'zero_division': Hint('zero_division'),
+ 'last_number': Hint('last_number'),
+ 'summing': Hint('summing'),
+}
+
+def test(python, code):
+ test_in = [
+ (None, '8\n'),
+ (None, '6\n'),
+ (None, '5\n'),
+ (None, '2\n'),
+ (None, '15\n'),
+ (None, '20\n'),
+ ]
+ test_out = [
+ 7,
+ 6,
+ 1,
+ 1,
+ 9,
+ 22]
+
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct, tin = 0, None
+ for i, (output, result) in enumerate(zip(outputs, test_out)):
+ if result in get_numbers(output):
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = result
+
+ passed = n_correct == len(test_in)
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, '8\n')], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc:
+ if 'ZeroDivisionError' in answer[0][3]:
+ return [{'id' : 'zero_division', 'args': {'message': answer[0][3]}}]
+ else:
+ return exc
+
+ # if has no input, tell him how to ask questions
+ if not has_token_sequence(tokens, ['input']):
+ return [{'id' : 'input_clause'}]
+
+ # if it has no range, explain how we can create a list (generator) from a number
+ if not has_token_sequence(tokens, ['range']):
+ return [{'id' : 'range_function'}]
+
+ # if it has no print function, tell him to use print
+ if not has_token_sequence(tokens, ['print']):
+ return [{'id' : 'printing'}]
+
+ # if it has no divisoin-by-modulo operator, explain that operator
+ if not has_token_sequence(tokens, ['%']):
+ return [{'id' : 'divisor'}]
+
+ # if the program prints 15 instead of 7,
+ # it means that is adds also itself
+ nums = get_numbers(answer[0][1])
+ if 15 in nums and 7 not in nums:
+ return [{'id' : 'last_number'}]
+
+ # if program prints only the last number or
+ # only the first number, explain how to sum
+ # elements in iterations
+ if 7 not in nums and \
+ (1 in nums or 4 in nums or 8 in nums):
+ return [{'id' : 'summing'}]
+
+
+ return None
diff --git a/python/problems/lists_and_for/divisors_sum/en.py b/python/problems/lists_and_for/divisors_sum/en.py
new file mode 100644
index 0000000..4ca12b9
--- /dev/null
+++ b/python/problems/lists_and_for/divisors_sum/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 216
+name = 'Divisors sum'
+slug = 'Divisors sum'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/divisors_sum/sl.py b/python/problems/lists_and_for/divisors_sum/sl.py
new file mode 100644
index 0000000..4f5c10a
--- /dev/null
+++ b/python/problems/lists_and_for/divisors_sum/sl.py
@@ -0,0 +1,101 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 216
+name = 'Vsota deliteljev'
+slug = 'Vsota deliteljev'
+
+
+description = '''\
+<p> Napiši program, ki izpiše vsoto vseh deliteljev števila, ki ga vnese uporabnik.
+Med delitelji izpustite vnešeno število. Primer: </p>
+<pre>
+>>> Vpiši število: 6
+Vsota deliteljev: 6
+</pre>'''
+
+input_clause = ['''\
+Uporabi funkcijo <code>input</code>.
+''']
+
+range_function = ['''\
+Uporabi funkcijo <code>range(a,b)</code>
+''',
+ '''\
+<p>Funkcija <code>range(a, b)</code> pripravi seznam števil od a do števila b-1. Poskusi!</p>''',
+ '''\
+<p>Z zanko <code>for</code> se sprehodi čez elemente seznama oz. v našem primeru
+čez vsa števila od <code>a</code> do <code>b-1</code>.</p>
+''']
+
+divisor = ['''\
+<p>Operator % vrne ostanek pri deljenju.</p>''',
+ '''\
+<pre>
+>>> 5%3
+2
+>>> 17%8
+1
+</pre>''',
+ '''\
+<p>Če je ostanek pri deljenju števila <code>a</code> s številom <code>b</code> enak 0, potem <code>b</code>
+deli število <code>a</code>. </p>''',
+ '''\
+<pre>
+if a%b == 0:
+ # b je delitelj števila a
+</pre>
+''']
+
+summing = ['''\
+<p>Če hočemo delitelje prišteti vsoti, moramo imeti vsoto nekje shranjeno.
+Torej potrebujemo spremenljivko.</p>''',
+ '''\
+<p>Nekako tako: </p>
+<pre>
+vsota = 0
+for ....
+ if ...
+ vsota += d # d deli izbrano število
+</pre>''']
+
+plan = ['''\
+<p>Plan bo podoben kot v prejšnji naloge, kjer smo delitelje izpisali.
+Tokrat delitelja ne izpišemo, ampak ga prištejemo vsoti. </p>
+''',
+ summing]
+
+
+hint = {
+ 'input_clause': input_clause,
+
+ 'range_function': range_function,
+
+ 'printing': ['''\
+<p>Izpiši rezultat.</p>'''],
+
+ 'divisor': divisor,
+
+ 'last_number': ['''\
+<p>Tokrat med delitelji ne upoštevamo vnešenega števila!</p>'''],
+
+ 'final_hint': ['''\
+<p>Naloga rešena! <br>
+Nakoč bomo znali to napisati krajše: </p>
+<pre>
+n = int(input("Vpiši število: "))
+print(sum(i for i in range(1, n) if n % i == 0))
+</pre>'''],
+
+ 'summing': summing,
+
+ 'zero_division': [mod.general_msg['error_head'],
+ mod.general_msg['general_exception'],
+ '''\
+<p>Deljenje z nič ni dovoljeno!</p>''',
+ '''\
+<p>Računanje ostanka z operatorjem % je tudi deljenje.''']
+
+}
diff --git a/python/problems/lists_and_for/every_third/common.py b/python/problems/lists_and_for/every_third/common.py
new file mode 100644
index 0000000..2d5b907
--- /dev/null
+++ b/python/problems/lists_and_for/every_third/common.py
@@ -0,0 +1,77 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 220
+number = 6
+visible = True
+
+solution = '''\
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+
+ys = []
+i = 2
+while i < len(xs):
+ ys.append(xs[i])
+ i += 3
+print(ys)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ([], []),
+ ([0], []),
+ ([0, 1], []),
+ ([0, 1, 2], [2]),
+ ([1, 2, 3, 4, 5, 5, 4, 3, 2, 1], [3, 5, 2]),
+ ([42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2], [4, 12, 11]),
+ (list(range(15)), [2, 5, 8, 11, 14])
+ ]
+
+ test_in = [t[0] for t in in_out]
+ test_out = [t[1] for t in in_out]
+
+ n_correct = 0
+ tin = None
+ for xs_i, xs in enumerate(test_in):
+ # change code to contain new xs instead of the one
+ # given by user
+ tcode = re.sub(r'^xs\s*=\s*\[.*?\]',
+ 'xs = ' + str(xs),
+ code,
+ flags = re.DOTALL | re.MULTILINE)
+
+ # use python session to call tcode
+ answers = python(code=tcode, inputs=[(None, None)], timeout=1.0)
+ output = answers[0][1]
+
+ if str(test_out[xs_i]) in output:
+ n_correct += 1
+ else:
+ tin = test_in[xs_i]
+ tout = test_out[xs_i]
+ passed = n_correct == len(test_in)
+
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/every_third/en.py b/python/problems/lists_and_for/every_third/en.py
new file mode 100644
index 0000000..e7c843e
--- /dev/null
+++ b/python/problems/lists_and_for/every_third/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 220
+name = 'Every third'
+slug = 'Every third'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/every_third/sl.py b/python/problems/lists_and_for/every_third/sl.py
new file mode 100644
index 0000000..50b4520
--- /dev/null
+++ b/python/problems/lists_and_for/every_third/sl.py
@@ -0,0 +1,80 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 220
+name = 'Vsak tretji'
+slug = 'Vsak tretji'
+
+
+description = '''\
+<p>
+Napiši program, ki iz podanega seznama sestavi nov seznam, ki vsebuje le vsak tretji element podanega seznama.
+Kot dosedaj, naj se program začne z
+<pre>
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+</pre>
+in (v tem primeru) izpiše
+<pre>
+[4, 12, 11]
+</pre>
+</p>'''
+
+empty_list = ['''\
+<p>Nov, prazen seznam ustvarimo s stavkom: </p>
+<pre>
+s = []
+</pre>
+''']
+
+enumerate_function = ['''\
+<p> Uporabi funkcijo <code>enumerate</code>.
+</p>
+''',
+ '''\
+<pre>
+for index, val in enumerate(xs):
+ print index, v
+</pre>''',
+ '''\
+<p>V zgornji <code>for</code>zanki se v spremenljivko <code>val</code> zapiše
+trenutni element v seznamu <code>xs</code>, v spremenljivki <code>indeks</code>
+pa je zapisano mesto oz. indeks trenutnega elementa. </p>''']
+
+append_method = [
+ '''\
+<p>V seznam dodamo nov element z metodo <code>append</code>.</p>''',
+ '''\
+<p>Poskusi: </p>
+<pre>
+s = []
+s.append(3)
+s.append(5)
+print (s)
+</pre>''']
+
+plan = ['''\
+<p>S <code>for</code> zanko pojdi čez seznam. V novi seznam dodaj vsak tretji element. </p>
+''',
+ '''\
+<p>
+<pre>
+Ustvari prazen seznam mest
+Za vsak element v seznamu
+ Ali je (mesto elementa + 1) deljivo s 3?
+ Če je, dodaj trenutno mesto v seznam mest
+Izpiši seznam mest
+</pre>
+</p>''',
+ empty_list,
+ enumerate_function,
+ mod.general_msg["modulo"],
+ append_method]
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/perfect_numbers/common.py b/python/problems/lists_and_for/perfect_numbers/common.py
new file mode 100644
index 0000000..9a48967
--- /dev/null
+++ b/python/problems/lists_and_for/perfect_numbers/common.py
@@ -0,0 +1,113 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 217
+number = 22
+visible = True
+
+solution = '''\
+n = int(input('Vnesi število: '))
+vsota = 0
+for i in range(1, n):
+ if n % i == 0:
+ vsota += i
+if vsota == n:
+ print('Je popolno')
+else:
+ print('Ni popolno')
+'''
+
+hint_type = {
+ 'input_clause': Hint('input_clause'),
+ 'range_function': Hint('range_function'),
+ 'printing': Hint('printing'),
+ 'divisor': Hint('divisor'),
+ 'final_hint': Hint('final_hint'),
+ 'zero_division': Hint('zero_division'),
+ 'last_number': Hint('last_number'),
+ 'summing': Hint('summing'),
+}
+
+def test(python, code):
+ test_in = [
+ (None, '8\n'),
+ (None, '6\n'),
+ (None, '5\n'),
+ (None, '2\n'),
+ (None, '15\n'),
+ (None, '20\n'),
+ ]
+ test_out = [
+ 7,
+ 6,
+ 1,
+ 1,
+ 9,
+ 22]
+
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct, tin = 0, None
+ for i, (output, result) in enumerate(zip(outputs, test_out)):
+ if result in get_numbers(output):
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = result
+
+ passed = n_correct == len(test_in)
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, '8\n')], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc:
+ if 'ZeroDivisionError' in answer[0][3]:
+ return [{'id' : 'zero_division', 'args': {'message': answer[0][3]}}]
+ else:
+ return exc
+
+ # if has no input, tell him how to ask questions
+ if not has_token_sequence(tokens, ['input']):
+ return [{'id' : 'input_clause'}]
+
+ # if it has no range, explain how we can create a list (generator) from a number
+ if not has_token_sequence(tokens, ['range']):
+ return [{'id' : 'range_function'}]
+
+ # if it has no print function, tell him to use print
+ if not has_token_sequence(tokens, ['print']):
+ return [{'id' : 'printing'}]
+
+ # if it has no divisoin-by-modulo operator, explain that operator
+ if not has_token_sequence(tokens, ['%']):
+ return [{'id' : 'divisor'}]
+
+ # if the program prints 15 instead of 7,
+ # it means that is adds also itself
+ nums = get_numbers(answer[0][1])
+ if 15 in nums and 7 not in nums:
+ return [{'id' : 'last_number'}]
+
+ # if program prints only the last number or
+ # only the first number, explain how to sum
+ # elements in iterations
+ if 7 not in nums and \
+ (1 in nums or 4 in nums or 8 in nums):
+ return [{'id' : 'summing'}]
+
+
+ return None
diff --git a/python/problems/lists_and_for/perfect_numbers/en.py b/python/problems/lists_and_for/perfect_numbers/en.py
new file mode 100644
index 0000000..19d5262
--- /dev/null
+++ b/python/problems/lists_and_for/perfect_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 217
+name = 'Perfect number'
+slug = 'Perfect number'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/perfect_numbers/sl.py b/python/problems/lists_and_for/perfect_numbers/sl.py
new file mode 100644
index 0000000..bc02d00
--- /dev/null
+++ b/python/problems/lists_and_for/perfect_numbers/sl.py
@@ -0,0 +1,96 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 217
+name = 'Popolna števila'
+slug = 'Popolna števila'
+
+
+description = '''\
+<p> Napiši program, ki izpiše "je popolno", če je podano število popolno, oz.
+"ni popolno", če ni. Popolna števila so števila, ki so enaka vsoti svojih
+deliteljev (brez samega sebe). Primer popolnega števila je 28,
+saj so njegovi delitelji 1, 2, 4, 7, 14, njihova vsota,
+1+2+4+7+14 pa je spet enaka 28. </p>'''
+
+input_clause = ['''\
+Uporabi funkcijo <code>input</code>.
+''']
+
+range_function = ['''\
+Uporabi funkcijo <code>range(a,b)</code>
+''',
+ '''\
+<p>Funkcija <code>range(a, b)</code> pripravi seznam števil od a do števila b-1. Poskusi!</p>''',
+ '''\
+<p>Z zanko <code>for</code> se sprehodi čez elemente seznama oz. v našem primeru
+čez vsa števila od <code>a</code> do <code>b-1</code>.</p>
+''']
+
+divisor = ['''\
+<p>Operator % vrne ostanek pri deljenju.</p>''',
+ '''\
+<pre>
+>>> 5%3
+2
+>>> 17%8
+1
+</pre>''',
+ '''\
+<p>Če je ostanek pri deljenju števila <code>a</code> s številom <code>b</code> enak 0, potem <code>b</code>
+deli število <code>a</code>. </p>''',
+ '''\
+<pre>
+if a%b == 0:
+ # b je delitelj števila a
+</pre>
+''']
+
+summing = ['''\
+<p>Če hočemo delitelje prišteti vsoti, moramo imeti vsoto nekje shranjeno.
+Torej potrebujemo spremenljivko.</p>''',
+ '''\
+<p>Nekako tako: </p>
+<pre>
+vsota = 0
+for ....
+ if ...
+ vsota += d # d deli izbrano število
+</pre>''']
+
+plan = ['''\
+<p>Gre za praktično enako nalogo, kot je bila prejšnja. Le na koncu
+moramo preveriti, če je vsota deliteljev enaka vnešenemu številu. </p>
+''']
+
+
+hint = {
+ 'input_clause': input_clause,
+
+ 'range_function': range_function,
+
+ 'printing': ['''\
+<p>Izpiši rezultat.</p>'''],
+
+ 'divisor': divisor,
+
+ 'final_hint': ['''\
+<p>Naloga rešena! <br>
+Podobno kot prejšnjo, lahko rešitev napišemo krajše: </p>
+<pre>
+n = int(input("Vpiši število: "))
+print(n == sum(i for i in range(1, n) if n % i == 0))
+</pre>'''],
+
+ 'summing': summing,
+
+ 'zero_division': [mod.general_msg['error_head'],
+ mod.general_msg['general_exception'],
+ '''\
+<p>Deljenje z nič ni dovoljeno!</p>''',
+ '''\
+<p>Računanje ostanka z operatorjem % je tudi deljenje.''']
+
+}
diff --git a/python/problems/lists_and_for/places/common.py b/python/problems/lists_and_for/places/common.py
new file mode 100644
index 0000000..e7d1adf
--- /dev/null
+++ b/python/problems/lists_and_for/places/common.py
@@ -0,0 +1,80 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 218
+number = 4
+visible = True
+
+solution = '''\
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+
+mesta = []
+for i in range(len(xs)):
+ if xs[i] == 42:
+ mesta.append(i)
+print(mesta)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ([], []),
+ ([0], []),
+ ([42], [0]),
+ ([4, 2], []),
+ ([42, 42], [0, 1]),
+ ([1, 2, 3, 4, 5, 5, 4, 3, 2, 1], []),
+ ([1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 42], [10]),
+ ([1, 2, 3, 4, 5, 42, 5, 4, 3, 2, 1], [5]),
+ ([1, 2, 42, 4, 5, 42, 5, 4, 42, 2, 1], [2, 5, 8]),
+ ([42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2], [0, 9]),
+ ([42] * 10, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
+ ]
+
+ test_in = [t[0] for t in in_out]
+ test_out = [t[1] for t in in_out]
+
+ n_correct = 0
+ tin = None
+ for xs_i, xs in enumerate(test_in):
+ # change code to contain new xs instead of the one
+ # given by user
+ tcode = re.sub(r'^xs\s*=\s*\[.*?\]',
+ 'xs = ' + str(xs),
+ code,
+ flags = re.DOTALL | re.MULTILINE)
+
+ # use python session to call tcode
+ answers = python(code=tcode, inputs=[(None, None)], timeout=1.0)
+ output = answers[0][1]
+
+ if str(test_out[xs_i]) in output:
+ n_correct += 1
+ else:
+ tin = test_in[xs_i]
+ tout = test_out[xs_i]
+
+ passed = n_correct == len(test_in)
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/places/en.py b/python/problems/lists_and_for/places/en.py
new file mode 100644
index 0000000..95b119f
--- /dev/null
+++ b/python/problems/lists_and_for/places/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 218
+name = 'Places'
+slug = 'Places'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/places/sl.py b/python/problems/lists_and_for/places/sl.py
new file mode 100644
index 0000000..5a435a0
--- /dev/null
+++ b/python/problems/lists_and_for/places/sl.py
@@ -0,0 +1,77 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 218
+name = 'Mesta'
+slug = 'Mesta'
+
+
+description = '''\
+<p>
+Program naj sestavi seznam vseh mest, na katerih se v podanem seznamu pojavi število 42.
+Za seznam iz prve naloge
+<pre>
+xs = [42, 5, 4, -7, 2, 12, -3, -4, 11, 42, 2]
+</pre>
+naj vaš program izpiše [0, 9], saj se število 42 pojavi na ničtem in devetem mestu (če začnemo šteti z 0).
+</p>'''
+
+empty_list = ['''\
+<p>Nov, prazen seznam ustvarimo s stavkom: </p>
+<pre>
+s = []
+</pre>
+''']
+
+enumerate_function = ['''\
+<p> Uporabi funkcijo <code>enumerate</code>.
+</p>
+''',
+ '''\
+<pre>
+for index, val in enumerate(xs):
+ print index, v
+</pre>''',
+ '''\
+<p>V zgornji <code>for</code>zanki se v spremenljivko <code>val</code> zapiše
+trenutni element v seznamu <code>xs</code>, v spremenljivki <code>indeks</code>
+pa je zapisano mesto oz. indeks trenutnega elementa. </p>''']
+
+append_method = [
+ '''\
+<p>V seznam dodamo nov element z metodo <code>append</code>.</p>''',
+ '''\
+<p>Poskusi: </p>
+<pre>
+s = []
+s.append(3)
+s.append(5)
+print (s)
+</pre>''']
+
+plan = ['''\
+<p>S <code>for</code> zanko pojdi čez seznam. Ko naletiš na 42, dodaj mesto trenutnega elementa
+v nov seznam. </p>
+''',
+ '''\
+<p>
+<pre>
+Ustvari prazen seznam mest
+Za vsak element v seznamu
+ Ali je 42?
+ Če je, dodaj trenutno mesto v seznam mest
+Izpiši seznam mest
+</pre>
+</p>''',
+ empty_list,
+ enumerate_function,
+ append_method]
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/prefix/common.py b/python/problems/lists_and_for/prefix/common.py
new file mode 100644
index 0000000..cd649af
--- /dev/null
+++ b/python/problems/lists_and_for/prefix/common.py
@@ -0,0 +1,66 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 221
+number = 7
+visible = True
+
+solution = '''\
+s = input('Vpiši besedo: ')
+
+xs = []
+for i in range(len(s) + 1):
+ xs.append(s[:i])
+print(xs)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ('a', ['', 'a']),
+ ('ab', ['', 'a', 'ab']),
+ ('abc', ['', 'a', 'ab', 'abc']),
+ ('drevo', ['', 'd', 'dr', 'dre', 'drev', 'drevo']),
+ ]
+
+ test_in = [(None, s[0]+'\n') for s in in_out]
+ test_out = [str(s[1]) for s in in_out]
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct = 0
+ tin = None
+ for i, (output, correct) in enumerate(zip(outputs, test_out)):
+ if correct in output:
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = correct
+
+ passed = n_correct == len(test_in)
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
+
+
diff --git a/python/problems/lists_and_for/prefix/en.py b/python/problems/lists_and_for/prefix/en.py
new file mode 100644
index 0000000..ea26765
--- /dev/null
+++ b/python/problems/lists_and_for/prefix/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 221
+name = 'Prefix'
+slug = 'Prefix'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/prefix/sl.py b/python/problems/lists_and_for/prefix/sl.py
new file mode 100644
index 0000000..0a3d391
--- /dev/null
+++ b/python/problems/lists_and_for/prefix/sl.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 221
+name = 'Predpone'
+slug = 'Predpone'
+
+
+description = '''\
+<p>
+Uporabnika prosite, da vam zaupa besedo, nato pa sestavite in izpišite seznam vseh predpon te besede.
+<pre>
+Vpiši besedo: drevo
+['', 'd', 'dr', 'dre', 'drev', 'drevo']
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/split_word/common.py b/python/problems/lists_and_for/split_word/common.py
new file mode 100644
index 0000000..6031b19
--- /dev/null
+++ b/python/problems/lists_and_for/split_word/common.py
@@ -0,0 +1,65 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 222
+number = 8
+visible = True
+
+solution = '''\
+s = input('Vpiši besedo: ')
+
+xs = []
+for i in range(len(s) + 1):
+ xs.append((s[:i], s[i:]))
+print(xs)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ('a', [('', 'a'), ('a', '')]),
+ ('ab', [('', 'ab'), ('a', 'b'), ('ab', '')]),
+ ('abc', [('', 'abc'), ('a', 'bc'), ('ab', 'c'), ('abc', '')]),
+ ('gozd', [('', 'gozd'), ('g', 'ozd'), ('go', 'zd'), ('goz', 'd'), ('gozd', '')]),
+ ]
+
+ test_in = [(None, s[0]+'\n') for s in in_out]
+ test_out = [str(s[1]) for s in in_out]
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct = 0
+ tin = None
+ for i, (output, correct) in enumerate(zip(outputs, test_out)):
+ if correct in output:
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = correct
+
+ passed = n_correct == len(test_in)
+
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/split_word/en.py b/python/problems/lists_and_for/split_word/en.py
new file mode 100644
index 0000000..a6519d0
--- /dev/null
+++ b/python/problems/lists_and_for/split_word/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 222
+name = 'Split word'
+slug = 'Split word'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/split_word/sl.py b/python/problems/lists_and_for/split_word/sl.py
new file mode 100644
index 0000000..80ecfc4
--- /dev/null
+++ b/python/problems/lists_and_for/split_word/sl.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 222
+name = 'Deli'
+slug = 'Deli'
+
+
+description = '''\
+<p>
+Program naj sestavi sezam vseh delitev podane besede.
+<pre>
+Vpiši besedo: gozd
+[('', 'gozd'), ('g', 'ozd'), ('go', 'zd'), ('goz', 'd'), ('gozd', '')]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/lists_and_for/substrings/common.py b/python/problems/lists_and_for/substrings/common.py
new file mode 100644
index 0000000..8128797
--- /dev/null
+++ b/python/problems/lists_and_for/substrings/common.py
@@ -0,0 +1,68 @@
+# coding=utf-8
+
+import re
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
+from server.hints import Hint
+
+id = 223
+number = 9
+visible = True
+
+solution = '''\
+s = input('Vpiši besedo: ')
+
+xs = ['']
+# Zanka po dolžini podniza.
+for i in range(1, len(s) + 1):
+ # Zanka po začetku podniza.
+ for j in range(len(s) - i + 1):
+ xs.append(s[j:j + i])
+print(xs)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ in_out = [
+ ('a', ['', 'a']),
+ ('ab', ['', 'a', 'b', 'ab']),
+ ('abc', ['', 'a', 'b', 'c', 'ab', 'bc', 'abc']),
+ ('tema', ['', 't', 'e', 'm', 'a', 'te', 'em', 'ma', 'tem', 'ema', 'tema']),
+ ]
+
+ test_in = [(None, s[0]+'\n') for s in in_out]
+ test_out = [str(s[1]) for s in in_out]
+ # List of outputs: (expression result, stdout, stderr, exception).
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ outputs = [ans[1] for ans in answers]
+
+ n_correct = 0
+ tin = None
+ for i, (output, correct) in enumerate(zip(outputs, test_out)):
+ if correct in output:
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = correct
+
+ passed = n_correct == len(test_in)
+
+ hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
+ if passed:
+ hints.append({'id': 'final_hint'})
+ return passed, hints
+
+def hint(python, code):
+ tokens = get_tokens(code)
+
+ # run one test first to see if there are any exceptions
+ answer = python(code=code, inputs=[(None, None)], timeout=1.0)
+ exc = get_exception_desc(answer[0][3])
+ if exc: return exc
+
+ return None
diff --git a/python/problems/lists_and_for/substrings/en.py b/python/problems/lists_and_for/substrings/en.py
new file mode 100644
index 0000000..053bee4
--- /dev/null
+++ b/python/problems/lists_and_for/substrings/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 223
+name = 'Substrings'
+slug = 'Substrings'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/lists_and_for/substrings/sl.py b/python/problems/lists_and_for/substrings/sl.py
new file mode 100644
index 0000000..595aee8
--- /dev/null
+++ b/python/problems/lists_and_for/substrings/sl.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 223
+name = 'Podnizi'
+slug = 'Podnizi'
+
+
+description = '''\
+<p>
+Program naj sestavi seznam vseh podnizov podane besede.
+<pre>
+Vpiši besedo: tema
+['', 't', 'e', 'm', 'a', 'te', 'em', 'ma', 'tem', 'ema', 'tema']
+</pre>
+Vrstni red naj bo točno tak kot ga prikazuje primer. Začnemo s praznim nizom,
+nato pridejo na vrsto podnizi dolžine ena, dva, tri, ...
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}