summaryrefslogtreecommitdiff
path: root/python/problems
diff options
context:
space:
mode:
authorMartin <martin@leo.fri1.uni-lj.si>2015-10-05 17:45:57 +0200
committerMartin <martin@leo.fri1.uni-lj.si>2015-10-05 17:45:57 +0200
commit8b11dd461c6d13afa852619b213b310e5b74181b (patch)
treeac1cc8c6e6d7f38cfd6c425d80422f8c85efb8b3 /python/problems
parente63627ad942a7d2c9eebb86f15c96191e7408eb8 (diff)
Added problem divisors.
Some small bug fixes.
Diffstat (limited to 'python/problems')
-rw-r--r--python/problems/introduction/average/common.py3
-rw-r--r--python/problems/lists_and_for/counting/en.py6
-rw-r--r--python/problems/lists_and_for/divisors/common.py105
-rw-r--r--python/problems/lists_and_for/divisors/en.py16
-rw-r--r--python/problems/lists_and_for/divisors/sl.py97
5 files changed, 221 insertions, 6 deletions
diff --git a/python/problems/introduction/average/common.py b/python/problems/introduction/average/common.py
index 1609a6f..4e7e97c 100644
--- a/python/problems/introduction/average/common.py
+++ b/python/problems/introduction/average/common.py
@@ -49,14 +49,11 @@ def test(python, code):
]
# List of outputs: (expression result, stdout, stderr, exception).
- print ("ena")
answers = python(code=code, inputs=test_in, timeout=1.0)
outputs = [ans[1] for ans in answers]
n_correct = 0
tin = None
- print (outputs)
- print (test_out)
for i, (output, correct) in enumerate(zip(outputs, test_out)):
if string_almost_equal(output, correct[0]) and \
string_almost_equal(output, correct[1]):
diff --git a/python/problems/lists_and_for/counting/en.py b/python/problems/lists_and_for/counting/en.py
index 805b37c..19568e3 100644
--- a/python/problems/lists_and_for/counting/en.py
+++ b/python/problems/lists_and_for/counting/en.py
@@ -1,8 +1,8 @@
# coding=utf-8
-id = 193
-name = 'Contains 42'
-slug = 'Contains 42'
+id = 203
+name = 'Counting'
+slug = 'Counting'
description = '''\
<p>(translation missing)</p>'''
diff --git a/python/problems/lists_and_for/divisors/common.py b/python/problems/lists_and_for/divisors/common.py
new file mode 100644
index 0000000..4f440e4
--- /dev/null
+++ b/python/problems/lists_and_for/divisors/common.py
@@ -0,0 +1,105 @@
+# 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 = 204
+group = 'lists_and_for'
+number = 4
+visible = True
+
+solution = '''\
+n = int(input('Vnesi število: '))
+for i in range(1, n+1):
+ if n % i == 0:
+ print(i)
+'''
+
+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'),
+}
+
+def test(python, code):
+ test_in = [
+ (None, '8\n'),
+ (None, '6\n'),
+ (None, '5\n'),
+ (None, '2\n'),
+ (None, '15\n'),
+ (None, '20\n'),
+ ]
+ values = [8, 6, 5, 2, 15, 20]
+
+ # 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, v) in enumerate(zip(outputs, values)):
+ correct = True
+ clist = []
+ nums = get_numbers(output)
+ for vi in range(1, v+1):
+ if v%vi == 0:
+ clist.append(vi)
+ if v%vi == 0 and vi not in nums:
+ correct = False
+ if v%vi != 0 and vi in nums:
+ correct = False
+ if correct:
+ n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = clist
+
+ 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):
+ # 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
+
+ tokens = get_tokens(code)
+
+ # 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 all divisors but 8,
+ # it means that is skips itself
+ nums = get_numbers(answer[0][1])
+ if 1 in nums and 2 in nums and 4 in nums and 8 not in nums:
+ return [{'id' : 'last_number'}]
+
+ return None
diff --git a/python/problems/lists_and_for/divisors/en.py b/python/problems/lists_and_for/divisors/en.py
new file mode 100644
index 0000000..e98e9a7
--- /dev/null
+++ b/python/problems/lists_and_for/divisors/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 204
+name = 'Divisors'
+slug = 'Divisors'
+
+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/sl.py b/python/problems/lists_and_for/divisors/sl.py
new file mode 100644
index 0000000..5ba36e1
--- /dev/null
+++ b/python/problems/lists_and_for/divisors/sl.py
@@ -0,0 +1,97 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 204
+name = 'Delitelji'
+slug = 'Delitelji'
+
+
+description = '''\
+<p>Napiši program, ki izpiše vse delitelje števila, ki ga vnese uporabnik..'''
+
+
+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>
+''']
+
+plan = ['''\
+<p>Preglej vsa števila od <code>1</code> do <code>n-1</code> in izpiši tista, ki delijo <code>n</code>.</p>
+''',
+ '''\
+<p>Plan: </p>
+<pre>
+Uporabnik vnese število n
+Za vsak element v seznamu [1, 2, ..., n-1]
+ Preveri, če to število deli n
+ Izpiši število
+</pre>
+''',
+ range_function,
+ divisor]
+
+
+hint = {
+ 'input_clause': input_clause,
+
+ 'range_function': range_function,
+
+ 'printing': ['''\
+<p>Izpiši rezultat.</p>'''],
+
+ 'divisor': divisor,
+
+ 'last_number': ['''\
+<p>Število deli samega sebe!</p>'''],
+
+ '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>
+ <pre>
+from math import sqrt
+n = int(input('Vnesi število: '))
+for i in range(1, sqrt(n)+1):
+ if n % i == 0:
+ print(i, n/i)
+</pre>'''],
+
+ '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.''']
+
+}