From 8b11dd461c6d13afa852619b213b310e5b74181b Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 5 Oct 2015 17:45:57 +0200 Subject: Added problem divisors. Some small bug fixes. --- python/problems/introduction/average/common.py | 3 - python/problems/lists_and_for/counting/en.py | 6 +- python/problems/lists_and_for/divisors/common.py | 105 +++++++++++++++++++++++ python/problems/lists_and_for/divisors/en.py | 16 ++++ python/problems/lists_and_for/divisors/sl.py | 97 +++++++++++++++++++++ 5 files changed, 221 insertions(+), 6 deletions(-) create mode 100644 python/problems/lists_and_for/divisors/common.py create mode 100644 python/problems/lists_and_for/divisors/en.py create mode 100644 python/problems/lists_and_for/divisors/sl.py (limited to 'python/problems') 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 = '''\

(translation missing)

''' 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 = '''\ +

(translation missing)

''' + +hint = { + 'plan': '''\ +

(translation missing)

''', + + 'no_input_call': '''\ +

(translation missing)

''', +} 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 = '''\ +

Napiši program, ki izpiše vse delitelje števila, ki ga vnese uporabnik..''' + + +input_clause = ['''\ +Uporabi funkcijo input. +'''] + +range_function = ['''\ +Uporabi funkcijo range(a,b) +''', + '''\ +

Funkcija range(a, b) pripravi seznam števil od a do števila b-1. Poskusi!

''', + '''\ +

Z zanko for se sprehodi čez elemente seznama oz. v našem primeru +čez vsa števila od a do b-1.

+'''] + +divisor = ['''\ +

Operator % vrne ostanek pri deljenju.

''', + '''\ +
+>>> 5%3
+2
+>>> 17%8
+1
+
''', + '''\ +

Če je ostanek pri deljenju števila a s številom b enak 0, potem b +deli število a.

''', + '''\ +
+if a%b == 0:
+    # b je delitelj števila a
+
+'''] + +plan = ['''\ +

Preglej vsa števila od 1 do n-1 in izpiši tista, ki delijo n.

+''', + '''\ +

Plan:

+
+Uporabnik vnese število n
+Za vsak element v seznamu [1, 2, ..., n-1]
+    Preveri, če to število deli n
+        Izpiši število
+
+''', + range_function, + divisor] + + +hint = { + 'input_clause': input_clause, + + 'range_function': range_function, + + 'printing': ['''\ +

Izpiši rezultat.

'''], + + 'divisor': divisor, + + 'last_number': ['''\ +

Število deli samega sebe!

'''], + + 'final_hint:': ['''\ +

Naloga rešena!

+ +

Dejansko ne potrebujemo pregledati vseh števil med 1 in n-1, + dovolj bo če gremo do kvadratnega korena od števila n:

+
+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)
+
'''], + + 'zero_division': [mod.general_msg['error_head'], + mod.general_msg['general_exception'], + '''\ +

Deljenje z nič ni dovoljeno!

''', + '''\ +

Računanje ostanka z operatorjem % je tudi deljenje.'''] + +} -- cgit v1.2.1