summaryrefslogtreecommitdiff
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
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
-rw-r--r--prolog/common.py2
-rw-r--r--prolog/problems/clp_fd/common.py2
-rw-r--r--prolog/problems/clp_fd/gcd_3/common.py1
-rw-r--r--prolog/problems/clp_fd/gcd_3/en.py1
-rw-r--r--prolog/problems/clp_fd/magic_1/common.py1
-rw-r--r--prolog/problems/clp_fd/magic_1/en.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_abc_3/common.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_abc_3/en.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_beth_1/common.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_beth_1/en.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_momson_2/common.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_momson_2/en.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_ratio_2/common.py1
-rw-r--r--prolog/problems/clp_fd/puzzle_ratio_2/en.py1
-rw-r--r--prolog/problems/clp_fd/tobase_3/common.py1
-rw-r--r--prolog/problems/clp_fd/tobase_3/en.py1
-rw-r--r--prolog/problems/clp_r/bounding_box_3/common.py1
-rw-r--r--prolog/problems/clp_r/bounding_box_3/en.py1
-rw-r--r--prolog/problems/clp_r/center_3/common.py1
-rw-r--r--prolog/problems/clp_r/center_3/en.py1
-rw-r--r--prolog/problems/clp_r/common.py2
-rw-r--r--prolog/problems/clp_r/linear_opt_3/common.py1
-rw-r--r--prolog/problems/clp_r/linear_opt_3/en.py1
-rw-r--r--prolog/problems/clp_r/max_sum_2/common.py1
-rw-r--r--prolog/problems/clp_r/max_sum_2/en.py1
-rw-r--r--prolog/problems/clp_r/megabytes_2/common.py1
-rw-r--r--prolog/problems/clp_r/megabytes_2/en.py1
-rw-r--r--prolog/problems/clp_r/turkey_3/common.py1
-rw-r--r--prolog/problems/clp_r/turkey_3/en.py1
-rw-r--r--prolog/problems/dcg/ab_2/common.py1
-rw-r--r--prolog/problems/dcg/ab_2/en.py1
-rw-r--r--prolog/problems/dcg/common.py2
-rw-r--r--prolog/problems/dcg/digit_2/common.py1
-rw-r--r--prolog/problems/dcg/digit_2/en.py1
-rw-r--r--prolog/problems/dcg/expr_2/common.py1
-rw-r--r--prolog/problems/dcg/expr_2/en.py1
-rw-r--r--prolog/problems/dcg/expr_3/common.py1
-rw-r--r--prolog/problems/dcg/expr_3/en.py1
-rw-r--r--prolog/problems/dcg/flower_2/common.py1
-rw-r--r--prolog/problems/dcg/flower_2/en.py1
-rw-r--r--prolog/problems/dcg/number_2/common.py1
-rw-r--r--prolog/problems/dcg/number_2/en.py1
-rw-r--r--prolog/problems/dcg/number_3/common.py1
-rw-r--r--prolog/problems/dcg/number_3/en.py1
-rw-r--r--prolog/problems/dcg/number_proper_2/common.py1
-rw-r--r--prolog/problems/dcg/number_proper_2/en.py1
-rw-r--r--prolog/problems/dcg/paren_2/common.py1
-rw-r--r--prolog/problems/dcg/paren_2/en.py1
-rw-r--r--prolog/problems/dcg/paren_3/common.py1
-rw-r--r--prolog/problems/dcg/paren_3/en.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_3/common.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_3/en.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_for_3/common.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_for_3/en.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_if_3/common.py1
-rw-r--r--prolog/problems/denotational_semantics/algol_if_3/en.py1
-rw-r--r--prolog/problems/denotational_semantics/common.py2
-rw-r--r--prolog/problems/denotational_semantics/prog_8puzzle_2/common.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_8puzzle_2/en.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_8puzzle_3/common.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_8puzzle_3/en.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_listswap_2/common.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_listswap_2/en.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_listswap_3/common.py1
-rw-r--r--prolog/problems/denotational_semantics/prog_listswap_3/en.py1
-rw-r--r--prolog/problems/family_relations/ancestor_2/common.py1
-rw-r--r--prolog/problems/family_relations/ancestor_2/en.py1
-rw-r--r--prolog/problems/family_relations/ancestor_2/sl.py1
-rw-r--r--prolog/problems/family_relations/aunt_2/common.py1
-rw-r--r--prolog/problems/family_relations/aunt_2/en.py1
-rw-r--r--prolog/problems/family_relations/aunt_2/sl.py1
-rw-r--r--prolog/problems/family_relations/brother_2/common.py1
-rw-r--r--prolog/problems/family_relations/brother_2/en.py1
-rw-r--r--prolog/problems/family_relations/brother_2/sl.py1
-rw-r--r--prolog/problems/family_relations/common.py2
-rw-r--r--prolog/problems/family_relations/connected_3/common.py1
-rw-r--r--prolog/problems/family_relations/connected_3/en.py1
-rw-r--r--prolog/problems/family_relations/cousin_2/common.py1
-rw-r--r--prolog/problems/family_relations/cousin_2/en.py1
-rw-r--r--prolog/problems/family_relations/cousin_2/sl.py1
-rw-r--r--prolog/problems/family_relations/descendant_2/common.py1
-rw-r--r--prolog/problems/family_relations/descendant_2/en.py1
-rw-r--r--prolog/problems/family_relations/descendant_2/sl.py1
-rw-r--r--prolog/problems/family_relations/father_2/common.py1
-rw-r--r--prolog/problems/family_relations/father_2/en.py1
-rw-r--r--prolog/problems/family_relations/father_2/sl.py1
-rw-r--r--prolog/problems/family_relations/grandparent_2/common.py1
-rw-r--r--prolog/problems/family_relations/grandparent_2/en.py1
-rw-r--r--prolog/problems/family_relations/grandparent_2/sl.py1
-rw-r--r--prolog/problems/family_relations/mother_2/common.py1
-rw-r--r--prolog/problems/family_relations/mother_2/en.py1
-rw-r--r--prolog/problems/family_relations/mother_2/sl.py1
-rw-r--r--prolog/problems/family_relations/sister_2/common.py1
-rw-r--r--prolog/problems/family_relations/sister_2/en.py1
-rw-r--r--prolog/problems/family_relations/sister_2/sl.py1
-rw-r--r--prolog/problems/license_plates/checklicenseplate_3/common.py1
-rw-r--r--prolog/problems/license_plates/checklicenseplate_3/en.py1
-rw-r--r--prolog/problems/license_plates/common.py2
-rw-r--r--prolog/problems/license_plates/firstminus_2/common.py1
-rw-r--r--prolog/problems/license_plates/firstminus_2/en.py1
-rw-r--r--prolog/problems/license_plates/genexp_2/common.py1
-rw-r--r--prolog/problems/license_plates/genexp_2/en.py1
-rw-r--r--prolog/problems/license_plates/getdigits_2/common.py1
-rw-r--r--prolog/problems/license_plates/getdigits_2/en.py1
-rw-r--r--prolog/problems/license_plates/joindigits_2/common.py1
-rw-r--r--prolog/problems/license_plates/joindigits_2/en.py1
-rw-r--r--prolog/problems/lists/common.py2
-rw-r--r--prolog/problems/lists/conc_3/common.py1
-rw-r--r--prolog/problems/lists/conc_3/en.py1
-rw-r--r--prolog/problems/lists/count_3/common.py1
-rw-r--r--prolog/problems/lists/count_3/en.py1
-rw-r--r--prolog/problems/lists/del_3/common.py1
-rw-r--r--prolog/problems/lists/del_3/en.py1
-rw-r--r--prolog/problems/lists/divide_3/common.py1
-rw-r--r--prolog/problems/lists/divide_3/en.py1
-rw-r--r--prolog/problems/lists/dup_2/common.py1
-rw-r--r--prolog/problems/lists/dup_2/en.py1
-rw-r--r--prolog/problems/lists/evenlen_1_+_oddlen_1/common.py1
-rw-r--r--prolog/problems/lists/evenlen_1_+_oddlen_1/en.py1
-rw-r--r--prolog/problems/lists/insert_3/common.py1
-rw-r--r--prolog/problems/lists/insert_3/en.py1
-rw-r--r--prolog/problems/lists/len_2/common.py1
-rw-r--r--prolog/problems/lists/len_2/en.py1
-rw-r--r--prolog/problems/lists/max_2/common.py1
-rw-r--r--prolog/problems/lists/max_2/en.py1
-rw-r--r--prolog/problems/lists/memb_2/common.py1
-rw-r--r--prolog/problems/lists/memb_2/en.py1
-rw-r--r--prolog/problems/lists/min_2/common.py1
-rw-r--r--prolog/problems/lists/min_2/en.py1
-rw-r--r--prolog/problems/lists/palindrome_1/common.py1
-rw-r--r--prolog/problems/lists/palindrome_1/en.py1
-rw-r--r--prolog/problems/lists/permute_2/common.py1
-rw-r--r--prolog/problems/lists/permute_2/en.py1
-rw-r--r--prolog/problems/lists/rev_2/common.py1
-rw-r--r--prolog/problems/lists/rev_2/en.py1
-rw-r--r--prolog/problems/lists/shiftleft_2/common.py1
-rw-r--r--prolog/problems/lists/shiftleft_2/en.py1
-rw-r--r--prolog/problems/lists/shiftright_2/common.py1
-rw-r--r--prolog/problems/lists/shiftright_2/en.py1
-rw-r--r--prolog/problems/lists/sublist_2/common.py1
-rw-r--r--prolog/problems/lists/sublist_2/en.py1
-rw-r--r--prolog/problems/lists/sum_2/common.py1
-rw-r--r--prolog/problems/lists/sum_2/en.py1
-rw-r--r--prolog/problems/old_exams/common.py1
-rw-r--r--prolog/problems/old_exams/pascal_3/common.py1
-rw-r--r--prolog/problems/old_exams/pascal_3/en.py1
-rw-r--r--prolog/problems/other/common.py1
-rw-r--r--prolog/problems/other/genlist_4/common.py1
-rw-r--r--prolog/problems/other/genlist_4/en.py1
-rw-r--r--prolog/problems/sets/common.py2
-rw-r--r--prolog/problems/sets/diff_3/common.py1
-rw-r--r--prolog/problems/sets/diff_3/en.py1
-rw-r--r--prolog/problems/sets/intersect_3/common.py1
-rw-r--r--prolog/problems/sets/intersect_3/en.py1
-rw-r--r--prolog/problems/sets/is_subset_2/common.py1
-rw-r--r--prolog/problems/sets/is_subset_2/en.py1
-rw-r--r--prolog/problems/sets/is_superset_2/common.py1
-rw-r--r--prolog/problems/sets/is_superset_2/en.py1
-rw-r--r--prolog/problems/sets/powerset_2/common.py1
-rw-r--r--prolog/problems/sets/powerset_2/en.py1
-rw-r--r--prolog/problems/sets/subset_2/common.py1
-rw-r--r--prolog/problems/sets/subset_2/en.py1
-rw-r--r--prolog/problems/sets/union_3/common.py1
-rw-r--r--prolog/problems/sets/union_3/en.py1
-rw-r--r--prolog/problems/sorting/common.py2
-rw-r--r--prolog/problems/sorting/is_sorted_1/common.py1
-rw-r--r--prolog/problems/sorting/is_sorted_1/en.py1
-rw-r--r--prolog/problems/sorting/isort_2/common.py1
-rw-r--r--prolog/problems/sorting/isort_2/en.py1
-rw-r--r--prolog/problems/sorting/pivoting_4/common.py1
-rw-r--r--prolog/problems/sorting/pivoting_4/en.py1
-rw-r--r--prolog/problems/sorting/quick_sort_2/common.py1
-rw-r--r--prolog/problems/sorting/quick_sort_2/en.py1
-rw-r--r--prolog/problems/sorting/sins_3/common.py1
-rw-r--r--prolog/problems/sorting/sins_3/en.py1
-rw-r--r--prolog/problems/sorting/slowest_sort_ever_2/common.py1
-rw-r--r--prolog/problems/sorting/slowest_sort_ever_2/en.py1
-rw-r--r--prolog/problems/trees/common.py2
-rw-r--r--prolog/problems/trees/deletebt_3/common.py1
-rw-r--r--prolog/problems/trees/deletebt_3/en.py1
-rw-r--r--prolog/problems/trees/depthbt_2/common.py1
-rw-r--r--prolog/problems/trees/depthbt_2/en.py1
-rw-r--r--prolog/problems/trees/insertbt_3/common.py1
-rw-r--r--prolog/problems/trees/insertbt_3/en.py1
-rw-r--r--prolog/problems/trees/maxt_2/common.py1
-rw-r--r--prolog/problems/trees/maxt_2/en.py1
-rw-r--r--prolog/problems/trees/memberbt_2/common.py1
-rw-r--r--prolog/problems/trees/memberbt_2/en.py1
-rw-r--r--prolog/problems/trees/membert_2/common.py1
-rw-r--r--prolog/problems/trees/membert_2/en.py1
-rw-r--r--prolog/problems/trees/mirrorbt_2/common.py1
-rw-r--r--prolog/problems/trees/mirrorbt_2/en.py1
-rw-r--r--prolog/problems/trees/numberbt_2/common.py1
-rw-r--r--prolog/problems/trees/numberbt_2/en.py1
-rw-r--r--prolog/problems/trees/tolistbt_2/common.py1
-rw-r--r--prolog/problems/trees/tolistbt_2/en.py1
-rw-r--r--python/common.py2
-rw-r--r--python/problems/functions/assign_numbers/common.py64
-rw-r--r--python/problems/functions/assign_numbers/en.py16
-rw-r--r--python/problems/functions/assign_numbers/sl.py34
-rw-r--r--python/problems/functions/body_mass_index/common.py67
-rw-r--r--python/problems/functions/body_mass_index/en.py16
-rw-r--r--python/problems/functions/body_mass_index/sl.py35
-rw-r--r--python/problems/functions/body_mass_index_2/common.py66
-rw-r--r--python/problems/functions/body_mass_index_2/en.py15
-rw-r--r--python/problems/functions/body_mass_index_2/sl.py31
-rw-r--r--python/problems/functions/common.py2
-rw-r--r--python/problems/functions/divisors/common.py69
-rw-r--r--python/problems/functions/divisors/en.py16
-rw-r--r--python/problems/functions/divisors/sl.py26
-rw-r--r--python/problems/functions/divisors_sum/common.py69
-rw-r--r--python/problems/functions/divisors_sum/en.py16
-rw-r--r--python/problems/functions/divisors_sum/sl.py27
-rw-r--r--python/problems/functions/friendly_numbers/common.py75
-rw-r--r--python/problems/functions/friendly_numbers/en.py16
-rw-r--r--python/problems/functions/friendly_numbers/sl.py37
-rw-r--r--python/problems/functions/greatest/common.py5
-rw-r--r--python/problems/functions/greatest/en.py1
-rw-r--r--python/problems/functions/greatest/sl.py1
-rw-r--r--python/problems/functions/greatest_absolutist/common.py5
-rw-r--r--python/problems/functions/greatest_absolutist/en.py1
-rw-r--r--python/problems/functions/greatest_absolutist/sl.py3
-rw-r--r--python/problems/functions/greatest_negative/common.py5
-rw-r--r--python/problems/functions/greatest_negative/en.py1
-rw-r--r--python/problems/functions/greatest_negative/sl.py1
-rw-r--r--python/problems/functions/palindrome/common.py68
-rw-r--r--python/problems/functions/palindrome/en.py16
-rw-r--r--python/problems/functions/palindrome/sl.py33
-rw-r--r--python/problems/functions/palindromic_numbers/common.py70
-rw-r--r--python/problems/functions/palindromic_numbers/en.py16
-rw-r--r--python/problems/functions/palindromic_numbers/sl.py31
-rw-r--r--python/problems/functions/perfect_numbers/common.py71
-rw-r--r--python/problems/functions/perfect_numbers/en.py16
-rw-r--r--python/problems/functions/perfect_numbers/sl.py30
-rw-r--r--python/problems/functions/prime_numbers/common.py69
-rw-r--r--python/problems/functions/prime_numbers/en.py16
-rw-r--r--python/problems/functions/prime_numbers/sl.py27
-rw-r--r--python/problems/functions_and_modules/all/common.py72
-rw-r--r--python/problems/functions_and_modules/all/en.py16
-rw-r--r--python/problems/functions_and_modules/all/sl.py40
-rw-r--r--python/problems/functions_and_modules/any/common.py70
-rw-r--r--python/problems/functions_and_modules/any/en.py16
-rw-r--r--python/problems/functions_and_modules/any/sl.py34
-rw-r--r--python/problems/functions_and_modules/caesar_cipher/common.py79
-rw-r--r--python/problems/functions_and_modules/caesar_cipher/en.py16
-rw-r--r--python/problems/functions_and_modules/caesar_cipher/sl.py35
-rw-r--r--python/problems/functions_and_modules/common.py2
-rw-r--r--python/problems/functions_and_modules/dominoes/common.py69
-rw-r--r--python/problems/functions_and_modules/dominoes/en.py16
-rw-r--r--python/problems/functions_and_modules/dominoes/sl.py29
-rw-r--r--python/problems/functions_and_modules/en.py3
-rw-r--r--python/problems/functions_and_modules/largest_sublist/common.py73
-rw-r--r--python/problems/functions_and_modules/largest_sublist/en.py16
-rw-r--r--python/problems/functions_and_modules/largest_sublist/sl.py33
-rw-r--r--python/problems/functions_and_modules/lists_sum/common.py72
-rw-r--r--python/problems/functions_and_modules/lists_sum/en.py16
-rw-r--r--python/problems/functions_and_modules/lists_sum/sl.py35
-rw-r--r--python/problems/functions_and_modules/longest_word/common.py71
-rw-r--r--python/problems/functions_and_modules/longest_word/en.py16
-rw-r--r--python/problems/functions_and_modules/longest_word/sl.py30
-rw-r--r--python/problems/functions_and_modules/map/common.py65
-rw-r--r--python/problems/functions_and_modules/map/en.py16
-rw-r--r--python/problems/functions_and_modules/map/sl.py34
-rw-r--r--python/problems/functions_and_modules/multiplicative_range/common.py68
-rw-r--r--python/problems/functions_and_modules/multiplicative_range/en.py16
-rw-r--r--python/problems/functions_and_modules/multiplicative_range/sl.py32
-rw-r--r--python/problems/functions_and_modules/similarity/common.py73
-rw-r--r--python/problems/functions_and_modules/similarity/en.py16
-rw-r--r--python/problems/functions_and_modules/similarity/sl.py39
-rw-r--r--python/problems/functions_and_modules/sl.py3
-rw-r--r--python/problems/functions_and_modules/suspicious_words/common.py70
-rw-r--r--python/problems/functions_and_modules/suspicious_words/en.py16
-rw-r--r--python/problems/functions_and_modules/suspicious_words/sl.py32
-rw-r--r--python/problems/introduction/average/common.py1
-rw-r--r--python/problems/introduction/average/en.py1
-rw-r--r--python/problems/introduction/average/sl.py1
-rw-r--r--python/problems/introduction/ballistics/common.py1
-rw-r--r--python/problems/introduction/ballistics/en.py1
-rw-r--r--python/problems/introduction/ballistics/sl.py1
-rw-r--r--python/problems/introduction/common.py2
-rw-r--r--python/problems/introduction/fahrenheit_to_celsius/common.py5
-rw-r--r--python/problems/introduction/fahrenheit_to_celsius/en.py1
-rw-r--r--python/problems/introduction/fahrenheit_to_celsius/sl.py3
-rw-r--r--python/problems/introduction/fast_fingers/common.py1
-rw-r--r--python/problems/introduction/fast_fingers/en.py1
-rw-r--r--python/problems/introduction/fast_fingers/sl.py1
-rw-r--r--python/problems/introduction/fast_fingers_2/common.py1
-rw-r--r--python/problems/introduction/fast_fingers_2/en.py1
-rw-r--r--python/problems/introduction/fast_fingers_2/sl.py1
-rw-r--r--python/problems/introduction/pythagorean_theorem/common.py1
-rw-r--r--python/problems/introduction/pythagorean_theorem/en.py1
-rw-r--r--python/problems/introduction/pythagorean_theorem/sl.py1
-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
-rw-r--r--python/problems/while_and_if/buy_five/common.py1
-rw-r--r--python/problems/while_and_if/buy_five/en.py1
-rw-r--r--python/problems/while_and_if/buy_five/sl.py13
-rw-r--r--python/problems/while_and_if/checking_account/common.py1
-rw-r--r--python/problems/while_and_if/checking_account/en.py4
-rw-r--r--python/problems/while_and_if/checking_account/sl.py5
-rw-r--r--python/problems/while_and_if/common.py2
-rw-r--r--python/problems/while_and_if/competition/common.py1
-rw-r--r--python/problems/while_and_if/competition/en.py1
-rw-r--r--python/problems/while_and_if/competition/sl.py7
-rw-r--r--python/problems/while_and_if/consumers_anonymous/common.py3
-rw-r--r--python/problems/while_and_if/consumers_anonymous/en.py4
-rw-r--r--python/problems/while_and_if/consumers_anonymous/sl.py11
-rw-r--r--python/problems/while_and_if/minimax/common.py3
-rw-r--r--python/problems/while_and_if/minimax/en.py1
-rw-r--r--python/problems/while_and_if/minimax/sl.py3
-rw-r--r--python/problems/while_and_if/top_shop/common.py3
-rw-r--r--python/problems/while_and_if/top_shop/en.py1
-rw-r--r--python/problems/while_and_if/top_shop/sl.py6
-rw-r--r--python/sl.py8
-rw-r--r--readme.md28
-rw-r--r--robot/common.py2
-rw-r--r--robot/problems/introduction/common.py2
-rw-r--r--robot/problems/introduction/forward/common.py1
-rw-r--r--robot/problems/introduction/forward/en.py3
-rw-r--r--robot/problems/introduction/forward/sl.py3
358 files changed, 4132 insertions, 299 deletions
diff --git a/prolog/common.py b/prolog/common.py
index 654ab81..1ab4522 100644
--- a/prolog/common.py
+++ b/prolog/common.py
@@ -4,6 +4,8 @@ import operator
import prolog.engine
from server.hints import Hint, HintSequence
+id = 1
+
hint_type = {
'no_hint': Hint('no_hint'),
'program_already_correct': Hint('program_already_correct'),
diff --git a/prolog/problems/clp_fd/common.py b/prolog/problems/clp_fd/common.py
new file mode 100644
index 0000000..3b1f9cf
--- /dev/null
+++ b/prolog/problems/clp_fd/common.py
@@ -0,0 +1,2 @@
+id = 8
+number = 7
diff --git a/prolog/problems/clp_fd/gcd_3/common.py b/prolog/problems/clp_fd/gcd_3/common.py
index a24926f..7cd6623 100644
--- a/prolog/problems/clp_fd/gcd_3/common.py
+++ b/prolog/problems/clp_fd/gcd_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 149
-group = 'clp_fd'
number = 61
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/gcd_3/en.py b/prolog/problems/clp_fd/gcd_3/en.py
index d6c92b7..7953eb1 100644
--- a/prolog/problems/clp_fd/gcd_3/en.py
+++ b/prolog/problems/clp_fd/gcd_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 149
name = 'gcd/3'
slug = 'greatest common divisor'
diff --git a/prolog/problems/clp_fd/magic_1/common.py b/prolog/problems/clp_fd/magic_1/common.py
index 93286e7..17a9199 100644
--- a/prolog/problems/clp_fd/magic_1/common.py
+++ b/prolog/problems/clp_fd/magic_1/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 151
-group = 'clp_fd'
number = 60
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/magic_1/en.py b/prolog/problems/clp_fd/magic_1/en.py
index 04c1481..c8b5a1a 100644
--- a/prolog/problems/clp_fd/magic_1/en.py
+++ b/prolog/problems/clp_fd/magic_1/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 151
name = 'magic/1'
slug = 'generate a 3x3 magic square'
diff --git a/prolog/problems/clp_fd/puzzle_abc_3/common.py b/prolog/problems/clp_fd/puzzle_abc_3/common.py
index 42463a6..1563e1f 100644
--- a/prolog/problems/clp_fd/puzzle_abc_3/common.py
+++ b/prolog/problems/clp_fd/puzzle_abc_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 153
-group = 'clp_fd'
number = 57
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/puzzle_abc_3/en.py b/prolog/problems/clp_fd/puzzle_abc_3/en.py
index 3d70715..899b428 100644
--- a/prolog/problems/clp_fd/puzzle_abc_3/en.py
+++ b/prolog/problems/clp_fd/puzzle_abc_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 153
name = 'puzzle_abc/3'
slug = 'age puzzle: abc'
diff --git a/prolog/problems/clp_fd/puzzle_beth_1/common.py b/prolog/problems/clp_fd/puzzle_beth_1/common.py
index 3321d52..bf81396 100644
--- a/prolog/problems/clp_fd/puzzle_beth_1/common.py
+++ b/prolog/problems/clp_fd/puzzle_beth_1/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 155
-group = 'clp_fd'
number = 56
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/puzzle_beth_1/en.py b/prolog/problems/clp_fd/puzzle_beth_1/en.py
index fed373c..3dea18c 100644
--- a/prolog/problems/clp_fd/puzzle_beth_1/en.py
+++ b/prolog/problems/clp_fd/puzzle_beth_1/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 155
name = 'puzzle_beth/1'
slug = 'age puzzle: beth'
diff --git a/prolog/problems/clp_fd/puzzle_momson_2/common.py b/prolog/problems/clp_fd/puzzle_momson_2/common.py
index 94e5aa2..9cef246 100644
--- a/prolog/problems/clp_fd/puzzle_momson_2/common.py
+++ b/prolog/problems/clp_fd/puzzle_momson_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 152
-group = 'clp_fd'
number = 58
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/puzzle_momson_2/en.py b/prolog/problems/clp_fd/puzzle_momson_2/en.py
index cf97abf..b9b26cb 100644
--- a/prolog/problems/clp_fd/puzzle_momson_2/en.py
+++ b/prolog/problems/clp_fd/puzzle_momson_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 152
name = 'puzzle_momson/2'
slug = 'age puzzle: mom & son'
diff --git a/prolog/problems/clp_fd/puzzle_ratio_2/common.py b/prolog/problems/clp_fd/puzzle_ratio_2/common.py
index baf7c02..73b9234 100644
--- a/prolog/problems/clp_fd/puzzle_ratio_2/common.py
+++ b/prolog/problems/clp_fd/puzzle_ratio_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 154
-group = 'clp_fd'
number = 59
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/puzzle_ratio_2/en.py b/prolog/problems/clp_fd/puzzle_ratio_2/en.py
index 28fc999..2cb3039 100644
--- a/prolog/problems/clp_fd/puzzle_ratio_2/en.py
+++ b/prolog/problems/clp_fd/puzzle_ratio_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 154
name = 'puzzle_ratio/2'
slug = 'age puzzle: ratio'
diff --git a/prolog/problems/clp_fd/tobase_3/common.py b/prolog/problems/clp_fd/tobase_3/common.py
index 3a29dbe..5d160d7 100644
--- a/prolog/problems/clp_fd/tobase_3/common.py
+++ b/prolog/problems/clp_fd/tobase_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 150
-group = 'clp_fd'
number = 62
visible = True
facts = None
diff --git a/prolog/problems/clp_fd/tobase_3/en.py b/prolog/problems/clp_fd/tobase_3/en.py
index a778ccb..c05ab2a 100644
--- a/prolog/problems/clp_fd/tobase_3/en.py
+++ b/prolog/problems/clp_fd/tobase_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 150
name = 'tobase/3'
slug = 'convert numbers from/to the decimal system'
diff --git a/prolog/problems/clp_r/bounding_box_3/common.py b/prolog/problems/clp_r/bounding_box_3/common.py
index dc6b047..94be5ee 100644
--- a/prolog/problems/clp_r/bounding_box_3/common.py
+++ b/prolog/problems/clp_r/bounding_box_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 157
-group = 'clp_r'
number = 67
visible = True
facts = None
diff --git a/prolog/problems/clp_r/bounding_box_3/en.py b/prolog/problems/clp_r/bounding_box_3/en.py
index 714f8a4..8c6a9f7 100644
--- a/prolog/problems/clp_r/bounding_box_3/en.py
+++ b/prolog/problems/clp_r/bounding_box_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 157
name = 'bounding_box/3'
slug = 'find the smallest bounding box'
diff --git a/prolog/problems/clp_r/center_3/common.py b/prolog/problems/clp_r/center_3/common.py
index 340cd7f..5391180 100644
--- a/prolog/problems/clp_r/center_3/common.py
+++ b/prolog/problems/clp_r/center_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 158
-group = 'clp_r'
number = 68
visible = True
facts = None
diff --git a/prolog/problems/clp_r/center_3/en.py b/prolog/problems/clp_r/center_3/en.py
index 2c1f882..ae5aeb8 100644
--- a/prolog/problems/clp_r/center_3/en.py
+++ b/prolog/problems/clp_r/center_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 158
name = 'center/3'
slug = 'find central points'
diff --git a/prolog/problems/clp_r/common.py b/prolog/problems/clp_r/common.py
new file mode 100644
index 0000000..2238250
--- /dev/null
+++ b/prolog/problems/clp_r/common.py
@@ -0,0 +1,2 @@
+id = 9
+number = 8
diff --git a/prolog/problems/clp_r/linear_opt_3/common.py b/prolog/problems/clp_r/linear_opt_3/common.py
index 35f582d..f6e8840 100644
--- a/prolog/problems/clp_r/linear_opt_3/common.py
+++ b/prolog/problems/clp_r/linear_opt_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 159
-group = 'clp_r'
number = 63
visible = True
facts = None
diff --git a/prolog/problems/clp_r/linear_opt_3/en.py b/prolog/problems/clp_r/linear_opt_3/en.py
index 58530a9..848a30d 100644
--- a/prolog/problems/clp_r/linear_opt_3/en.py
+++ b/prolog/problems/clp_r/linear_opt_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 159
name = 'linear_opt/3'
slug = 'linear optimization'
diff --git a/prolog/problems/clp_r/max_sum_2/common.py b/prolog/problems/clp_r/max_sum_2/common.py
index 71c3005..d025090 100644
--- a/prolog/problems/clp_r/max_sum_2/common.py
+++ b/prolog/problems/clp_r/max_sum_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 156
-group = 'clp_r'
number = 66
visible = True
facts = None
diff --git a/prolog/problems/clp_r/max_sum_2/en.py b/prolog/problems/clp_r/max_sum_2/en.py
index 6d0c1d2..eeff4cd 100644
--- a/prolog/problems/clp_r/max_sum_2/en.py
+++ b/prolog/problems/clp_r/max_sum_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 156
name = 'max_sum/2'
slug = 'find maximal adjacent elements'
diff --git a/prolog/problems/clp_r/megabytes_2/common.py b/prolog/problems/clp_r/megabytes_2/common.py
index aefab2d..1f5bdd5 100644
--- a/prolog/problems/clp_r/megabytes_2/common.py
+++ b/prolog/problems/clp_r/megabytes_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 160
-group = 'clp_r'
number = 65
visible = True
facts = None
diff --git a/prolog/problems/clp_r/megabytes_2/en.py b/prolog/problems/clp_r/megabytes_2/en.py
index cb355f1..01fdfff 100644
--- a/prolog/problems/clp_r/megabytes_2/en.py
+++ b/prolog/problems/clp_r/megabytes_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 160
name = 'megabytes/2'
slug = 'convert mebibytes to megabytes'
diff --git a/prolog/problems/clp_r/turkey_3/common.py b/prolog/problems/clp_r/turkey_3/common.py
index 42f4119..b7bc7f4 100644
--- a/prolog/problems/clp_r/turkey_3/common.py
+++ b/prolog/problems/clp_r/turkey_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 161
-group = 'clp_r'
number = 64
visible = True
facts = None
diff --git a/prolog/problems/clp_r/turkey_3/en.py b/prolog/problems/clp_r/turkey_3/en.py
index b6e1d55..979033d 100644
--- a/prolog/problems/clp_r/turkey_3/en.py
+++ b/prolog/problems/clp_r/turkey_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 161
name = 'turkey/3'
slug = 'turkey feed'
diff --git a/prolog/problems/dcg/ab_2/common.py b/prolog/problems/dcg/ab_2/common.py
index f473a0b..b9109fc 100644
--- a/prolog/problems/dcg/ab_2/common.py
+++ b/prolog/problems/dcg/ab_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 162
-group = 'dcg'
number = 69
visible = True
facts = None
diff --git a/prolog/problems/dcg/ab_2/en.py b/prolog/problems/dcg/ab_2/en.py
index 20c8317..4dd81a5 100644
--- a/prolog/problems/dcg/ab_2/en.py
+++ b/prolog/problems/dcg/ab_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 162
name = 'ab/2'
slug = 'a*b*'
diff --git a/prolog/problems/dcg/common.py b/prolog/problems/dcg/common.py
new file mode 100644
index 0000000..4992f2d
--- /dev/null
+++ b/prolog/problems/dcg/common.py
@@ -0,0 +1,2 @@
+id = 10
+number = 9
diff --git a/prolog/problems/dcg/digit_2/common.py b/prolog/problems/dcg/digit_2/common.py
index 5b31e04..571df40 100644
--- a/prolog/problems/dcg/digit_2/common.py
+++ b/prolog/problems/dcg/digit_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 164
-group = 'dcg'
number = 71
visible = True
facts = None
diff --git a/prolog/problems/dcg/digit_2/en.py b/prolog/problems/dcg/digit_2/en.py
index 3172a21..80b7be0 100644
--- a/prolog/problems/dcg/digit_2/en.py
+++ b/prolog/problems/dcg/digit_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 164
name = 'digit/2'
slug = 'a decimal digit'
diff --git a/prolog/problems/dcg/expr_2/common.py b/prolog/problems/dcg/expr_2/common.py
index f5c4aa0..2420ebe 100644
--- a/prolog/problems/dcg/expr_2/common.py
+++ b/prolog/problems/dcg/expr_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 170
-group = 'dcg'
number = 77
visible = False
facts = None
diff --git a/prolog/problems/dcg/expr_2/en.py b/prolog/problems/dcg/expr_2/en.py
index d4b0dc9..88f1731 100644
--- a/prolog/problems/dcg/expr_2/en.py
+++ b/prolog/problems/dcg/expr_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 170
name = 'expr/2'
slug = 'arithmetic expressions'
diff --git a/prolog/problems/dcg/expr_3/common.py b/prolog/problems/dcg/expr_3/common.py
index 651a1b9..10220a8 100644
--- a/prolog/problems/dcg/expr_3/common.py
+++ b/prolog/problems/dcg/expr_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 171
-group = 'dcg'
number = 78
visible = False
facts = None
diff --git a/prolog/problems/dcg/expr_3/en.py b/prolog/problems/dcg/expr_3/en.py
index 659503d..298ebeb 100644
--- a/prolog/problems/dcg/expr_3/en.py
+++ b/prolog/problems/dcg/expr_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 171
name = 'expr/3'
slug = 'arithmetic expressions with meaning'
diff --git a/prolog/problems/dcg/flower_2/common.py b/prolog/problems/dcg/flower_2/common.py
index 5865da9..e28d10d 100644
--- a/prolog/problems/dcg/flower_2/common.py
+++ b/prolog/problems/dcg/flower_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 163
-group = 'dcg'
number = 70
visible = True
facts = None
diff --git a/prolog/problems/dcg/flower_2/en.py b/prolog/problems/dcg/flower_2/en.py
index 0267278..e7272c5 100644
--- a/prolog/problems/dcg/flower_2/en.py
+++ b/prolog/problems/dcg/flower_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 163
name = 'flower/2'
slug = 'words like +++--+++'
diff --git a/prolog/problems/dcg/number_2/common.py b/prolog/problems/dcg/number_2/common.py
index 6d33e12..a05ca18 100644
--- a/prolog/problems/dcg/number_2/common.py
+++ b/prolog/problems/dcg/number_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 165
-group = 'dcg'
number = 72
visible = True
facts = None
diff --git a/prolog/problems/dcg/number_2/en.py b/prolog/problems/dcg/number_2/en.py
index 8e88655..29a4366 100644
--- a/prolog/problems/dcg/number_2/en.py
+++ b/prolog/problems/dcg/number_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 165
name = 'number/2'
slug = 'numbers with potential leading zeros'
diff --git a/prolog/problems/dcg/number_3/common.py b/prolog/problems/dcg/number_3/common.py
index 0e6f2b0..2977392 100644
--- a/prolog/problems/dcg/number_3/common.py
+++ b/prolog/problems/dcg/number_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 167
-group = 'dcg'
number = 74
visible = True
facts = None
diff --git a/prolog/problems/dcg/number_3/en.py b/prolog/problems/dcg/number_3/en.py
index b73e16d..c2f9c3d 100644
--- a/prolog/problems/dcg/number_3/en.py
+++ b/prolog/problems/dcg/number_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 167
name = 'number/3'
slug = 'numbers with meaning'
diff --git a/prolog/problems/dcg/number_proper_2/common.py b/prolog/problems/dcg/number_proper_2/common.py
index c6b535b..a3e3592 100644
--- a/prolog/problems/dcg/number_proper_2/common.py
+++ b/prolog/problems/dcg/number_proper_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 166
-group = 'dcg'
number = 73
visible = True
facts = None
diff --git a/prolog/problems/dcg/number_proper_2/en.py b/prolog/problems/dcg/number_proper_2/en.py
index 81ca5f6..8580ab7 100644
--- a/prolog/problems/dcg/number_proper_2/en.py
+++ b/prolog/problems/dcg/number_proper_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 166
name = 'number_proper/2'
slug = 'numbers without leading zeros'
diff --git a/prolog/problems/dcg/paren_2/common.py b/prolog/problems/dcg/paren_2/common.py
index d5969a2..1d8f653 100644
--- a/prolog/problems/dcg/paren_2/common.py
+++ b/prolog/problems/dcg/paren_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 168
-group = 'dcg'
number = 75
visible = True
facts = None
diff --git a/prolog/problems/dcg/paren_2/en.py b/prolog/problems/dcg/paren_2/en.py
index 268b774..3041a67 100644
--- a/prolog/problems/dcg/paren_2/en.py
+++ b/prolog/problems/dcg/paren_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 168
name = 'paren/2'
slug = 'properly nested parens'
diff --git a/prolog/problems/dcg/paren_3/common.py b/prolog/problems/dcg/paren_3/common.py
index 4cda182..a905149 100644
--- a/prolog/problems/dcg/paren_3/common.py
+++ b/prolog/problems/dcg/paren_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 169
-group = 'dcg'
number = 76
visible = True
facts = None
diff --git a/prolog/problems/dcg/paren_3/en.py b/prolog/problems/dcg/paren_3/en.py
index 737f0ef..56519ff 100644
--- a/prolog/problems/dcg/paren_3/en.py
+++ b/prolog/problems/dcg/paren_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 169
name = 'paren/3'
slug = 'properly nested parens with meaning'
diff --git a/prolog/problems/denotational_semantics/algol_3/common.py b/prolog/problems/denotational_semantics/algol_3/common.py
index 1f5b196..cce9b69 100644
--- a/prolog/problems/denotational_semantics/algol_3/common.py
+++ b/prolog/problems/denotational_semantics/algol_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 176
-group = 'denotational_semantics'
number = 83
visible = True
facts = None
diff --git a/prolog/problems/denotational_semantics/algol_3/en.py b/prolog/problems/denotational_semantics/algol_3/en.py
index 5c79c41..c5da13e 100644
--- a/prolog/problems/denotational_semantics/algol_3/en.py
+++ b/prolog/problems/denotational_semantics/algol_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 176
name = 'algol/3'
slug = 'interpreter for mini-algol'
diff --git a/prolog/problems/denotational_semantics/algol_for_3/common.py b/prolog/problems/denotational_semantics/algol_for_3/common.py
index bc0c3e8..4cf9373 100644
--- a/prolog/problems/denotational_semantics/algol_for_3/common.py
+++ b/prolog/problems/denotational_semantics/algol_for_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 178
-group = 'denotational_semantics'
number = 85
visible = True
facts = None
diff --git a/prolog/problems/denotational_semantics/algol_for_3/en.py b/prolog/problems/denotational_semantics/algol_for_3/en.py
index 53e5e2b..d4b8144 100644
--- a/prolog/problems/denotational_semantics/algol_for_3/en.py
+++ b/prolog/problems/denotational_semantics/algol_for_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 178
name = 'algol_for/3'
slug = 'interpreter for mini-algol with for-statement'
diff --git a/prolog/problems/denotational_semantics/algol_if_3/common.py b/prolog/problems/denotational_semantics/algol_if_3/common.py
index fd750e0..0c52886 100644
--- a/prolog/problems/denotational_semantics/algol_if_3/common.py
+++ b/prolog/problems/denotational_semantics/algol_if_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 177
-group = 'denotational_semantics'
number = 84
visible = True
facts = None
diff --git a/prolog/problems/denotational_semantics/algol_if_3/en.py b/prolog/problems/denotational_semantics/algol_if_3/en.py
index f4ae00a..fae6c45 100644
--- a/prolog/problems/denotational_semantics/algol_if_3/en.py
+++ b/prolog/problems/denotational_semantics/algol_if_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 177
name = 'algol_if/3'
slug = 'interpreter for mini-algol with if-statement'
diff --git a/prolog/problems/denotational_semantics/common.py b/prolog/problems/denotational_semantics/common.py
new file mode 100644
index 0000000..e2c420e
--- /dev/null
+++ b/prolog/problems/denotational_semantics/common.py
@@ -0,0 +1,2 @@
+id = 11
+number = 10
diff --git a/prolog/problems/denotational_semantics/prog_8puzzle_2/common.py b/prolog/problems/denotational_semantics/prog_8puzzle_2/common.py
index e48d03f..d994039 100644
--- a/prolog/problems/denotational_semantics/prog_8puzzle_2/common.py
+++ b/prolog/problems/denotational_semantics/prog_8puzzle_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 172
-group = 'denotational_semantics'
number = 81
visible = True
facts = None
diff --git a/prolog/problems/denotational_semantics/prog_8puzzle_2/en.py b/prolog/problems/denotational_semantics/prog_8puzzle_2/en.py
index d43a837..fc49742 100644
--- a/prolog/problems/denotational_semantics/prog_8puzzle_2/en.py
+++ b/prolog/problems/denotational_semantics/prog_8puzzle_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 172
name = 'prog_8puzzle/2'
slug = '8-puzzle-solving language'
diff --git a/prolog/problems/denotational_semantics/prog_8puzzle_3/common.py b/prolog/problems/denotational_semantics/prog_8puzzle_3/common.py
index f86a0c4..15dce6b 100644
--- a/prolog/problems/denotational_semantics/prog_8puzzle_3/common.py
+++ b/prolog/problems/denotational_semantics/prog_8puzzle_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 173
-group = 'denotational_semantics'
number = 82
visible = True
facts = 'denotational_semantics_aux__predicates'
diff --git a/prolog/problems/denotational_semantics/prog_8puzzle_3/en.py b/prolog/problems/denotational_semantics/prog_8puzzle_3/en.py
index 346d579..1c23b18 100644
--- a/prolog/problems/denotational_semantics/prog_8puzzle_3/en.py
+++ b/prolog/problems/denotational_semantics/prog_8puzzle_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 173
name = 'prog_8puzzle/3'
slug = '8-puzzle-solving language with semantics'
diff --git a/prolog/problems/denotational_semantics/prog_listswap_2/common.py b/prolog/problems/denotational_semantics/prog_listswap_2/common.py
index 9a7c586..1f8b655 100644
--- a/prolog/problems/denotational_semantics/prog_listswap_2/common.py
+++ b/prolog/problems/denotational_semantics/prog_listswap_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 175
-group = 'denotational_semantics'
number = 79
visible = True
facts = None
diff --git a/prolog/problems/denotational_semantics/prog_listswap_2/en.py b/prolog/problems/denotational_semantics/prog_listswap_2/en.py
index 2cf8fff..0f8e038 100644
--- a/prolog/problems/denotational_semantics/prog_listswap_2/en.py
+++ b/prolog/problems/denotational_semantics/prog_listswap_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 175
name = 'prog_listswap/2'
slug = 'list-manipulation language'
diff --git a/prolog/problems/denotational_semantics/prog_listswap_3/common.py b/prolog/problems/denotational_semantics/prog_listswap_3/common.py
index 2b32618..a40be29 100644
--- a/prolog/problems/denotational_semantics/prog_listswap_3/common.py
+++ b/prolog/problems/denotational_semantics/prog_listswap_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 174
-group = 'denotational_semantics'
number = 80
visible = True
facts = 'denotational_semantics_aux__predicates'
diff --git a/prolog/problems/denotational_semantics/prog_listswap_3/en.py b/prolog/problems/denotational_semantics/prog_listswap_3/en.py
index 88a927a..5e85ce6 100644
--- a/prolog/problems/denotational_semantics/prog_listswap_3/en.py
+++ b/prolog/problems/denotational_semantics/prog_listswap_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 174
name = 'prog_listswap/3'
slug = 'list-manipulation language with semantics'
diff --git a/prolog/problems/family_relations/ancestor_2/common.py b/prolog/problems/family_relations/ancestor_2/common.py
index 3226f34..7249ed8 100644
--- a/prolog/problems/family_relations/ancestor_2/common.py
+++ b/prolog/problems/family_relations/ancestor_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 100
-group = 'family_relations'
number = 7
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/ancestor_2/en.py b/prolog/problems/family_relations/ancestor_2/en.py
index b390705..29fb253 100644
--- a/prolog/problems/family_relations/ancestor_2/en.py
+++ b/prolog/problems/family_relations/ancestor_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 100
name = 'ancestor/2'
slug = 'the ancestor relation'
diff --git a/prolog/problems/family_relations/ancestor_2/sl.py b/prolog/problems/family_relations/ancestor_2/sl.py
index 76c2bea..d74ccc5 100644
--- a/prolog/problems/family_relations/ancestor_2/sl.py
+++ b/prolog/problems/family_relations/ancestor_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 100
name = 'ancestor/2'
slug = 'X je prednik od Y'
diff --git a/prolog/problems/family_relations/aunt_2/common.py b/prolog/problems/family_relations/aunt_2/common.py
index 2aeba9d..51bc99a 100644
--- a/prolog/problems/family_relations/aunt_2/common.py
+++ b/prolog/problems/family_relations/aunt_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 98
-group = 'family_relations'
number = 5
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/aunt_2/en.py b/prolog/problems/family_relations/aunt_2/en.py
index 8d20d7e..25cac41 100644
--- a/prolog/problems/family_relations/aunt_2/en.py
+++ b/prolog/problems/family_relations/aunt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 98
name = 'aunt/2'
slug = 'the aunt relation'
diff --git a/prolog/problems/family_relations/aunt_2/sl.py b/prolog/problems/family_relations/aunt_2/sl.py
index 95fc6b2..2bf0ef6 100644
--- a/prolog/problems/family_relations/aunt_2/sl.py
+++ b/prolog/problems/family_relations/aunt_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 98
name = 'aunt/2'
slug = 'X je teta od Y'
diff --git a/prolog/problems/family_relations/brother_2/common.py b/prolog/problems/family_relations/brother_2/common.py
index 3fb685f..48b89fe 100644
--- a/prolog/problems/family_relations/brother_2/common.py
+++ b/prolog/problems/family_relations/brother_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 97
-group = 'family_relations'
number = 4
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/brother_2/en.py b/prolog/problems/family_relations/brother_2/en.py
index 709b077..2daf78f 100644
--- a/prolog/problems/family_relations/brother_2/en.py
+++ b/prolog/problems/family_relations/brother_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 97
name = 'brother/2'
slug = 'the brother relation'
diff --git a/prolog/problems/family_relations/brother_2/sl.py b/prolog/problems/family_relations/brother_2/sl.py
index f945026..96c6126 100644
--- a/prolog/problems/family_relations/brother_2/sl.py
+++ b/prolog/problems/family_relations/brother_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 97
name = 'brother/2'
slug = 'X je brat od Y'
diff --git a/prolog/problems/family_relations/common.py b/prolog/problems/family_relations/common.py
new file mode 100644
index 0000000..5aff819
--- /dev/null
+++ b/prolog/problems/family_relations/common.py
@@ -0,0 +1,2 @@
+id = 1
+number = 1
diff --git a/prolog/problems/family_relations/connected_3/common.py b/prolog/problems/family_relations/connected_3/common.py
index 1221713..9c0bef7 100644
--- a/prolog/problems/family_relations/connected_3/common.py
+++ b/prolog/problems/family_relations/connected_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 102
-group = 'family_relations'
number = 9
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/connected_3/en.py b/prolog/problems/family_relations/connected_3/en.py
index 5fe8edb..f50d60e 100644
--- a/prolog/problems/family_relations/connected_3/en.py
+++ b/prolog/problems/family_relations/connected_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 102
name = 'connected/3'
slug = 'check if two people are connected in the family tree'
diff --git a/prolog/problems/family_relations/cousin_2/common.py b/prolog/problems/family_relations/cousin_2/common.py
index cd5cd38..8dc33b8 100644
--- a/prolog/problems/family_relations/cousin_2/common.py
+++ b/prolog/problems/family_relations/cousin_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 99
-group = 'family_relations'
number = 6
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/cousin_2/en.py b/prolog/problems/family_relations/cousin_2/en.py
index 1399013..cf628db 100644
--- a/prolog/problems/family_relations/cousin_2/en.py
+++ b/prolog/problems/family_relations/cousin_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 99
name = 'cousin/2'
slug = 'the cousin relation'
diff --git a/prolog/problems/family_relations/cousin_2/sl.py b/prolog/problems/family_relations/cousin_2/sl.py
index ebecf8d..7e3e7f0 100644
--- a/prolog/problems/family_relations/cousin_2/sl.py
+++ b/prolog/problems/family_relations/cousin_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 99
name = 'cousin/2'
slug = 'X je bratranec ali sestrična od Y'
diff --git a/prolog/problems/family_relations/descendant_2/common.py b/prolog/problems/family_relations/descendant_2/common.py
index 21de450..cfa1d37 100644
--- a/prolog/problems/family_relations/descendant_2/common.py
+++ b/prolog/problems/family_relations/descendant_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 101
-group = 'family_relations'
number = 8
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/descendant_2/en.py b/prolog/problems/family_relations/descendant_2/en.py
index b0fccf2..74360f3 100644
--- a/prolog/problems/family_relations/descendant_2/en.py
+++ b/prolog/problems/family_relations/descendant_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 101
name = 'descendant/2'
slug = 'the descendant relation'
diff --git a/prolog/problems/family_relations/descendant_2/sl.py b/prolog/problems/family_relations/descendant_2/sl.py
index fb60e76..5e81d26 100644
--- a/prolog/problems/family_relations/descendant_2/sl.py
+++ b/prolog/problems/family_relations/descendant_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 101
name = 'descendant/2'
slug = 'the descendant relation'
diff --git a/prolog/problems/family_relations/father_2/common.py b/prolog/problems/family_relations/father_2/common.py
index 50ac701..8eef44a 100644
--- a/prolog/problems/family_relations/father_2/common.py
+++ b/prolog/problems/family_relations/father_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 181
-group = 'family_relations'
number = 2
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/father_2/en.py b/prolog/problems/family_relations/father_2/en.py
index 59857a8..722c016 100644
--- a/prolog/problems/family_relations/father_2/en.py
+++ b/prolog/problems/family_relations/father_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 181
name = 'mother/2'
slug = 'the mother-child relation'
diff --git a/prolog/problems/family_relations/father_2/sl.py b/prolog/problems/family_relations/father_2/sl.py
index 67bf764..178fbc6 100644
--- a/prolog/problems/family_relations/father_2/sl.py
+++ b/prolog/problems/family_relations/father_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 181
name = 'father/2'
slug = 'X je oče od Y'
diff --git a/prolog/problems/family_relations/grandparent_2/common.py b/prolog/problems/family_relations/grandparent_2/common.py
index fec7734..ee7b25b 100644
--- a/prolog/problems/family_relations/grandparent_2/common.py
+++ b/prolog/problems/family_relations/grandparent_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence, HintPopup
import server.problems
id = 95
-group = 'family_relations'
number = 30
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/grandparent_2/en.py b/prolog/problems/family_relations/grandparent_2/en.py
index 6fdeb70..c181ab5 100644
--- a/prolog/problems/family_relations/grandparent_2/en.py
+++ b/prolog/problems/family_relations/grandparent_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 95
name = 'grandparent/2'
slug = 'the grandparent relation'
diff --git a/prolog/problems/family_relations/grandparent_2/sl.py b/prolog/problems/family_relations/grandparent_2/sl.py
index 35ff49e..a4440a6 100644
--- a/prolog/problems/family_relations/grandparent_2/sl.py
+++ b/prolog/problems/family_relations/grandparent_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 95
name = 'grandparent/2'
slug = 'X je dedek ali babica od Y'
diff --git a/prolog/problems/family_relations/mother_2/common.py b/prolog/problems/family_relations/mother_2/common.py
index 18b3027..e3a883f 100644
--- a/prolog/problems/family_relations/mother_2/common.py
+++ b/prolog/problems/family_relations/mother_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 94
-group = 'family_relations'
number = 1
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/mother_2/en.py b/prolog/problems/family_relations/mother_2/en.py
index 108bb9b..722c016 100644
--- a/prolog/problems/family_relations/mother_2/en.py
+++ b/prolog/problems/family_relations/mother_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 94
name = 'mother/2'
slug = 'the mother-child relation'
diff --git a/prolog/problems/family_relations/mother_2/sl.py b/prolog/problems/family_relations/mother_2/sl.py
index 9e384c0..b37c20c 100644
--- a/prolog/problems/family_relations/mother_2/sl.py
+++ b/prolog/problems/family_relations/mother_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 94
name = 'mother/2'
slug = 'X je mama od Y'
diff --git a/prolog/problems/family_relations/sister_2/common.py b/prolog/problems/family_relations/sister_2/common.py
index b2bf954..627648c 100644
--- a/prolog/problems/family_relations/sister_2/common.py
+++ b/prolog/problems/family_relations/sister_2/common.py
@@ -8,7 +8,6 @@ from server.hints import Hint, HintSequence
import server.problems
id = 96
-group = 'family_relations'
number = 3
visible = True
facts = 'family_relations'
diff --git a/prolog/problems/family_relations/sister_2/en.py b/prolog/problems/family_relations/sister_2/en.py
index 6b055e8..32bb9d9 100644
--- a/prolog/problems/family_relations/sister_2/en.py
+++ b/prolog/problems/family_relations/sister_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 96
name = 'sister/2'
slug = 'the sister relation'
diff --git a/prolog/problems/family_relations/sister_2/sl.py b/prolog/problems/family_relations/sister_2/sl.py
index 1cb457d..d69b56c 100644
--- a/prolog/problems/family_relations/sister_2/sl.py
+++ b/prolog/problems/family_relations/sister_2/sl.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 96
name = 'sister/2'
slug = 'X je sestra od Y'
diff --git a/prolog/problems/license_plates/checklicenseplate_3/common.py b/prolog/problems/license_plates/checklicenseplate_3/common.py
index 5dc1c3c..c37e210 100644
--- a/prolog/problems/license_plates/checklicenseplate_3/common.py
+++ b/prolog/problems/license_plates/checklicenseplate_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 148
-group = 'license_plates'
number = 55
visible = True
facts = None
diff --git a/prolog/problems/license_plates/checklicenseplate_3/en.py b/prolog/problems/license_plates/checklicenseplate_3/en.py
index 4e3e726..76270cd 100644
--- a/prolog/problems/license_plates/checklicenseplate_3/en.py
+++ b/prolog/problems/license_plates/checklicenseplate_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 148
name = 'checkLicensePlate/3'
slug = 'check if the numbers in a license plate form an equation'
diff --git a/prolog/problems/license_plates/common.py b/prolog/problems/license_plates/common.py
new file mode 100644
index 0000000..3d15487
--- /dev/null
+++ b/prolog/problems/license_plates/common.py
@@ -0,0 +1,2 @@
+id = 7
+number = 6
diff --git a/prolog/problems/license_plates/firstminus_2/common.py b/prolog/problems/license_plates/firstminus_2/common.py
index ece4dd6..20376d2 100644
--- a/prolog/problems/license_plates/firstminus_2/common.py
+++ b/prolog/problems/license_plates/firstminus_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 147
-group = 'license_plates'
number = 54
visible = True
facts = None
diff --git a/prolog/problems/license_plates/firstminus_2/en.py b/prolog/problems/license_plates/firstminus_2/en.py
index 00bb198..cea521a 100644
--- a/prolog/problems/license_plates/firstminus_2/en.py
+++ b/prolog/problems/license_plates/firstminus_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 147
name = 'firstMinus/2'
slug = 'negate the first element in a list of numbers'
diff --git a/prolog/problems/license_plates/genexp_2/common.py b/prolog/problems/license_plates/genexp_2/common.py
index 170722b..ecdc772 100644
--- a/prolog/problems/license_plates/genexp_2/common.py
+++ b/prolog/problems/license_plates/genexp_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 146
-group = 'license_plates'
number = 53
visible = True
facts = None
diff --git a/prolog/problems/license_plates/genexp_2/en.py b/prolog/problems/license_plates/genexp_2/en.py
index de168ec..2238f4d 100644
--- a/prolog/problems/license_plates/genexp_2/en.py
+++ b/prolog/problems/license_plates/genexp_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 146
name = 'genexp/2'
slug = 'generate an arithmetic expression from a list'
diff --git a/prolog/problems/license_plates/getdigits_2/common.py b/prolog/problems/license_plates/getdigits_2/common.py
index 20be22e..82fe033 100644
--- a/prolog/problems/license_plates/getdigits_2/common.py
+++ b/prolog/problems/license_plates/getdigits_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 144
-group = 'license_plates'
number = 51
visible = True
facts = None
diff --git a/prolog/problems/license_plates/getdigits_2/en.py b/prolog/problems/license_plates/getdigits_2/en.py
index 6da7033..afc41d4 100644
--- a/prolog/problems/license_plates/getdigits_2/en.py
+++ b/prolog/problems/license_plates/getdigits_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 144
name = 'getdigits/2'
slug = 'remove non-numeric elements from a list'
diff --git a/prolog/problems/license_plates/joindigits_2/common.py b/prolog/problems/license_plates/joindigits_2/common.py
index b89559f..9ebc037 100644
--- a/prolog/problems/license_plates/joindigits_2/common.py
+++ b/prolog/problems/license_plates/joindigits_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 145
-group = 'license_plates'
number = 52
visible = True
facts = None
diff --git a/prolog/problems/license_plates/joindigits_2/en.py b/prolog/problems/license_plates/joindigits_2/en.py
index 3a5ff41..c51f452 100644
--- a/prolog/problems/license_plates/joindigits_2/en.py
+++ b/prolog/problems/license_plates/joindigits_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 145
name = 'joindigits/2'
slug = 'join adjacent numbers in a list'
diff --git a/prolog/problems/lists/common.py b/prolog/problems/lists/common.py
new file mode 100644
index 0000000..4788fc4
--- /dev/null
+++ b/prolog/problems/lists/common.py
@@ -0,0 +1,2 @@
+id = 2
+number = 2
diff --git a/prolog/problems/lists/conc_3/common.py b/prolog/problems/lists/conc_3/common.py
index ef23d67..e83c454 100644
--- a/prolog/problems/lists/conc_3/common.py
+++ b/prolog/problems/lists/conc_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 104
-group = 'lists'
number = 12
visible = True
facts = None
diff --git a/prolog/problems/lists/conc_3/en.py b/prolog/problems/lists/conc_3/en.py
index 184ca44..7399f7e 100644
--- a/prolog/problems/lists/conc_3/en.py
+++ b/prolog/problems/lists/conc_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 104
name = 'conc/3'
slug = 'concatenate two lists'
diff --git a/prolog/problems/lists/count_3/common.py b/prolog/problems/lists/count_3/common.py
index bf6f688..8a85079 100644
--- a/prolog/problems/lists/count_3/common.py
+++ b/prolog/problems/lists/count_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 120
-group = 'lists'
number = 27
visible = True
facts = None
diff --git a/prolog/problems/lists/count_3/en.py b/prolog/problems/lists/count_3/en.py
index 9115940..c676dea 100644
--- a/prolog/problems/lists/count_3/en.py
+++ b/prolog/problems/lists/count_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 120
name = 'count/3'
slug = 'find the number of occurrences of an element in list'
diff --git a/prolog/problems/lists/del_3/common.py b/prolog/problems/lists/del_3/common.py
index 81bbb75..755193c 100644
--- a/prolog/problems/lists/del_3/common.py
+++ b/prolog/problems/lists/del_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 105
-group = 'lists'
number = 11
visible = True
facts = None
diff --git a/prolog/problems/lists/del_3/en.py b/prolog/problems/lists/del_3/en.py
index 1e58ae5..d7e38e8 100644
--- a/prolog/problems/lists/del_3/en.py
+++ b/prolog/problems/lists/del_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 105
name = 'del/3'
slug = 'delete an element from list'
diff --git a/prolog/problems/lists/divide_3/common.py b/prolog/problems/lists/divide_3/common.py
index 337f702..c5744cc 100644
--- a/prolog/problems/lists/divide_3/common.py
+++ b/prolog/problems/lists/divide_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 115
-group = 'lists'
number = 22
visible = True
facts = None
diff --git a/prolog/problems/lists/divide_3/en.py b/prolog/problems/lists/divide_3/en.py
index 657b013..fded262 100644
--- a/prolog/problems/lists/divide_3/en.py
+++ b/prolog/problems/lists/divide_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 115
name = 'divide/3'
slug = 'split a list into parts of roughly equal length'
diff --git a/prolog/problems/lists/dup_2/common.py b/prolog/problems/lists/dup_2/common.py
index 7417006..e0a1001 100644
--- a/prolog/problems/lists/dup_2/common.py
+++ b/prolog/problems/lists/dup_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 110
-group = 'lists'
number = 17
visible = True
facts = None
diff --git a/prolog/problems/lists/dup_2/en.py b/prolog/problems/lists/dup_2/en.py
index f6354b3..c1d0c1a 100644
--- a/prolog/problems/lists/dup_2/en.py
+++ b/prolog/problems/lists/dup_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 110
name = 'dup/2'
slug = 'duplicate the elements of a list'
diff --git a/prolog/problems/lists/evenlen_1_+_oddlen_1/common.py b/prolog/problems/lists/evenlen_1_+_oddlen_1/common.py
index aaca8ec..601cd33 100644
--- a/prolog/problems/lists/evenlen_1_+_oddlen_1/common.py
+++ b/prolog/problems/lists/evenlen_1_+_oddlen_1/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 116
-group = 'lists'
number = 23
visible = True
facts = None
diff --git a/prolog/problems/lists/evenlen_1_+_oddlen_1/en.py b/prolog/problems/lists/evenlen_1_+_oddlen_1/en.py
index 741c36a..1ac7990 100644
--- a/prolog/problems/lists/evenlen_1_+_oddlen_1/en.py
+++ b/prolog/problems/lists/evenlen_1_+_oddlen_1/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 116
name = 'evenlen/1 + oddlen/1'
slug = 'check if the length of a list is even or odd'
diff --git a/prolog/problems/lists/insert_3/common.py b/prolog/problems/lists/insert_3/common.py
index df4e16e..4892f4d 100644
--- a/prolog/problems/lists/insert_3/common.py
+++ b/prolog/problems/lists/insert_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 106
-group = 'lists'
number = 13
visible = True
facts = None
diff --git a/prolog/problems/lists/insert_3/en.py b/prolog/problems/lists/insert_3/en.py
index 01a7d0a..6a3da54 100644
--- a/prolog/problems/lists/insert_3/en.py
+++ b/prolog/problems/lists/insert_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 106
name = 'insert/3'
slug = 'insert an element into list'
diff --git a/prolog/problems/lists/len_2/common.py b/prolog/problems/lists/len_2/common.py
index 33fc223..7dbdc62 100644
--- a/prolog/problems/lists/len_2/common.py
+++ b/prolog/problems/lists/len_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 119
-group = 'lists'
number = 26
visible = True
facts = None
diff --git a/prolog/problems/lists/len_2/en.py b/prolog/problems/lists/len_2/en.py
index 325e28f..9de0060 100644
--- a/prolog/problems/lists/len_2/en.py
+++ b/prolog/problems/lists/len_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 119
name = 'len/2'
slug = 'find the length of a list'
diff --git a/prolog/problems/lists/max_2/common.py b/prolog/problems/lists/max_2/common.py
index 73c39a2..0e8f031 100644
--- a/prolog/problems/lists/max_2/common.py
+++ b/prolog/problems/lists/max_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 109
-group = 'lists'
number = 16
visible = True
facts = None
diff --git a/prolog/problems/lists/max_2/en.py b/prolog/problems/lists/max_2/en.py
index 1f6aba7..f851cd9 100644
--- a/prolog/problems/lists/max_2/en.py
+++ b/prolog/problems/lists/max_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 109
name = 'max/2'
slug = 'find the largest element in list'
diff --git a/prolog/problems/lists/memb_2/common.py b/prolog/problems/lists/memb_2/common.py
index 9e8b58e..3acbc15 100644
--- a/prolog/problems/lists/memb_2/common.py
+++ b/prolog/problems/lists/memb_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 103
-group = 'lists'
number = 10
visible = True
facts = None
diff --git a/prolog/problems/lists/memb_2/en.py b/prolog/problems/lists/memb_2/en.py
index 9b3c4d9..3fb20d3 100644
--- a/prolog/problems/lists/memb_2/en.py
+++ b/prolog/problems/lists/memb_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 103
name = 'memb/2'
slug = 'find elements in list'
diff --git a/prolog/problems/lists/min_2/common.py b/prolog/problems/lists/min_2/common.py
index a5421d1..cc6ad9e 100644
--- a/prolog/problems/lists/min_2/common.py
+++ b/prolog/problems/lists/min_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 108
-group = 'lists'
number = 15
visible = True
facts = None
diff --git a/prolog/problems/lists/min_2/en.py b/prolog/problems/lists/min_2/en.py
index 0e5a907..2432be2 100644
--- a/prolog/problems/lists/min_2/en.py
+++ b/prolog/problems/lists/min_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 108
name = 'min/2'
slug = 'find the smallest element'
diff --git a/prolog/problems/lists/palindrome_1/common.py b/prolog/problems/lists/palindrome_1/common.py
index 31998e2..5df4b87 100644
--- a/prolog/problems/lists/palindrome_1/common.py
+++ b/prolog/problems/lists/palindrome_1/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 112
-group = 'lists'
number = 19
visible = True
facts = None
diff --git a/prolog/problems/lists/palindrome_1/en.py b/prolog/problems/lists/palindrome_1/en.py
index 3e5f561..7f30f8e 100644
--- a/prolog/problems/lists/palindrome_1/en.py
+++ b/prolog/problems/lists/palindrome_1/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 112
name = 'palindrome/1'
slug = 'check if list is a palindrome'
diff --git a/prolog/problems/lists/permute_2/common.py b/prolog/problems/lists/permute_2/common.py
index a1c66ff..2f37a3b 100644
--- a/prolog/problems/lists/permute_2/common.py
+++ b/prolog/problems/lists/permute_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 107
-group = 'lists'
number = 14
visible = True
facts = None
diff --git a/prolog/problems/lists/permute_2/en.py b/prolog/problems/lists/permute_2/en.py
index 048713e..29d287f 100644
--- a/prolog/problems/lists/permute_2/en.py
+++ b/prolog/problems/lists/permute_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 107
name = 'permute/2'
slug = 'generate permutations of a list'
diff --git a/prolog/problems/lists/rev_2/common.py b/prolog/problems/lists/rev_2/common.py
index c31e25b..ba72492 100644
--- a/prolog/problems/lists/rev_2/common.py
+++ b/prolog/problems/lists/rev_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 111
-group = 'lists'
number = 18
visible = True
facts = None
diff --git a/prolog/problems/lists/rev_2/en.py b/prolog/problems/lists/rev_2/en.py
index c4800b6..fe36ec5 100644
--- a/prolog/problems/lists/rev_2/en.py
+++ b/prolog/problems/lists/rev_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 111
name = 'rev/2'
slug = 'reverse a list'
diff --git a/prolog/problems/lists/shiftleft_2/common.py b/prolog/problems/lists/shiftleft_2/common.py
index f8e09f2..9a2fe0e 100644
--- a/prolog/problems/lists/shiftleft_2/common.py
+++ b/prolog/problems/lists/shiftleft_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 113
-group = 'lists'
number = 20
visible = True
facts = None
diff --git a/prolog/problems/lists/shiftleft_2/en.py b/prolog/problems/lists/shiftleft_2/en.py
index 72d55e5..a99b4a7 100644
--- a/prolog/problems/lists/shiftleft_2/en.py
+++ b/prolog/problems/lists/shiftleft_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 113
name = 'shiftleft/2'
slug = 'shift a list left'
diff --git a/prolog/problems/lists/shiftright_2/common.py b/prolog/problems/lists/shiftright_2/common.py
index e443332..5358935 100644
--- a/prolog/problems/lists/shiftright_2/common.py
+++ b/prolog/problems/lists/shiftright_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 114
-group = 'lists'
number = 21
visible = True
facts = None
diff --git a/prolog/problems/lists/shiftright_2/en.py b/prolog/problems/lists/shiftright_2/en.py
index 3f20565..13384b0 100644
--- a/prolog/problems/lists/shiftright_2/en.py
+++ b/prolog/problems/lists/shiftright_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 114
name = 'shiftright/2'
slug = 'shift a list right'
diff --git a/prolog/problems/lists/sublist_2/common.py b/prolog/problems/lists/sublist_2/common.py
index f9cef37..694bfcf 100644
--- a/prolog/problems/lists/sublist_2/common.py
+++ b/prolog/problems/lists/sublist_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 117
-group = 'lists'
number = 24
visible = True
facts = None
diff --git a/prolog/problems/lists/sublist_2/en.py b/prolog/problems/lists/sublist_2/en.py
index e17270b..e761e19 100644
--- a/prolog/problems/lists/sublist_2/en.py
+++ b/prolog/problems/lists/sublist_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 117
name = 'sublist/2'
slug = 'generate sublists of a list'
diff --git a/prolog/problems/lists/sum_2/common.py b/prolog/problems/lists/sum_2/common.py
index 106f310..9c17e9c 100644
--- a/prolog/problems/lists/sum_2/common.py
+++ b/prolog/problems/lists/sum_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 118
-group = 'lists'
number = 25
visible = True
facts = None
diff --git a/prolog/problems/lists/sum_2/en.py b/prolog/problems/lists/sum_2/en.py
index fb47a1f..fc4cea8 100644
--- a/prolog/problems/lists/sum_2/en.py
+++ b/prolog/problems/lists/sum_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 118
name = 'sum/2'
slug = 'find the sum of all elements in list'
diff --git a/prolog/problems/old_exams/common.py b/prolog/problems/old_exams/common.py
new file mode 100644
index 0000000..56857ba
--- /dev/null
+++ b/prolog/problems/old_exams/common.py
@@ -0,0 +1 @@
+id = 12
diff --git a/prolog/problems/old_exams/pascal_3/common.py b/prolog/problems/old_exams/pascal_3/common.py
index ebbc114..ddb3c6c 100644
--- a/prolog/problems/old_exams/pascal_3/common.py
+++ b/prolog/problems/old_exams/pascal_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 179
-group = 'old_exams'
number = 86
visible = False
facts = None
diff --git a/prolog/problems/old_exams/pascal_3/en.py b/prolog/problems/old_exams/pascal_3/en.py
index 0506004..bd17577 100644
--- a/prolog/problems/old_exams/pascal_3/en.py
+++ b/prolog/problems/old_exams/pascal_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 179
name = 'pascal/3'
slug = 'pascal's triangle'
diff --git a/prolog/problems/other/common.py b/prolog/problems/other/common.py
new file mode 100644
index 0000000..50384ad
--- /dev/null
+++ b/prolog/problems/other/common.py
@@ -0,0 +1 @@
+id = 4
diff --git a/prolog/problems/other/genlist_4/common.py b/prolog/problems/other/genlist_4/common.py
index 83f4b0e..3d8f326 100644
--- a/prolog/problems/other/genlist_4/common.py
+++ b/prolog/problems/other/genlist_4/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 127
-group = 'other'
number = 34
visible = False
facts = None
diff --git a/prolog/problems/other/genlist_4/en.py b/prolog/problems/other/genlist_4/en.py
index 51ef8ea..bcdcefa 100644
--- a/prolog/problems/other/genlist_4/en.py
+++ b/prolog/problems/other/genlist_4/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 127
name = 'genlist/4'
slug = 'generate a list of random numbers'
diff --git a/prolog/problems/sets/common.py b/prolog/problems/sets/common.py
new file mode 100644
index 0000000..104aa9d
--- /dev/null
+++ b/prolog/problems/sets/common.py
@@ -0,0 +1,2 @@
+id = 5
+number = 4
diff --git a/prolog/problems/sets/diff_3/common.py b/prolog/problems/sets/diff_3/common.py
index 82a6fe9..fee93b2 100644
--- a/prolog/problems/sets/diff_3/common.py
+++ b/prolog/problems/sets/diff_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 130
-group = 'sets'
number = 37
visible = True
facts = None
diff --git a/prolog/problems/sets/diff_3/en.py b/prolog/problems/sets/diff_3/en.py
index 7ce6944..47def00 100644
--- a/prolog/problems/sets/diff_3/en.py
+++ b/prolog/problems/sets/diff_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 130
name = 'diff/3'
slug = 'find the difference of two sets'
diff --git a/prolog/problems/sets/intersect_3/common.py b/prolog/problems/sets/intersect_3/common.py
index b2250e6..501cdf3 100644
--- a/prolog/problems/sets/intersect_3/common.py
+++ b/prolog/problems/sets/intersect_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 129
-group = 'sets'
number = 36
visible = True
facts = None
diff --git a/prolog/problems/sets/intersect_3/en.py b/prolog/problems/sets/intersect_3/en.py
index def0ab5..fed5e34 100644
--- a/prolog/problems/sets/intersect_3/en.py
+++ b/prolog/problems/sets/intersect_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 129
name = 'intersect/3'
slug = 'find the intersection of two sets'
diff --git a/prolog/problems/sets/is_subset_2/common.py b/prolog/problems/sets/is_subset_2/common.py
index 330ca21..4047146 100644
--- a/prolog/problems/sets/is_subset_2/common.py
+++ b/prolog/problems/sets/is_subset_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 132
-group = 'sets'
number = 39
visible = True
facts = None
diff --git a/prolog/problems/sets/is_subset_2/en.py b/prolog/problems/sets/is_subset_2/en.py
index b851d82..ad4804c 100644
--- a/prolog/problems/sets/is_subset_2/en.py
+++ b/prolog/problems/sets/is_subset_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 132
name = 'is_subset/2'
slug = 'check if one set is a subset of another'
diff --git a/prolog/problems/sets/is_superset_2/common.py b/prolog/problems/sets/is_superset_2/common.py
index 356ca34..86e5dc7 100644
--- a/prolog/problems/sets/is_superset_2/common.py
+++ b/prolog/problems/sets/is_superset_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 131
-group = 'sets'
number = 38
visible = True
facts = None
diff --git a/prolog/problems/sets/is_superset_2/en.py b/prolog/problems/sets/is_superset_2/en.py
index 16b3db0..464762c 100644
--- a/prolog/problems/sets/is_superset_2/en.py
+++ b/prolog/problems/sets/is_superset_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 131
name = 'is_superset/2'
slug = 'check if one set is a superset of the other'
diff --git a/prolog/problems/sets/powerset_2/common.py b/prolog/problems/sets/powerset_2/common.py
index 1561eed..c825430 100644
--- a/prolog/problems/sets/powerset_2/common.py
+++ b/prolog/problems/sets/powerset_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 134
-group = 'sets'
number = 41
visible = True
facts = None
diff --git a/prolog/problems/sets/powerset_2/en.py b/prolog/problems/sets/powerset_2/en.py
index dcaee19..ad2fe87 100644
--- a/prolog/problems/sets/powerset_2/en.py
+++ b/prolog/problems/sets/powerset_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 134
name = 'powerset/2'
slug = 'find all subsets of a set'
diff --git a/prolog/problems/sets/subset_2/common.py b/prolog/problems/sets/subset_2/common.py
index 4cc2260..130d87b 100644
--- a/prolog/problems/sets/subset_2/common.py
+++ b/prolog/problems/sets/subset_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 133
-group = 'sets'
number = 40
visible = True
facts = None
diff --git a/prolog/problems/sets/subset_2/en.py b/prolog/problems/sets/subset_2/en.py
index 78c1362..eb96ac0 100644
--- a/prolog/problems/sets/subset_2/en.py
+++ b/prolog/problems/sets/subset_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 133
name = 'subset/2'
slug = 'generate all subsets of a set'
diff --git a/prolog/problems/sets/union_3/common.py b/prolog/problems/sets/union_3/common.py
index bd77d3a..2a14245 100644
--- a/prolog/problems/sets/union_3/common.py
+++ b/prolog/problems/sets/union_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 128
-group = 'sets'
number = 35
visible = True
facts = None
diff --git a/prolog/problems/sets/union_3/en.py b/prolog/problems/sets/union_3/en.py
index 1c9379e..db6bbd9 100644
--- a/prolog/problems/sets/union_3/en.py
+++ b/prolog/problems/sets/union_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 128
name = 'union/3'
slug = 'find the union of two sets'
diff --git a/prolog/problems/sorting/common.py b/prolog/problems/sorting/common.py
new file mode 100644
index 0000000..f006f10
--- /dev/null
+++ b/prolog/problems/sorting/common.py
@@ -0,0 +1,2 @@
+id = 3
+number = 3
diff --git a/prolog/problems/sorting/is_sorted_1/common.py b/prolog/problems/sorting/is_sorted_1/common.py
index 4bb3fa9..8feb549 100644
--- a/prolog/problems/sorting/is_sorted_1/common.py
+++ b/prolog/problems/sorting/is_sorted_1/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 121
-group = 'sorting'
number = 28
visible = True
facts = None
diff --git a/prolog/problems/sorting/is_sorted_1/en.py b/prolog/problems/sorting/is_sorted_1/en.py
index ab8e2dc..3ea6572 100644
--- a/prolog/problems/sorting/is_sorted_1/en.py
+++ b/prolog/problems/sorting/is_sorted_1/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 121
name = 'is_sorted/1'
slug = 'check if list is sorted'
diff --git a/prolog/problems/sorting/isort_2/common.py b/prolog/problems/sorting/isort_2/common.py
index 94f5f42..f2c4244 100644
--- a/prolog/problems/sorting/isort_2/common.py
+++ b/prolog/problems/sorting/isort_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 123
-group = 'sorting'
number = 30
visible = True
facts = None
diff --git a/prolog/problems/sorting/isort_2/en.py b/prolog/problems/sorting/isort_2/en.py
index d9b3796..9fba6ac 100644
--- a/prolog/problems/sorting/isort_2/en.py
+++ b/prolog/problems/sorting/isort_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 123
name = 'isort/2'
slug = 'sort a list using insertion sort'
diff --git a/prolog/problems/sorting/pivoting_4/common.py b/prolog/problems/sorting/pivoting_4/common.py
index a8ff2f4..dd1a1a9 100644
--- a/prolog/problems/sorting/pivoting_4/common.py
+++ b/prolog/problems/sorting/pivoting_4/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 124
-group = 'sorting'
number = 31
visible = True
facts = None
diff --git a/prolog/problems/sorting/pivoting_4/en.py b/prolog/problems/sorting/pivoting_4/en.py
index 5a5e171..43e4ae3 100644
--- a/prolog/problems/sorting/pivoting_4/en.py
+++ b/prolog/problems/sorting/pivoting_4/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 124
name = 'pivoting/4'
slug = 'split a list according to the pivot'
diff --git a/prolog/problems/sorting/quick_sort_2/common.py b/prolog/problems/sorting/quick_sort_2/common.py
index 9c2b261..4afc8fa 100644
--- a/prolog/problems/sorting/quick_sort_2/common.py
+++ b/prolog/problems/sorting/quick_sort_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 125
-group = 'sorting'
number = 32
visible = True
facts = None
diff --git a/prolog/problems/sorting/quick_sort_2/en.py b/prolog/problems/sorting/quick_sort_2/en.py
index bed1a83..faf6d41 100644
--- a/prolog/problems/sorting/quick_sort_2/en.py
+++ b/prolog/problems/sorting/quick_sort_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 125
name = 'quick_sort/2'
slug = 'sort a list using quicksort'
diff --git a/prolog/problems/sorting/sins_3/common.py b/prolog/problems/sorting/sins_3/common.py
index ba50e65..ab592ea 100644
--- a/prolog/problems/sorting/sins_3/common.py
+++ b/prolog/problems/sorting/sins_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 122
-group = 'sorting'
number = 29
visible = True
facts = None
diff --git a/prolog/problems/sorting/sins_3/en.py b/prolog/problems/sorting/sins_3/en.py
index 384fbf7..2d9cf98 100644
--- a/prolog/problems/sorting/sins_3/en.py
+++ b/prolog/problems/sorting/sins_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 122
name = 'sins/3'
slug = 'insert an element at correct position into a sorted list'
diff --git a/prolog/problems/sorting/slowest_sort_ever_2/common.py b/prolog/problems/sorting/slowest_sort_ever_2/common.py
index 267f06a..fc8f980 100644
--- a/prolog/problems/sorting/slowest_sort_ever_2/common.py
+++ b/prolog/problems/sorting/slowest_sort_ever_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 126
-group = 'sorting'
number = 33
visible = True
facts = None
diff --git a/prolog/problems/sorting/slowest_sort_ever_2/en.py b/prolog/problems/sorting/slowest_sort_ever_2/en.py
index 0f39645..e327102 100644
--- a/prolog/problems/sorting/slowest_sort_ever_2/en.py
+++ b/prolog/problems/sorting/slowest_sort_ever_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 126
name = 'slowest_sort_ever/2'
slug = 'sort a list by randomly permuting elements'
diff --git a/prolog/problems/trees/common.py b/prolog/problems/trees/common.py
new file mode 100644
index 0000000..a519878
--- /dev/null
+++ b/prolog/problems/trees/common.py
@@ -0,0 +1,2 @@
+id = 6
+number = 5
diff --git a/prolog/problems/trees/deletebt_3/common.py b/prolog/problems/trees/deletebt_3/common.py
index 0963d15..98ad95f 100644
--- a/prolog/problems/trees/deletebt_3/common.py
+++ b/prolog/problems/trees/deletebt_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 137
-group = 'trees'
number = 47
visible = True
facts = None
diff --git a/prolog/problems/trees/deletebt_3/en.py b/prolog/problems/trees/deletebt_3/en.py
index a69ea15..215fced 100644
--- a/prolog/problems/trees/deletebt_3/en.py
+++ b/prolog/problems/trees/deletebt_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 137
name = 'deleteBT/3'
slug = 'delete an element from a binary tree'
diff --git a/prolog/problems/trees/depthbt_2/common.py b/prolog/problems/trees/depthbt_2/common.py
index d8b255d..85dfa27 100644
--- a/prolog/problems/trees/depthbt_2/common.py
+++ b/prolog/problems/trees/depthbt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 140
-group = 'trees'
number = 45
visible = True
facts = None
diff --git a/prolog/problems/trees/depthbt_2/en.py b/prolog/problems/trees/depthbt_2/en.py
index 5616bc0..94fec48 100644
--- a/prolog/problems/trees/depthbt_2/en.py
+++ b/prolog/problems/trees/depthbt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 140
name = 'depthBT/2'
slug = 'find the depth of a binary tree'
diff --git a/prolog/problems/trees/insertbt_3/common.py b/prolog/problems/trees/insertbt_3/common.py
index 1653183..f8ef004 100644
--- a/prolog/problems/trees/insertbt_3/common.py
+++ b/prolog/problems/trees/insertbt_3/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 138
-group = 'trees'
number = 48
visible = True
facts = None
diff --git a/prolog/problems/trees/insertbt_3/en.py b/prolog/problems/trees/insertbt_3/en.py
index dec4050..08eb2cd 100644
--- a/prolog/problems/trees/insertbt_3/en.py
+++ b/prolog/problems/trees/insertbt_3/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 138
name = 'insertBT/3'
slug = 'insert an element into a binary tree'
diff --git a/prolog/problems/trees/maxt_2/common.py b/prolog/problems/trees/maxt_2/common.py
index 264f5e2..280cb25 100644
--- a/prolog/problems/trees/maxt_2/common.py
+++ b/prolog/problems/trees/maxt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 143
-group = 'trees'
number = 50
visible = True
facts = None
diff --git a/prolog/problems/trees/maxt_2/en.py b/prolog/problems/trees/maxt_2/en.py
index 18e99d4..20db52e 100644
--- a/prolog/problems/trees/maxt_2/en.py
+++ b/prolog/problems/trees/maxt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 143
name = 'maxT/2'
slug = 'find the greatest element in a tree'
diff --git a/prolog/problems/trees/memberbt_2/common.py b/prolog/problems/trees/memberbt_2/common.py
index e983b76..f5e5435 100644
--- a/prolog/problems/trees/memberbt_2/common.py
+++ b/prolog/problems/trees/memberbt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 135
-group = 'trees'
number = 42
visible = True
facts = None
diff --git a/prolog/problems/trees/memberbt_2/en.py b/prolog/problems/trees/memberbt_2/en.py
index e9b87a6..e8d48f2 100644
--- a/prolog/problems/trees/memberbt_2/en.py
+++ b/prolog/problems/trees/memberbt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 135
name = 'memberBT/2'
slug = 'find elements in a binary tree'
diff --git a/prolog/problems/trees/membert_2/common.py b/prolog/problems/trees/membert_2/common.py
index 33a966d..c91371e 100644
--- a/prolog/problems/trees/membert_2/common.py
+++ b/prolog/problems/trees/membert_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 142
-group = 'trees'
number = 49
visible = True
facts = None
diff --git a/prolog/problems/trees/membert_2/en.py b/prolog/problems/trees/membert_2/en.py
index 9095e08..738d625 100644
--- a/prolog/problems/trees/membert_2/en.py
+++ b/prolog/problems/trees/membert_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 142
name = 'memberT/2'
slug = 'find elements in a tree'
diff --git a/prolog/problems/trees/mirrorbt_2/common.py b/prolog/problems/trees/mirrorbt_2/common.py
index c10f433..cc271cc 100644
--- a/prolog/problems/trees/mirrorbt_2/common.py
+++ b/prolog/problems/trees/mirrorbt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 136
-group = 'trees'
number = 43
visible = True
facts = None
diff --git a/prolog/problems/trees/mirrorbt_2/en.py b/prolog/problems/trees/mirrorbt_2/en.py
index 797ca93..85c2a54 100644
--- a/prolog/problems/trees/mirrorbt_2/en.py
+++ b/prolog/problems/trees/mirrorbt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 136
name = 'mirrorBT/2'
slug = 'flip a binary tree horizontally'
diff --git a/prolog/problems/trees/numberbt_2/common.py b/prolog/problems/trees/numberbt_2/common.py
index a7499c2..7df71d8 100644
--- a/prolog/problems/trees/numberbt_2/common.py
+++ b/prolog/problems/trees/numberbt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 139
-group = 'trees'
number = 44
visible = True
facts = None
diff --git a/prolog/problems/trees/numberbt_2/en.py b/prolog/problems/trees/numberbt_2/en.py
index d0f835c..3be193d 100644
--- a/prolog/problems/trees/numberbt_2/en.py
+++ b/prolog/problems/trees/numberbt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 139
name = 'numberBT/2'
slug = 'find the number of nodes in a binary tree'
diff --git a/prolog/problems/trees/tolistbt_2/common.py b/prolog/problems/trees/tolistbt_2/common.py
index c9765df..e6c8ffd 100644
--- a/prolog/problems/trees/tolistbt_2/common.py
+++ b/prolog/problems/trees/tolistbt_2/common.py
@@ -1,7 +1,6 @@
# coding=utf-8
id = 141
-group = 'trees'
number = 46
visible = True
facts = None
diff --git a/prolog/problems/trees/tolistbt_2/en.py b/prolog/problems/trees/tolistbt_2/en.py
index e67fffb..a6d0d4b 100644
--- a/prolog/problems/trees/tolistbt_2/en.py
+++ b/prolog/problems/trees/tolistbt_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 141
name = 'tolistBT/2'
slug = 'construct a list with all elements of a binary tree'
diff --git a/python/common.py b/python/common.py
index c754a1a..2d89c19 100644
--- a/python/common.py
+++ b/python/common.py
@@ -3,6 +3,8 @@
import ast
from server.hints import Hint
+id = 2
+
hint_type = {
'no_hint': Hint('no_hint'),
'program_already_correct': Hint('program_already_correct'),
diff --git a/python/problems/functions/assign_numbers/common.py b/python/problems/functions/assign_numbers/common.py
new file mode 100644
index 0000000..effd061
--- /dev/null
+++ b/python/problems/functions/assign_numbers/common.py
@@ -0,0 +1,64 @@
+# 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 = 225
+number = 4
+visible = True
+
+solution = '''\
+def numbers(xs):
+ ys = []
+ for i in range(len(xs)):
+ ys.append((i, xs[i]))
+ return ys
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'numbers'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([], []),
+ ([1], [(0, 1)]),
+ ([5, 1, 4, 2, 3], [(0, 5), (1, 1), (2, 4), (3, 2), (4, 3)]),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/assign_numbers/en.py b/python/problems/functions/assign_numbers/en.py
new file mode 100644
index 0000000..a68c6c8
--- /dev/null
+++ b/python/problems/functions/assign_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 225
+name = 'Assign numbers'
+slug = 'Assign numbers'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/assign_numbers/sl.py b/python/problems/functions/assign_numbers/sl.py
new file mode 100644
index 0000000..97c0c3a
--- /dev/null
+++ b/python/problems/functions/assign_numbers/sl.py
@@ -0,0 +1,34 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 225
+name = 'Oštevilči'
+slug = 'Oštevilči'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>numbers(xs)</code>, ki vrne seznam oblike <code>[(0, xs[0]), (1, xs[1]), ..., (n, xs[n])]</code>.
+Število <code>n</code> je enako dolžini seznama <code>xs</code> minus ena.
+<pre>
+>>> numbers([4, 4, 4])
+[(0, 4), (1, 4), (2, 4)]
+>>> numbers([5, 1, 4, 2, 3])
+[(0, 5), (1, 1), (2, 4), (3, 2), (4, 3)]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/body_mass_index/common.py b/python/problems/functions/body_mass_index/common.py
new file mode 100644
index 0000000..8e774be
--- /dev/null
+++ b/python/problems/functions/body_mass_index/common.py
@@ -0,0 +1,67 @@
+# 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 = 226
+number = 5
+visible = True
+
+solution = '''\
+def bmi(xs):
+ ys = []
+ for name, weight, height in xs:
+ ys.append((name, weight / (height / 100)**2))
+ return ys
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'bmi'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([], []),
+ ([('Ana', 55, 165), ('Berta', 60, 153)],
+ [('Ana', 20.202020202020204), ('Berta', 25.63116749967961)]),
+ ([('Ana', 55, 165), ('Berta', 60, 153), ('Cilka', 70, 183)],
+ [('Ana', 20.202020202020204), ('Berta', 25.63116749967961), ('Cilka', 20.902385858042937)]),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/body_mass_index/en.py b/python/problems/functions/body_mass_index/en.py
new file mode 100644
index 0000000..fb4663f
--- /dev/null
+++ b/python/problems/functions/body_mass_index/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 226
+name = 'Body mass index'
+slug = 'Body mass index'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/body_mass_index/sl.py b/python/problems/functions/body_mass_index/sl.py
new file mode 100644
index 0000000..fd67c88
--- /dev/null
+++ b/python/problems/functions/body_mass_index/sl.py
@@ -0,0 +1,35 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 226
+name = 'Indeks telesne teže'
+slug = 'Indeks telesne teže'
+
+
+description = '''\
+<p>
+Podan imamo seznam trojk: ime osebe, teža, višina, na primer:
+<pre>
+>>> osebe = [('Ana', 55, 165), ('Berta', 60, 153)]
+</pre>
+Napišite funkcijo <code>bmi(osebe)</code>, ki na podlagi podanega seznama osebe, sestavi seznam dvojk: ime osebe, indeks telesne teže:
+<pre>
+>>> bmi(osebe)
+[('Ana', 20.202020202020204), ('Berta', 25.63116749967961)]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/body_mass_index_2/common.py b/python/problems/functions/body_mass_index_2/common.py
new file mode 100644
index 0000000..c6cf2b3
--- /dev/null
+++ b/python/problems/functions/body_mass_index_2/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 = 227
+number = 6
+visible = True
+
+solution = '''\
+def bmi2(names, weights, heights):
+ ys = []
+ for name, weight, height in zip(names, weights, heights):
+ ys.append((name, weight / (height / 100)**2))
+ return ys
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'bmi2'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (([], [], []), []),
+ ((['Ana', 'Berta'], [55, 60], [165, 153]),
+ [('Ana', 20.202020202020204), ('Berta', 25.63116749967961)]),
+ ((['Ana', 'Berta', 'Cilka'], [55, 60, 70], [165, 153, 183]),
+ [('Ana', 20.202020202020204), ('Berta', 25.63116749967961), ('Cilka', 20.902385858042937)]),
+ ]
+
+ test_in = [(func_name+'(*%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/body_mass_index_2/en.py b/python/problems/functions/body_mass_index_2/en.py
new file mode 100644
index 0000000..b34718b
--- /dev/null
+++ b/python/problems/functions/body_mass_index_2/en.py
@@ -0,0 +1,15 @@
+# coding=utf-8
+
+name = 'Body mass index 2'
+slug = 'Body mass index 2'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/body_mass_index_2/sl.py b/python/problems/functions/body_mass_index_2/sl.py
new file mode 100644
index 0000000..8cd56c7
--- /dev/null
+++ b/python/problems/functions/body_mass_index_2/sl.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+name = 'Indeks telesne teže 2'
+slug = 'Indeks telesne teže 2'
+
+description = '''\
+<p>
+Naloga je podobna prejšnji, le da imamo tokrat podatke v drugačni obliki:
+<pre>
+>>> imena = ['Ana', 'Berta']
+>>> teze = [55, 60]
+>>> visine = [165, 153]
+>>> bmi2(imena, teze, visine)
+[('Ana', 20.202020202020204), ('Berta', 25.63116749967961)]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/common.py b/python/problems/functions/common.py
new file mode 100644
index 0000000..ede78e6
--- /dev/null
+++ b/python/problems/functions/common.py
@@ -0,0 +1,2 @@
+id = 17
+number = 4 \ No newline at end of file
diff --git a/python/problems/functions/divisors/common.py b/python/problems/functions/divisors/common.py
new file mode 100644
index 0000000..afff7c5
--- /dev/null
+++ b/python/problems/functions/divisors/common.py
@@ -0,0 +1,69 @@
+# 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 = 230
+number = 9
+visible = True
+
+solution = '''\
+def divisors(n):
+ for i in range(1, n):
+ if n % i == 0:
+ print(i)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'divisors'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (8, [1,2,4]),
+ (6, [1,2,3]),
+ (5, [1]),
+ (1, []),
+ (2, [1]),
+ (15, [1,3,5]),
+ (20, [1,2,4,5,10])
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ numbers = sorted(int(n) for n in get_numbers(ans[1]))
+ if numbers == to:
+ n_correct += 1
+ else:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/divisors/en.py b/python/problems/functions/divisors/en.py
new file mode 100644
index 0000000..d1e71c2
--- /dev/null
+++ b/python/problems/functions/divisors/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 230
+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/functions/divisors/sl.py b/python/problems/functions/divisors/sl.py
new file mode 100644
index 0000000..76b0917
--- /dev/null
+++ b/python/problems/functions/divisors/sl.py
@@ -0,0 +1,26 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 230
+name = 'Delitelji'
+slug = 'Delitelji'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>divisors(n)</code>, ki izpiše vse delitelje števila (brez samega sebe), ki ga vnese uporabnik.</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/divisors_sum/common.py b/python/problems/functions/divisors_sum/common.py
new file mode 100644
index 0000000..142a448
--- /dev/null
+++ b/python/problems/functions/divisors_sum/common.py
@@ -0,0 +1,69 @@
+# 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 = 231
+number = 10
+visible = True
+
+solution = '''\
+def divisors_sum(n):
+ s = 0
+ for i in range(1, n):
+ if n % i == 0:
+ s += i
+ return s
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'divisors_sum'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (8, 7),
+ (6, 6),
+ (5, 1),
+ (1, 0),
+ (2, 1),
+ (15, 9),
+ (20, 22)
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/divisors_sum/en.py b/python/problems/functions/divisors_sum/en.py
new file mode 100644
index 0000000..67806f7
--- /dev/null
+++ b/python/problems/functions/divisors_sum/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 231
+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/functions/divisors_sum/sl.py b/python/problems/functions/divisors_sum/sl.py
new file mode 100644
index 0000000..47b8719
--- /dev/null
+++ b/python/problems/functions/divisors_sum/sl.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 231
+name = 'Vsota deliteljev'
+slug = 'Vsota deliteljev'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>divisors_sum(n)</code>, ki vrne vsoto vseh deliteljev števila, ki ga vnese uporabnik.
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/friendly_numbers/common.py b/python/problems/functions/friendly_numbers/common.py
new file mode 100644
index 0000000..fe121dc
--- /dev/null
+++ b/python/problems/functions/friendly_numbers/common.py
@@ -0,0 +1,75 @@
+# 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 = 233
+number = 12
+visible = True
+
+solution = '''\
+def divisors_sum(n):
+ s = 0
+ for i in range(1, n):
+ if n % i == 0:
+ s += i
+ return s
+
+def amicable_number(n):
+ s = divisors_sum(n)
+ if n == divisors_sum(s):
+ return s
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'amicable_number'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (220, 284),
+ (284, 220),
+ (1010, None),
+ (6, None),
+ (2620, 2924),
+ (1, None),
+ (10, None),
+ (1210, 1184)
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/friendly_numbers/en.py b/python/problems/functions/friendly_numbers/en.py
new file mode 100644
index 0000000..c77dca1
--- /dev/null
+++ b/python/problems/functions/friendly_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 233
+name = 'Amicable numbers'
+slug = 'Amicable numbers'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/friendly_numbers/sl.py b/python/problems/functions/friendly_numbers/sl.py
new file mode 100644
index 0000000..51d47ae
--- /dev/null
+++ b/python/problems/functions/friendly_numbers/sl.py
@@ -0,0 +1,37 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 233
+name = 'Prijateljska števila'
+slug = 'Prijateljska števila'
+
+
+description = '''\
+<p>
+220 in 284 sta prijateljski števili. Delitelji 220 so 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 in 110.
+Če jih seštejemo, dobimo 284. Delitelji 284 pa so 1, 2, 4, 71 in 142. Vsota teh števil pa je 220.
+Napiši funkcijo <code>amicable_number(n)</code>, ki vrne prijateljsko število številu <code>n</code>, če ga ima, oz.
+vrne <code>None</code>, če ga nima. Primer:
+<pre>
+>>> amicable_number(220)
+284
+>>> amicable_number(222)
+None
+</pre>
+</p>
+<p> Uporabite funkcijo za vsoto deliteljev!</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/greatest/common.py b/python/problems/functions/greatest/common.py
index 6857603..726fa88 100644
--- a/python/problems/functions/greatest/common.py
+++ b/python/problems/functions/greatest/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 195
-group = 'functions'
number = 1
visible = True
@@ -32,6 +31,10 @@ hint_type = {
}
def test(python, code):
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', 'max_val']):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : 'max_val'}}]
+
test_lists = [[6, 4, 2, 0],
[4, 6, 2, 0],
[4, 2, 6, 0],
diff --git a/python/problems/functions/greatest/en.py b/python/problems/functions/greatest/en.py
index 8a0c883..acf4672 100644
--- a/python/problems/functions/greatest/en.py
+++ b/python/problems/functions/greatest/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 195
name = 'Maximum number'
slug = 'Maximum number'
diff --git a/python/problems/functions/greatest/sl.py b/python/problems/functions/greatest/sl.py
index a7916a5..12e07fe 100644
--- a/python/problems/functions/greatest/sl.py
+++ b/python/problems/functions/greatest/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 195
name = 'Največji'
slug = 'Največji'
diff --git a/python/problems/functions/greatest_absolutist/common.py b/python/problems/functions/greatest_absolutist/common.py
index 2d80097..3226b87 100644
--- a/python/problems/functions/greatest_absolutist/common.py
+++ b/python/problems/functions/greatest_absolutist/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 196
-group = 'functions'
number = 2
visible = True
@@ -35,6 +34,10 @@ hint_type = {
def test(python, code):
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', 'max_abs']):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : 'max_abs'}}]
+
test_lists = [[6, 4, 2, 0],
[4, 6, 2, 0],
[4, 2, 6, 0],
diff --git a/python/problems/functions/greatest_absolutist/en.py b/python/problems/functions/greatest_absolutist/en.py
index 03614e7..1ede4a9 100644
--- a/python/problems/functions/greatest_absolutist/en.py
+++ b/python/problems/functions/greatest_absolutist/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 196
name = 'Greatest absolutist'
slug = 'Greatest absolutist'
diff --git a/python/problems/functions/greatest_absolutist/sl.py b/python/problems/functions/greatest_absolutist/sl.py
index d51cd96..a45f483 100644
--- a/python/problems/functions/greatest_absolutist/sl.py
+++ b/python/problems/functions/greatest_absolutist/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 196
name = 'Največji absolutist'
slug = 'Največji absolutist'
@@ -101,7 +100,7 @@ V tem primeru se lahko zgodi, da se zanka ne izteče do konca.</p>''',
Tudi to nalogo lahko rešimo s funkcijo <code>max</code>:</p>
<pre>
def max_abs(xs):
- return max(xs, key = lambda x: abs(x))
+ return max(xs, key = abs(x))
</pre>''',
}
diff --git a/python/problems/functions/greatest_negative/common.py b/python/problems/functions/greatest_negative/common.py
index 5d65438..72754e2 100644
--- a/python/problems/functions/greatest_negative/common.py
+++ b/python/problems/functions/greatest_negative/common.py
@@ -6,7 +6,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 197
-group = 'functions'
number = 3
visible = True
@@ -35,6 +34,10 @@ hint_type = {
def test(python, code):
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', 'max_neg']):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : 'max_neg'}}]
+
test_lists = [[6, 4, 2, 0],
[4, 6, 2, -1],
[4, -2, -6, 0],
diff --git a/python/problems/functions/greatest_negative/en.py b/python/problems/functions/greatest_negative/en.py
index a57cb1f..5c2919a 100644
--- a/python/problems/functions/greatest_negative/en.py
+++ b/python/problems/functions/greatest_negative/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 197
name = 'Greatest negativist'
slug = 'Greatest negativist'
diff --git a/python/problems/functions/greatest_negative/sl.py b/python/problems/functions/greatest_negative/sl.py
index ea1e47c..31f1fd6 100644
--- a/python/problems/functions/greatest_negative/sl.py
+++ b/python/problems/functions/greatest_negative/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 197
name = 'Največji negativec'
slug = 'Največji negativec'
diff --git a/python/problems/functions/palindrome/common.py b/python/problems/functions/palindrome/common.py
new file mode 100644
index 0000000..eec8211
--- /dev/null
+++ b/python/problems/functions/palindrome/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 = 228
+number = 7
+visible = True
+
+solution = '''\
+def palindrome(s):
+ return s == s[::-1]
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'palindrome'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ('', True),
+ ('a', True),
+ ('aa', True),
+ ('ab', False),
+ ('aba', True),
+ ('abc', False),
+ ('abcdefedcba', True),
+ ('abcdefgedcba', False),
+ ('pericarezeracirep', True),
+ ('perica', False),
+ ]
+
+ test_in = [(func_name+'("%s")'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/palindrome/en.py b/python/problems/functions/palindrome/en.py
new file mode 100644
index 0000000..784c395
--- /dev/null
+++ b/python/problems/functions/palindrome/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 228
+name = 'Palindrome'
+slug = 'Palindrome'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/palindrome/sl.py b/python/problems/functions/palindrome/sl.py
new file mode 100644
index 0000000..e005057
--- /dev/null
+++ b/python/problems/functions/palindrome/sl.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 228
+name = 'Palindrom'
+slug = 'Palindrom'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>palindrome(s)</code>, ki preveri, ali je niz s palindrom.
+<pre>
+>>> palindrome('pericarezeracirep')
+True
+>>> palindrome('perica')
+False
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/palindromic_numbers/common.py b/python/problems/functions/palindromic_numbers/common.py
new file mode 100644
index 0000000..6f49896
--- /dev/null
+++ b/python/problems/functions/palindromic_numbers/common.py
@@ -0,0 +1,70 @@
+# 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 = 229
+number = 8
+visible = True
+
+solution = '''\
+def palindromic_numbers():
+ xs = []
+ for i in range(100, 1000):
+ for j in range(100, 1000):
+ if str(i * j) == str(i * j)[::-1]:
+ xs.append(i * j)
+ return max(xs)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'numbers'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (906609, True),
+ (123456, False),
+ (1, True),
+ (11, True),
+ (12, False),
+ (113, False),
+ (131, True)
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/palindromic_numbers/en.py b/python/problems/functions/palindromic_numbers/en.py
new file mode 100644
index 0000000..5f4ea76
--- /dev/null
+++ b/python/problems/functions/palindromic_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 229
+name = 'Palindromic numbers'
+slug = 'Palindromic numbers'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/palindromic_numbers/sl.py b/python/problems/functions/palindromic_numbers/sl.py
new file mode 100644
index 0000000..8d64bab
--- /dev/null
+++ b/python/problems/functions/palindromic_numbers/sl.py
@@ -0,0 +1,31 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 229
+name = 'Palindromska števila'
+slug = 'Palindromska števila'
+
+
+description = '''\
+<p>
+Največje palindromsko število, ki ga lahko dobimo kot produkt dveh dvomestnih števil je <code>9009 = 91 * 99</code>.
+Napišite funkcijo <code>palindromic_number()</code>, ki poišče in vrne največje palindromsko število,
+ki ga lahko dobimo kot produkt dveh tromestnih števil.
+
+Vir: Project Euler, <a href="http://projecteuler.net/index.php?section=problems&id=4">Problem 4</a>.
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/perfect_numbers/common.py b/python/problems/functions/perfect_numbers/common.py
new file mode 100644
index 0000000..72267e6
--- /dev/null
+++ b/python/problems/functions/perfect_numbers/common.py
@@ -0,0 +1,71 @@
+# 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 = 232
+number = 11
+visible = True
+
+solution = '''\
+def divisors_sum(n):
+ s = 0
+ for i in range(1, n):
+ if n % i == 0:
+ s += i
+ return s
+
+def perfect(n):
+ return n == divisors_sum(n)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'perfect'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (6, True),
+ (28, True),
+ (1, False),
+ (5, False),
+ (496, True),
+ (497, False),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/perfect_numbers/en.py b/python/problems/functions/perfect_numbers/en.py
new file mode 100644
index 0000000..a7cb94e
--- /dev/null
+++ b/python/problems/functions/perfect_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 232
+name = 'Perfect numbers'
+slug = 'Perfect numbers'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/perfect_numbers/sl.py b/python/problems/functions/perfect_numbers/sl.py
new file mode 100644
index 0000000..a354a17
--- /dev/null
+++ b/python/problems/functions/perfect_numbers/sl.py
@@ -0,0 +1,30 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 232
+name = 'Popolna števila'
+slug = 'Popolna števila'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>perfect(n)</code>, ki vrne <code>True</code>, če je podano število popolno, oz. <code>False</code>, č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>
+<p> Uporabite funkcijo za vsoto deliteljev!</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions/prime_numbers/common.py b/python/problems/functions/prime_numbers/common.py
new file mode 100644
index 0000000..33eb134
--- /dev/null
+++ b/python/problems/functions/prime_numbers/common.py
@@ -0,0 +1,69 @@
+# 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 = 234
+number = 13
+visible = True
+
+solution = '''\
+def prime(n):
+ for i in range(2, n):
+ for j in range(2, i):
+ if i % j == 0:
+ break
+ else:
+ print(i)
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'prime'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (3, [2]),
+ (10, [2, 3, 5, 7]),
+ (100, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ numbers = sorted([int(n) for n in get_numbers(ans[1])])
+
+ if numbers == to:
+ n_correct += 1
+ else:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions/prime_numbers/en.py b/python/problems/functions/prime_numbers/en.py
new file mode 100644
index 0000000..87c01a2
--- /dev/null
+++ b/python/problems/functions/prime_numbers/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 234
+name = 'Prime numbers'
+slug = 'Prime numbers'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions/prime_numbers/sl.py b/python/problems/functions/prime_numbers/sl.py
new file mode 100644
index 0000000..f6c6b24
--- /dev/null
+++ b/python/problems/functions/prime_numbers/sl.py
@@ -0,0 +1,27 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 234
+name = 'Praštevila'
+slug = 'Praštevila'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>prime(n)</code>, ki izpiše vsa praštevila manjša od <code>n</code>.
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/all/common.py b/python/problems/functions_and_modules/all/common.py
new file mode 100644
index 0000000..a02cb4b
--- /dev/null
+++ b/python/problems/functions_and_modules/all/common.py
@@ -0,0 +1,72 @@
+# 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 = 238
+number = 4
+visible = True
+
+solution = '''\
+def all(xs):
+ for x in xs:
+ if not x:
+ return False
+ return True
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'all'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([True, True, False], False),
+ ([True, True], True),
+ ([1, 2, 3, 0], False),
+ (['foo', 42, True], True),
+ (['foo', '', 42, True], False),
+ (['foo', 0.0, 42, True], False),
+ (['foo', None, 42, True], False),
+ (['foo', (), 42, True], False),
+ (['foo', [], 42, True], False),
+ ([], True),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/all/en.py b/python/problems/functions_and_modules/all/en.py
new file mode 100644
index 0000000..3028ad4
--- /dev/null
+++ b/python/problems/functions_and_modules/all/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 238
+name = 'All'
+slug = 'All'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/all/sl.py b/python/problems/functions_and_modules/all/sl.py
new file mode 100644
index 0000000..f71fa4b
--- /dev/null
+++ b/python/problems/functions_and_modules/all/sl.py
@@ -0,0 +1,40 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 238
+name = 'Vsi'
+slug = 'Vsi'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>all</code>, ki sprejme seznam <code>xs</code> in vrne <code>True</code>,
+če so vse vrednosti v seznamu resnične. Elementi seznama <code>xs</code> so lahko poljubnega tipa, ne le <code>bool</code>.
+<pre>
+>>> all([True, True, False])
+False
+>>> all([True, True])
+True
+>>> all([1, 2, 3, 0])
+False
+>>> all(['foo', 42, True])
+True
+>>> all([])
+True
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/any/common.py b/python/problems/functions_and_modules/any/common.py
new file mode 100644
index 0000000..9d0d0d2
--- /dev/null
+++ b/python/problems/functions_and_modules/any/common.py
@@ -0,0 +1,70 @@
+# 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 = 239
+number = 4
+visible = True
+
+solution = '''\
+def any(xs):
+ for x in xs:
+ if x:
+ return True
+ return False
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'any'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([2, 3, 0], True),
+ ([], False),
+ ([True, False, False], True),
+ ([False, False], False),
+ (['foo', 42, True], True),
+ ([False, 0, 0.0, '', None, (), []], False),
+ ([False, 0, 0.42, '', None, (), []], True),
+ ([False, 0, 0.0, '', None, (), [42]], True),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/any/en.py b/python/problems/functions_and_modules/any/en.py
new file mode 100644
index 0000000..f5b94d9
--- /dev/null
+++ b/python/problems/functions_and_modules/any/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 239
+name = 'Any'
+slug = 'Any'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/any/sl.py b/python/problems/functions_and_modules/any/sl.py
new file mode 100644
index 0000000..f32e50e
--- /dev/null
+++ b/python/problems/functions_and_modules/any/sl.py
@@ -0,0 +1,34 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 239
+name = 'Vsaj eden'
+slug = 'Vsaj eden'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>any(xs)</code>, ki deluje podobno kot <code>all</code>, le da vrne <code>True</code>,
+če je vsaj ena vrednost v seznamu resnična.
+<pre>
+>>> any([2, 3, 0])
+True
+>>> any([])
+False
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/caesar_cipher/common.py b/python/problems/functions_and_modules/caesar_cipher/common.py
new file mode 100644
index 0000000..497ce34
--- /dev/null
+++ b/python/problems/functions_and_modules/caesar_cipher/common.py
@@ -0,0 +1,79 @@
+# 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 = 243
+number = 9
+visible = True
+
+solution = '''\
+def caesar(s):
+ cipher = ''
+ for c in s:
+ if 'a' <= c <= 'w':
+ cipher += chr(ord(c) + 3)
+ elif 'x' <= c <= 'z':
+ cipher += chr(ord(c) - 23)
+ else:
+ cipher += c
+ return cipher
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'caesar'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ('', ''),
+ ('a', 'd'),
+ ('aa', 'dd'),
+ ('ab', 'de'),
+ ('z', 'c'),
+ ('xyz', 'abc'),
+ (' ', ' '),
+ ('a a', 'd d'),
+ ('julij cezar je seveda uporabljal cezarjevo sifro',
+ 'mxolm fhcdu mh vhyhgd xsrudeomdo fhcdumhyr vliur'),
+ ('the quick brown fox jumps over the lazy dog',
+ 'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'),
+ ]
+
+ test_in = [(func_name+'("%s")'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/caesar_cipher/en.py b/python/problems/functions_and_modules/caesar_cipher/en.py
new file mode 100644
index 0000000..bcfedee
--- /dev/null
+++ b/python/problems/functions_and_modules/caesar_cipher/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 243
+name = 'Caesar cipher'
+slug = 'Caesar cipher'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/caesar_cipher/sl.py b/python/problems/functions_and_modules/caesar_cipher/sl.py
new file mode 100644
index 0000000..ea4d9c8
--- /dev/null
+++ b/python/problems/functions_and_modules/caesar_cipher/sl.py
@@ -0,0 +1,35 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 243
+name = 'Cezarjeva šifra'
+slug = 'Cezarjeva šifra'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>caesar(s)</code>, ki podan niz zašifrira z uporabo <a href="http://sl.wikipedia.org/wiki/Cezarjeva_%C5%A1ifra">cezarjeve šifre</a>.
+Preden se lotite naloge, se je morda vredno pozanimati kaj počneta funkciji
+<a href="https://docs.python.org/3.5/library/functions.html#ord">ord</a> in
+<a href="https://docs.python.org/3.5/library/functions.html#chr">chr</a>.
+Predpostavite lahko, da niz <code>s</code> vsebuje le male črke angleške besede in presledke.
+<pre>
+>>> caesar('the quick brown fox jumps over the lazy dog')
+'wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj'
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/common.py b/python/problems/functions_and_modules/common.py
new file mode 100644
index 0000000..915b041
--- /dev/null
+++ b/python/problems/functions_and_modules/common.py
@@ -0,0 +1,2 @@
+id = 18
+number = 5 \ No newline at end of file
diff --git a/python/problems/functions_and_modules/dominoes/common.py b/python/problems/functions_and_modules/dominoes/common.py
new file mode 100644
index 0000000..9a46a78
--- /dev/null
+++ b/python/problems/functions_and_modules/dominoes/common.py
@@ -0,0 +1,69 @@
+# 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 = 240
+number = 6
+visible = True
+
+solution = '''\
+def dominoes(domine):
+ for i in range(len(domine) - 1):
+ if domine[i][1] != domine[i + 1][0]:
+ return False
+ return True
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'dominoes'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([], True),
+ ([(2, 4), (4, 4)], True),
+ ([(2, 4), (4, 4), (4, 2)], True),
+ ([(2, 4), (4, 4), (4, 2), (2, 9), (9, 1)], True),
+ ([(2, 4), (4, 3), (4, 2), (2, 9), (9, 1)], False),
+ ([(3, 6), (6, 6), (6, 1), (1, 0)], True),
+ ([(3, 6), (6, 6), (2, 3)], False),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/dominoes/en.py b/python/problems/functions_and_modules/dominoes/en.py
new file mode 100644
index 0000000..4d0d31b
--- /dev/null
+++ b/python/problems/functions_and_modules/dominoes/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 240
+name = 'Dominoes'
+slug = 'Dominoes'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/dominoes/sl.py b/python/problems/functions_and_modules/dominoes/sl.py
new file mode 100644
index 0000000..41cb860
--- /dev/null
+++ b/python/problems/functions_and_modules/dominoes/sl.py
@@ -0,0 +1,29 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 240
+name = 'Domine'
+slug = 'Domine'
+
+
+description = '''\
+<p>
+Vrsta domin je podana s seznamom parov (terk), na primer
+<code>[(3, 6), (6, 6), (6, 1), (1, 0)] ali [(3, 6), (6, 6), (2, 3)]</code>. Napišite funkcijo <code>dominoes(xs)</code>,
+ki prejme takšen seznam in pove, ali so domine pravilno zložene. Za prvi seznam mora vrniti <code>True</code> in za drugega <code>False</code>.
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/en.py b/python/problems/functions_and_modules/en.py
new file mode 100644
index 0000000..1218e73
--- /dev/null
+++ b/python/problems/functions_and_modules/en.py
@@ -0,0 +1,3 @@
+name = 'Functions and Modules'
+description = 'Advanced functions and modules'
+
diff --git a/python/problems/functions_and_modules/largest_sublist/common.py b/python/problems/functions_and_modules/largest_sublist/common.py
new file mode 100644
index 0000000..237b817
--- /dev/null
+++ b/python/problems/functions_and_modules/largest_sublist/common.py
@@ -0,0 +1,73 @@
+# 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 = 242
+number = 8
+visible = True
+
+solution = '''\
+def largest_sublist(xss):
+ najvecji = []
+ najvecji_vsota = float('-inf')
+ for xs in xss:
+ vsota = 0
+ for x in xs:
+ vsota += x
+ if vsota > najvecji_vsota:
+ najvecji = xs
+ najvecji_vsota = vsota
+ return najvecji
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'largest_sublist'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([[0]], [0]),
+ ([[1, 2]], [1, 2]),
+ ([[1, 2], [], [0]], [1, 2]),
+ ([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]], [8, 2]),
+ ([[5, 3, 6, 3], [1, 2, 3, 4], [5, -1, 0]], [5, 3, 6, 3]),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/largest_sublist/en.py b/python/problems/functions_and_modules/largest_sublist/en.py
new file mode 100644
index 0000000..132eb39
--- /dev/null
+++ b/python/problems/functions_and_modules/largest_sublist/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 242
+name = 'Largest sublist'
+slug = 'Largest sublist'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/largest_sublist/sl.py b/python/problems/functions_and_modules/largest_sublist/sl.py
new file mode 100644
index 0000000..b550ce2
--- /dev/null
+++ b/python/problems/functions_and_modules/largest_sublist/sl.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 242
+name = 'Največji podseznam'
+slug = 'Največji podseznam'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>largest_sublist</code>, ki vrne podseznam z največjo vsoto elementov.
+<pre>
+>>> largest_sublist([[1, 1, 1], [1, 1]])
+[1, 1, 1]
+>>> largest_sublist([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
+[8, 2]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/lists_sum/common.py b/python/problems/functions_and_modules/lists_sum/common.py
new file mode 100644
index 0000000..c62bce1
--- /dev/null
+++ b/python/problems/functions_and_modules/lists_sum/common.py
@@ -0,0 +1,72 @@
+# 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 = 241
+number = 7
+visible = True
+
+solution = '''\
+def lists_sum(xss):
+ vsote = []
+ for xs in xss:
+ vsota = 0
+ for x in xs:
+ vsota += x
+ vsote.append(vsota)
+ return vsote
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'lists_sum'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ([], []),
+ ([[]], [0]),
+ ([[0]], [0]),
+ ([[1, 2]], [3]),
+ ([[1, 2], [], [0]], [3, 0, 0]),
+ ([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]], [7, 4, 0, 10, 4]),
+ ([[5, 3, 6, 3], [1, 2, 3, 4], [5, -1, 0]], [17, 10, 4]),
+ ]
+
+ test_in = [(func_name+'(%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/lists_sum/en.py b/python/problems/functions_and_modules/lists_sum/en.py
new file mode 100644
index 0000000..12eaf0b
--- /dev/null
+++ b/python/problems/functions_and_modules/lists_sum/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 241
+name = 'Lists sum'
+slug = 'Lists sum'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/lists_sum/sl.py b/python/problems/functions_and_modules/lists_sum/sl.py
new file mode 100644
index 0000000..4baa002
--- /dev/null
+++ b/python/problems/functions_and_modules/lists_sum/sl.py
@@ -0,0 +1,35 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 241
+name = 'Vsota seznamov'
+slug = 'Vsota seznamov'
+
+
+description = '''\
+<p>
+Podan je seznam seznamov, npr. <code>[[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]]</code>.
+Napiši funkcijo <code>lists_sum(xxs)</code>, ki v seznamu vrne vsote vseh elementov v posameznih podseznamih.
+Za gornji seznam naj funkcija vrne seznam <code>[7, 4, 0, 10, 4]</code>, saj je, na primer, <code>2 + 4 + 1 = 7</code>.
+<pre>
+>>> lists_sum([[1, 1, 1], [1, 1]])
+[3, 2]
+>>> lists_sum([[2, 4, 1], [3, 1], [], [8, 2], [1, 1, 1, 1]])
+[7, 4, 0, 10, 4]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/longest_word/common.py b/python/problems/functions_and_modules/longest_word/common.py
new file mode 100644
index 0000000..b4fabc1
--- /dev/null
+++ b/python/problems/functions_and_modules/longest_word/common.py
@@ -0,0 +1,71 @@
+# 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 = 235
+number = 1
+visible = True
+
+solution = '''\
+def longest(s):
+ naj = ''
+ for beseda in s.split():
+ if len(beseda) > len(naj):
+ naj = beseda
+ return naj
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'longest'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ('beseda', 'beseda'),
+ ('an ban', 'ban'),
+ ('an ban pet podgan', 'podgan'),
+ ('an ban pet podgan stiri misi', 'podgan'),
+ ('ta clanek je lepo napisan', 'napisan'),
+ ('123456 12345 1234 123 12 1', '123456'),
+ ('12345 123456 12345 1234 123 12 1', '123456'),
+ ('1234 12345 123456 12345 1234 123 12 1', '123456'),
+ ]
+
+ test_in = [(func_name+'("%s")'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/longest_word/en.py b/python/problems/functions_and_modules/longest_word/en.py
new file mode 100644
index 0000000..7bd4dc2
--- /dev/null
+++ b/python/problems/functions_and_modules/longest_word/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 235
+name = 'Longest word'
+slug = 'Longest word'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/longest_word/sl.py b/python/problems/functions_and_modules/longest_word/sl.py
new file mode 100644
index 0000000..eb85509
--- /dev/null
+++ b/python/problems/functions_and_modules/longest_word/sl.py
@@ -0,0 +1,30 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 235
+name = 'Najdaljša beseda'
+slug = 'Najdaljša beseda'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>longest(s)</code>, ki vrne najdaljšo besedo v nizu <code>s</code>.
+<pre>
+>>> longest('an ban pet podgan')
+'podgan'
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/map/common.py b/python/problems/functions_and_modules/map/common.py
new file mode 100644
index 0000000..93ba8ac
--- /dev/null
+++ b/python/problems/functions_and_modules/map/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 = 245
+number = 11
+visible = True
+
+solution = '''\
+def map(f, xs):
+ ys = []
+ for x in xs:
+ ys.append(f(x))
+ return ys
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'map'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (('abs', [-5, 8, -3, -1, 3]), [5, 8, 3, 1, 3]),
+ (('len', 'Daydream delusion limousine eyelash'.split()), [8, 8, 9, 7]),
+ (('int', '1 3 5 42'.split()), [1, 3, 5, 42]),
+ ]
+
+ test_in = [(func_name+'({l[0]},{l[1]})'.format(l = l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/map/en.py b/python/problems/functions_and_modules/map/en.py
new file mode 100644
index 0000000..dcc1785
--- /dev/null
+++ b/python/problems/functions_and_modules/map/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 245
+name = 'Map'
+slug = 'Map'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/map/sl.py b/python/problems/functions_and_modules/map/sl.py
new file mode 100644
index 0000000..18c47fb
--- /dev/null
+++ b/python/problems/functions_and_modules/map/sl.py
@@ -0,0 +1,34 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 245
+name = 'Slikaj'
+slug = 'Slikaj'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>map(f, xs)</code>, ki sprejme funkcijo <code>f</code> in seznam <code>[x_1, x_2, ..., x_n]</code>
+in vrne nov seznam <code>[f(x_1), f(x_2), ..., f(x_n)]</code>.
+<pre>
+>>> map(abs, [-5, 8, -3, -1, 3])
+[5, 8, 3, 1, 3]
+>>> map(len, "Daydream delusion limousine eyelash".split())
+[8, 8, 9, 7]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/multiplicative_range/common.py b/python/problems/functions_and_modules/multiplicative_range/common.py
new file mode 100644
index 0000000..9b892e6
--- /dev/null
+++ b/python/problems/functions_and_modules/multiplicative_range/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 = 244
+number = 10
+visible = True
+
+solution = '''\
+def mrange(s, r, l):
+ xs = []
+ for i in range(l):
+ xs.append(s)
+ s *= r
+ return xs
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'mrange'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ((32, 2, 0), []),
+ ((32, 2, 1), [32]),
+ ((32, 2, 2), [32, 64]),
+ ((42, -1, 5), [42, -42, 42, -42, 42]),
+ ((7, 4, 7), [7, 28, 112, 448, 1792, 7168, 28672]),
+ ]
+
+ test_in = [(func_name+'(*%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/multiplicative_range/en.py b/python/problems/functions_and_modules/multiplicative_range/en.py
new file mode 100644
index 0000000..566ef5f
--- /dev/null
+++ b/python/problems/functions_and_modules/multiplicative_range/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 244
+name = 'Multiplicative range'
+slug = 'Multiplicative range'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/multiplicative_range/sl.py b/python/problems/functions_and_modules/multiplicative_range/sl.py
new file mode 100644
index 0000000..8bd4bd0
--- /dev/null
+++ b/python/problems/functions_and_modules/multiplicative_range/sl.py
@@ -0,0 +1,32 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 244
+name = 'Multiplikativni range'
+slug = 'Multiplikativni range'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>mrange(start, factor, length)</code>, ki vrne seznam, kjer je vsako naslednje število za
+<code>factor</code> večje od prejšnjega. Npr., v seznamu <code>[1, 2, 4, 8, 16]</code> je vsako naslednje število 2-krat večje od prejšnjega.
+<pre>
+>>> print(mrange(7, 4, 7))
+[7, 28, 112, 448, 1792, 7168, 28672]
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/similarity/common.py b/python/problems/functions_and_modules/similarity/common.py
new file mode 100644
index 0000000..3a6df99
--- /dev/null
+++ b/python/problems/functions_and_modules/similarity/common.py
@@ -0,0 +1,73 @@
+# 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 = 236
+number = 2
+visible = True
+
+solution = '''\
+def similarity(s1, s2):
+ stevec = 0
+ for i in range(min(len(s1), len(s2))):
+ if s1[i] == s2[i]:
+ stevec += 1
+ return stevec
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'similarity'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ (('sobota', 'robot'), 4),
+ (('', 'robot'), 0),
+ (('sobota', ''), 0),
+ (('', ''), 0),
+ (('a', 'b'), 0),
+ (('a', 'a'), 1),
+ (('aaa', 'a'), 1),
+ (('amper', 'amonijak'), 2),
+ (('1000 let', 'tisoc let'), 0),
+ (('hamming distance', 'haming distance'), 12)
+ ]
+
+ test_in = [(func_name+'(*%s)'%str(l[0]), None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/similarity/en.py b/python/problems/functions_and_modules/similarity/en.py
new file mode 100644
index 0000000..e1dc014
--- /dev/null
+++ b/python/problems/functions_and_modules/similarity/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 236
+name = 'Similarity'
+slug = 'Similarity'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/similarity/sl.py b/python/problems/functions_and_modules/similarity/sl.py
new file mode 100644
index 0000000..8aaf0b0
--- /dev/null
+++ b/python/problems/functions_and_modules/similarity/sl.py
@@ -0,0 +1,39 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 236
+name = 'Podobnost'
+slug = 'Podobnost'
+
+
+description = '''\
+<p>
+Napišite funkcijo <code>similarity(s1, s2)</code>, ki izračuna podobnost med dvema nizoma.
+Podobnost definirajmo kot število mest v katerih se niza ujemata.
+<pre>
+sobota
+robot
+------
+011110 -> 4
+
+>>> podobnost('sobota', 'robot')
+4
+>>> podobnost('robot', 'sobota')
+4
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/functions_and_modules/sl.py b/python/problems/functions_and_modules/sl.py
new file mode 100644
index 0000000..fb4f520
--- /dev/null
+++ b/python/problems/functions_and_modules/sl.py
@@ -0,0 +1,3 @@
+name = 'Funkcije in delo z moduli'
+description = 'Uporaba funkcij in delo z moduli (predvsem z nizi)'
+
diff --git a/python/problems/functions_and_modules/suspicious_words/common.py b/python/problems/functions_and_modules/suspicious_words/common.py
new file mode 100644
index 0000000..89c1a88
--- /dev/null
+++ b/python/problems/functions_and_modules/suspicious_words/common.py
@@ -0,0 +1,70 @@
+# 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 = 237
+number = 3
+visible = True
+
+solution = '''\
+def suspicious(s):
+ susp = []
+ for word in s.split():
+ if 'u' in word and 'a' in word:
+ susp.append(word)
+ return susp
+'''
+
+hint_type = {
+ 'final_hint': Hint('final_hint')
+}
+
+def test(python, code):
+ func_name = 'suspicious'
+ tokens = get_tokens(code)
+ if not has_token_sequence(tokens, ['def', func_name]):
+ return False, [{'id' : 'no_func_name', 'args' : {'func_name' : func_name}}]
+
+ in_out = [
+ ('', []),
+ ('aa uu', []),
+ ('aa uu au', ['au']),
+ ('muha', ['muha']),
+ ('Muha pa je rekla: "Tale juha se je pa res prilegla, najlepša huala," in odletela.',
+ ['Muha', 'juha', 'huala,"']),
+ ('ameba nima aja in uja, ampak samo a', ['uja,']),
+ ]
+
+ test_in = [(func_name+"('"+l[0]+"')", None) for l in in_out]
+ test_out = [l[1] for l in in_out]
+
+ answers = python(code=code, inputs=test_in, timeout=1.0)
+ n_correct = 0
+ tin, tout = None, None
+ for i, (ans, to) in enumerate(zip(answers, test_out)):
+ n_correct += ans[0] == to
+ if ans[0] != to:
+ tin = test_in[i][0]
+ tout = to
+
+ 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/functions_and_modules/suspicious_words/en.py b/python/problems/functions_and_modules/suspicious_words/en.py
new file mode 100644
index 0000000..9a406bf
--- /dev/null
+++ b/python/problems/functions_and_modules/suspicious_words/en.py
@@ -0,0 +1,16 @@
+# coding=utf-8
+
+id = 237
+name = 'Suspicious words'
+slug = 'Suspicious words'
+
+description = '''\
+<p>(translation missing)</p>'''
+
+hint = {
+ 'plan': '''\
+<p>(translation missing)</p>''',
+
+ 'no_input_call': '''\
+<p>(translation missing)</p>''',
+}
diff --git a/python/problems/functions_and_modules/suspicious_words/sl.py b/python/problems/functions_and_modules/suspicious_words/sl.py
new file mode 100644
index 0000000..3bf2c7b
--- /dev/null
+++ b/python/problems/functions_and_modules/suspicious_words/sl.py
@@ -0,0 +1,32 @@
+# coding=utf-8
+import server
+mod = server.problems.load_language('python', 'sl')
+
+
+id = 237
+name = 'Sumljive besede'
+slug = 'Sumljive besede'
+
+
+description = '''\
+<p>
+Napiši funkcijo <code>suspicious(s)</code>, ki vrne seznam vseh sumljivih besed v danem nizu.
+Beseda je sumljiva, če vsebuje tako črko u kot črko a.
+<pre>
+>>> susupicious('Muha pa je rekla: "Tale juha se je pa res prilegla, najlepša huala," in odletela.')
+['Muha', 'juha', 'huala,"']
+</pre>
+</p>'''
+
+plan = ['''\
+<p></p>
+''',
+ '''\
+<p></p>''']
+
+hint = {
+ 'final_hint': ['''\
+<p>Program je pravilen! <br>
+</p>
+'''],
+}
diff --git a/python/problems/introduction/average/common.py b/python/problems/introduction/average/common.py
index c61f7e6..28c7a7e 100644
--- a/python/problems/introduction/average/common.py
+++ b/python/problems/introduction/average/common.py
@@ -6,7 +6,6 @@ from server.hints import Hint
id = 189
-group = 'introduction'
number = 4
visible = True
diff --git a/python/problems/introduction/average/en.py b/python/problems/introduction/average/en.py
index 7742a7d..5ce621e 100644
--- a/python/problems/introduction/average/en.py
+++ b/python/problems/introduction/average/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 1000
name = 'Average grade'
slug = 'Average grade'
diff --git a/python/problems/introduction/average/sl.py b/python/problems/introduction/average/sl.py
index d7eafbb..540a9cc 100644
--- a/python/problems/introduction/average/sl.py
+++ b/python/problems/introduction/average/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 189
name = 'Povprečna ocena'
slug = 'Povprečna ocena'
diff --git a/python/problems/introduction/ballistics/common.py b/python/problems/introduction/ballistics/common.py
index afb84b6..8cb5c2d 100644
--- a/python/problems/introduction/ballistics/common.py
+++ b/python/problems/introduction/ballistics/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 187
-group = 'introduction'
number = 3
visible = True
diff --git a/python/problems/introduction/ballistics/en.py b/python/problems/introduction/ballistics/en.py
index 34dca8a..6fab80f 100644
--- a/python/problems/introduction/ballistics/en.py
+++ b/python/problems/introduction/ballistics/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 1000
name = 'Ballistics'
slug = 'Ballistics'
diff --git a/python/problems/introduction/ballistics/sl.py b/python/problems/introduction/ballistics/sl.py
index fa0fe5d..ee073f8 100644
--- a/python/problems/introduction/ballistics/sl.py
+++ b/python/problems/introduction/ballistics/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 187
name = 'Topologija'
slug = 'Topologija'
diff --git a/python/problems/introduction/common.py b/python/problems/introduction/common.py
new file mode 100644
index 0000000..8498d9c
--- /dev/null
+++ b/python/problems/introduction/common.py
@@ -0,0 +1,2 @@
+id = 13
+number = 1
diff --git a/python/problems/introduction/fahrenheit_to_celsius/common.py b/python/problems/introduction/fahrenheit_to_celsius/common.py
index 6549c32..10a1067 100644
--- a/python/problems/introduction/fahrenheit_to_celsius/common.py
+++ b/python/problems/introduction/fahrenheit_to_celsius/common.py
@@ -3,9 +3,9 @@
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
+import re
id = 180
-group = 'introduction'
number = 1
visible = True
@@ -87,6 +87,9 @@ def hint(python, code):
if not has_token_sequence(tokens, ['input']):
return [{'id': 'no_input_call'}]
+ if not re.findall(r'=[^\n]*?input', code):
+ return [{'id': 'no_input_call'}]
+
# if tokens * or / or = are not in code, we have to teach them how to
# evaluate expressions.
if (not has_token_sequence(tokens, ['/']) or
diff --git a/python/problems/introduction/fahrenheit_to_celsius/en.py b/python/problems/introduction/fahrenheit_to_celsius/en.py
index a2af212..5d7522e 100644
--- a/python/problems/introduction/fahrenheit_to_celsius/en.py
+++ b/python/problems/introduction/fahrenheit_to_celsius/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 180
name = 'Converting Fahrenheit to Celsius'
slug = 'Converting Fahrenheit to Celsius'
diff --git a/python/problems/introduction/fahrenheit_to_celsius/sl.py b/python/problems/introduction/fahrenheit_to_celsius/sl.py
index b61c436..f5ce4a4 100644
--- a/python/problems/introduction/fahrenheit_to_celsius/sl.py
+++ b/python/problems/introduction/fahrenheit_to_celsius/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 180
name = 'Pretvarjanje iz Fahrenheitov v Celzije'
slug = 'Pretvarjanje iz Fahrenheitov v Celzije'
@@ -12,7 +11,7 @@ stopinjah, program pa jo izpiše v Celzijevih. Med temperaturama pretvarjamo po
formuli C = 5/9 (F – 32).</p>'''
no_input_call = ['''\
-<p>Uporabnika nekaj vprašamo s funkcijo <code>input</code>.</p>''',
+<p>Uporabi funkcijo <code>input</code> in shrani rezultat.</p>''',
'''\
<p>Funkcija <code>input</code> sprejme niz (<em>angl.</em> string), ki se
prikaže uporabniku kot vprašanje in vrača, kar je uporabnik napisal. </p>''',
diff --git a/python/problems/introduction/fast_fingers/common.py b/python/problems/introduction/fast_fingers/common.py
index dc04dcf..754679d 100644
--- a/python/problems/introduction/fast_fingers/common.py
+++ b/python/problems/introduction/fast_fingers/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 190
-group = 'introduction'
number = 5
visible = True
diff --git a/python/problems/introduction/fast_fingers/en.py b/python/problems/introduction/fast_fingers/en.py
index de07494..ab4637a 100644
--- a/python/problems/introduction/fast_fingers/en.py
+++ b/python/problems/introduction/fast_fingers/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 1000
name = 'Fast fingers'
slug = 'Fast fingers'
diff --git a/python/problems/introduction/fast_fingers/sl.py b/python/problems/introduction/fast_fingers/sl.py
index 0b38a3a..c181951 100644
--- a/python/problems/introduction/fast_fingers/sl.py
+++ b/python/problems/introduction/fast_fingers/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 190
name = 'Hitri prsti'
slug = 'Hitri prsti'
diff --git a/python/problems/introduction/fast_fingers_2/common.py b/python/problems/introduction/fast_fingers_2/common.py
index af4439c..c738d45 100644
--- a/python/problems/introduction/fast_fingers_2/common.py
+++ b/python/problems/introduction/fast_fingers_2/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 191
-group = 'introduction'
number = 6
visible = True
diff --git a/python/problems/introduction/fast_fingers_2/en.py b/python/problems/introduction/fast_fingers_2/en.py
index 636f4d0..2172127 100644
--- a/python/problems/introduction/fast_fingers_2/en.py
+++ b/python/problems/introduction/fast_fingers_2/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 1000
name = 'Fast fingers 2'
slug = 'Fast fingers 2'
diff --git a/python/problems/introduction/fast_fingers_2/sl.py b/python/problems/introduction/fast_fingers_2/sl.py
index 125bd24..6606fbe 100644
--- a/python/problems/introduction/fast_fingers_2/sl.py
+++ b/python/problems/introduction/fast_fingers_2/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 191
name = 'Hitri prsti 2'
slug = 'Hitri prsti 2'
diff --git a/python/problems/introduction/pythagorean_theorem/common.py b/python/problems/introduction/pythagorean_theorem/common.py
index ed49b1a..cebae68 100644
--- a/python/problems/introduction/pythagorean_theorem/common.py
+++ b/python/problems/introduction/pythagorean_theorem/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 188
-group = 'introduction'
number = 2
visible = True
diff --git a/python/problems/introduction/pythagorean_theorem/en.py b/python/problems/introduction/pythagorean_theorem/en.py
index b3c6117..79d7e39 100644
--- a/python/problems/introduction/pythagorean_theorem/en.py
+++ b/python/problems/introduction/pythagorean_theorem/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 1000
name = 'Pythagorean theorem'
slug = 'Pythagorean theorem'
diff --git a/python/problems/introduction/pythagorean_theorem/sl.py b/python/problems/introduction/pythagorean_theorem/sl.py
index 21aec9a..9500651 100644
--- a/python/problems/introduction/pythagorean_theorem/sl.py
+++ b/python/problems/introduction/pythagorean_theorem/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 188
name = 'Pitagorov izrek'
slug = 'Pitagorov izrek'
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>
+'''],
+}
diff --git a/python/problems/while_and_if/buy_five/common.py b/python/problems/while_and_if/buy_five/common.py
index ba44f5b..a96b2b0 100644
--- a/python/problems/while_and_if/buy_five/common.py
+++ b/python/problems/while_and_if/buy_five/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 185
-group = 'while_and_if'
number = 1
visible = True
diff --git a/python/problems/while_and_if/buy_five/en.py b/python/problems/while_and_if/buy_five/en.py
index 7e522da..9ad1f06 100644
--- a/python/problems/while_and_if/buy_five/en.py
+++ b/python/problems/while_and_if/buy_five/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 185
name = 'Buy five'
slug = 'Buy five'
diff --git a/python/problems/while_and_if/buy_five/sl.py b/python/problems/while_and_if/buy_five/sl.py
index 22fa7b4..3dbc9d3 100644
--- a/python/problems/while_and_if/buy_five/sl.py
+++ b/python/problems/while_and_if/buy_five/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 185
name = 'Blagajna "vse po pet"'
slug = 'Blagajna "vse po pet"'
@@ -22,7 +21,7 @@ Vsota: 16
'''
bad_solution = ['''\
-<p><b>Primer, kako NE reševati</b></h3>
+<p>Primer, kako NE reševati</h3>
<pre>
cena1 = float(input('Cena artikla: '))
cena2 = float(input('Cena artikla: '))
@@ -36,7 +35,7 @@ print ("Vsota: " + vsota)
<p>Rešitev je slaba, saj imamo pet enakih vrstic! Uporabite zanko! </p>''']
main_plan = ['''\
-<p><b>Plan:</b></p>
+<p>Plan:</p>
<pre>
1. Ponavljaj 5x:
2. Preberi ceno.
@@ -45,9 +44,9 @@ main_plan = ['''\
</pre>''']
while_clause = ['''\
-<p>Kako bi nekaj <b>5x ponovil</b>?</p>''',
+<p>Uporabi zanko <code>while</code>.</p>''',
'''\
-<p>Zanka while ima naslednjo sintakso:</p>
+<p>Zanka <code>while</code> ima naslednjo sintakso:</p>
<pre>
while Pogoj:
stavek 1
@@ -62,7 +61,7 @@ našem primeru s stavkom n.</p>'''
]
reading_while = ['''\
-<p>Za <b>večkratno branje</b> želimo uporabiti zanko</p>''',
+<p>Za večkratno branje želimo uporabiti zanko</p>''',
'''\
<pre>
@@ -94,7 +93,7 @@ while stevec < 5:
''']
summation = ['''\
-<p><b>Računanje vsote</b> bo najlažje sproti v zanki. <p>''',
+<p>Računaj vsoto sproti v zanki. <p>''',
'''\
<p>Izmisli si spremenljivko, ki bo predstavljala vsoto, jo na
diff --git a/python/problems/while_and_if/checking_account/common.py b/python/problems/while_and_if/checking_account/common.py
index ee1e3ee..002003f 100644
--- a/python/problems/while_and_if/checking_account/common.py
+++ b/python/problems/while_and_if/checking_account/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 200
-group = 'while_and_if'
number = 5
visible = True
diff --git a/python/problems/while_and_if/checking_account/en.py b/python/problems/while_and_if/checking_account/en.py
index 1d36474..47633e8 100644
--- a/python/problems/while_and_if/checking_account/en.py
+++ b/python/problems/while_and_if/checking_account/en.py
@@ -1,8 +1,8 @@
# coding=utf-8
id = 199
-name = 'Checking Account'
-slug = 'Checking Account'
+name = 'Checking account'
+slug = 'Checking account'
description = '''\
<p>(translation missing)</p>'''
diff --git a/python/problems/while_and_if/checking_account/sl.py b/python/problems/while_and_if/checking_account/sl.py
index 2825431..86f973b 100644
--- a/python/problems/while_and_if/checking_account/sl.py
+++ b/python/problems/while_and_if/checking_account/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 200
name = 'Tekoči račun'
slug = 'Tekoči račun'
@@ -11,7 +10,7 @@ description = '''\
<p>Državna agencija za varstvo potrošnikov je razpisala projekt za izdelavo programa, s katerimi bodo
lahko potrošniki nadzorovali svoje tekoče račune. V program uporabniki vtipkavajo prejemke in
izdatke (kot pozitivne in negativne zneske) na svojem tekočem računu. Program jim sproti izpisuje
-stanje in se ustavi, ko je uporabnik v minusu za 100 evrov ali več.</p>
+stanje in se ustavi, ko je uporabnik v minusu za 100 evrov ali več. Takrat naj program izpiše "Bankrot". </p>
<pre>
Sprememba 23
Stanje 23
@@ -32,7 +31,7 @@ Bankrot
'''
main_plan = ['''\
-<p><b>Plan</b></p> je enak kot pri prejšnjih nalogah, le vsebina je drugačna:
+<p>Plan je enak kot pri prejšnjih nalogah, le vsebina je drugačna:
<pre>
1.Ponavljaj dokler ni bankrot
2.Preberi ceno
diff --git a/python/problems/while_and_if/common.py b/python/problems/while_and_if/common.py
new file mode 100644
index 0000000..c4071df
--- /dev/null
+++ b/python/problems/while_and_if/common.py
@@ -0,0 +1,2 @@
+id = 14
+number = 2 \ No newline at end of file
diff --git a/python/problems/while_and_if/competition/common.py b/python/problems/while_and_if/competition/common.py
index fff96ed..8d2c098 100644
--- a/python/problems/while_and_if/competition/common.py
+++ b/python/problems/while_and_if/competition/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 192
-group = 'while_and_if'
number = 2
visible = True
diff --git a/python/problems/while_and_if/competition/en.py b/python/problems/while_and_if/competition/en.py
index f6399a2..215665c 100644
--- a/python/problems/while_and_if/competition/en.py
+++ b/python/problems/while_and_if/competition/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 185
name = 'Competition'
slug = 'Competition'
diff --git a/python/problems/while_and_if/competition/sl.py b/python/problems/while_and_if/competition/sl.py
index 8d01ad4..195b51f 100644
--- a/python/problems/while_and_if/competition/sl.py
+++ b/python/problems/while_and_if/competition/sl.py
@@ -3,7 +3,6 @@ import server
mod = server.problems.load_language('python', 'sl')
-id = 192
name = 'Blagajna "konkurenca"'
slug = 'Blagajna "konkurenca"'
@@ -21,7 +20,7 @@ Vsota: 7
</pre>
'''
main_plan = ['''\
-<p><b>Plan</b> bo enak kot pri prejšnji nalogi,
+<p>Plan bo enak kot pri prejšnji nalogi,
le število ponavljanj se spremeni. </p>''',
'''\
<pre>
@@ -35,7 +34,7 @@ plan = [main_plan]
while_clause = ['''\
-<p>Kako bi <b>prebral 5 cen</b> z uporabo zanke while?</p>''',
+<p>Kako bi prebral N cen z uporabo zanke while?</p>''',
'''\
<p>Zanka while ima naslednjo sintakso:</p>
<pre>
@@ -52,7 +51,7 @@ našem primeru s stavkom n.</p>'''
]
summation = ['''\
-<p><b>Računanje vsote</b> bo najlažje sproti v zanki. <p>''',
+<p>Računaj vsoto sproti v zanki. <p>''',
'''\
<p>Izmisli si spremenljivko, ki bo predstavljala vsoto, jo na
diff --git a/python/problems/while_and_if/consumers_anonymous/common.py b/python/problems/while_and_if/consumers_anonymous/common.py
index 07a0ebf..895d985 100644
--- a/python/problems/while_and_if/consumers_anonymous/common.py
+++ b/python/problems/while_and_if/consumers_anonymous/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 201
-group = 'while_and_if'
number = 6
visible = True
@@ -111,7 +110,7 @@ def hint(python, code):
return [{'id' : 'printing'}]
# student does not print any values
- if not get_numbers(answer[0][1]):
+ if len(get_numbers(answer[0][1])) < 2:
return [{'id' : 'nonumber'}]
# student's answer is not correct (three possibilities)
diff --git a/python/problems/while_and_if/consumers_anonymous/en.py b/python/problems/while_and_if/consumers_anonymous/en.py
index 6331570..9691ac2 100644
--- a/python/problems/while_and_if/consumers_anonymous/en.py
+++ b/python/problems/while_and_if/consumers_anonymous/en.py
@@ -3,8 +3,8 @@ import server
mod = server.problems.load_language('python', 'sl')
id = 201
-name = 'Consumers Anonymous'
-slug = 'Consumers Anonymous'
+name = 'Consumers anonymous'
+slug = 'Consumers anonymous'
description = '''\
<p>(translation missing)</p>'''
diff --git a/python/problems/while_and_if/consumers_anonymous/sl.py b/python/problems/while_and_if/consumers_anonymous/sl.py
index 284abbc..131a13b 100644
--- a/python/problems/while_and_if/consumers_anonymous/sl.py
+++ b/python/problems/while_and_if/consumers_anonymous/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 201
name = 'Klub anonimnih potrošnikov'
slug = 'Klub anonimnih potrošnikov'
@@ -46,17 +45,17 @@ Porabili boste 10 evrov za 10 stvari.
'''
main_plan = ['''\
-<p><b>Plan</b> je enak kot pri prejšnjih nalogah: while zanka + izpis števca in vsote. </p>
+<p>Plan je enak kot pri prejšnjih nalogah: while zanka + izpis števca in vsote. </p>
''']
while_condition = ['''\
-<p><b>Pogoj</b> v zanki while bo sestavljen iz več pogojev.</p>''',
+<p>Pogoj v zanki <code>while</code> bo sestavljen iz več pogojev.</p>''',
'''\
<p>V Pythonu združujemo pogoje z logičnimi operatoriji <code>and</code>,
<code>or</code> in <code>not</code></p>'''
'''\
<p>Zanka se ustavi, če presežemo 100 EUR, če smo vpisali 0 ali kupili 10 stvari.
-Vendar pazite: napisati moramo pogoj, kdaj se zanka <b>nadaljuje</b>!</p>''',
+Vendar pazite: napisati moramo pogoj, kdaj se zanka nadaljuje!</p>''',
'''\
<pre>
cena != 0 and vsota < 100 and artiklov < 10
@@ -110,10 +109,10 @@ hint = {
Pravilna vsota [%=sum%], pravilno število stvari: [%=count%]'''],
'final_hint': ['''\
-<p><b>Odlično!</b> Naloga rešena.</p>
+<p>Odlično! Naloga rešena.<br>
Še zanimivost: v while zanki smo dobili ustavitveni pogoj tako, da smo negirali pogoj iz teksta (ali vnesemo 0 ali je
vnešenih deset števil ali ko vsota cen doseže ali preseže 100 evrov). Pri tem smo ali (or) spremenili v in (and):
-<code>cena > 0 and stevec < 10 and vsota < 100</code>. Temu pravimo De Morganov zakon.
+<code>cena > 0 and stevec < 10 and vsota < 100</code>. Temu pravimo De Morganov zakon.</p>
'''],
'eof_error':[mod.general_msg['eof_error'],
diff --git a/python/problems/while_and_if/minimax/common.py b/python/problems/while_and_if/minimax/common.py
index 71632b7..d853058 100644
--- a/python/problems/while_and_if/minimax/common.py
+++ b/python/problems/while_and_if/minimax/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 199
-group = 'while_and_if'
number = 4
visible = True
@@ -60,7 +59,7 @@ def test(python, code):
n_correct = 0
tin = None
for i, (output, correct) in enumerate(zip(outputs, test_out)):
- if all(string_almost_equal(output, correct[i]) for i in range(4)):
+ if all(string_almost_equal(output, correct[i], prec=2) for i in range(4)):
n_correct += 1
else:
tin = test_in[i][1]
diff --git a/python/problems/while_and_if/minimax/en.py b/python/problems/while_and_if/minimax/en.py
index 10689ec..2aee417 100644
--- a/python/problems/while_and_if/minimax/en.py
+++ b/python/problems/while_and_if/minimax/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 200
name = 'Minimax'
slug = 'Minimax'
diff --git a/python/problems/while_and_if/minimax/sl.py b/python/problems/while_and_if/minimax/sl.py
index a76bd2e..0d934b8 100644
--- a/python/problems/while_and_if/minimax/sl.py
+++ b/python/problems/while_and_if/minimax/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 199
name = 'Blagajna "minimax"'
slug = 'Blagajna "minimax"'
@@ -22,7 +21,7 @@ Najvišja cena: 4
'''
main_plan = ['''\
-<p><b>Plan:</b></p>
+<p>Plan:</p>
<pre>
1. Ponavljaj dokler je cena večja od 0:
2. Preberi ceno.
diff --git a/python/problems/while_and_if/top_shop/common.py b/python/problems/while_and_if/top_shop/common.py
index 115dc9e..02855ec 100644
--- a/python/problems/while_and_if/top_shop/common.py
+++ b/python/problems/while_and_if/top_shop/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint
id = 198
-group = 'while_and_if'
number = 3
visible = True
@@ -55,7 +54,7 @@ def test(python, code):
n_correct = 0
tin = None
for i, (output, correct) in enumerate(zip(outputs, test_out)):
- if all(string_almost_equal(output, correct[i]) for i in range(2)):
+ if all(string_almost_equal(output, correct[i], prec=2) for i in range(2)):
n_correct += 1
else:
tin = test_in[i][1]
diff --git a/python/problems/while_and_if/top_shop/en.py b/python/problems/while_and_if/top_shop/en.py
index a69ae9a..b8e5119 100644
--- a/python/problems/while_and_if/top_shop/en.py
+++ b/python/problems/while_and_if/top_shop/en.py
@@ -1,6 +1,5 @@
# coding=utf-8
-id = 198
name = 'Top shop'
slug = 'Top shop'
diff --git a/python/problems/while_and_if/top_shop/sl.py b/python/problems/while_and_if/top_shop/sl.py
index ee9d02d..334736c 100644
--- a/python/problems/while_and_if/top_shop/sl.py
+++ b/python/problems/while_and_if/top_shop/sl.py
@@ -2,7 +2,6 @@
import server
mod = server.problems.load_language('python', 'sl')
-id = 198
name = 'Blagajna "top shop"'
slug = 'Blagajna "top shop"'
@@ -24,7 +23,7 @@ Poprečna cena: 2.33333333333
'''
main_plan = ['''\
-<p><b>Plan:</b></p>
+<p>Plan:</p>
<pre>
1. Ponavljaj dokler je cena večja od 0:
2. Preberi ceno.
@@ -94,7 +93,8 @@ while cena != 0:
...'''],
'final_hint': ['''\
-<p><b>Odlično!</b> Kaj bi pa moral narediti, da bi število -1 pomenilo konec?</p>''',
+<p>Odlično, program je pravilen! <br>
+Kaj bi pa moral narediti, da bi število -1 pomenilo konec?</p>''',
'''\
<p>Spremeniti pogoj in paziti,
da se vrednost -1 ne prišteje vsoti!</p>'''],
diff --git a/python/sl.py b/python/sl.py
index af06db9..f9870fc 100644
--- a/python/sl.py
+++ b/python/sl.py
@@ -29,10 +29,14 @@ Npr., sešteti niz in število ali klicati funkcijo, čeprav tisto ni funkcija,
<p>Poskušaš prebrati preveč vrednosti.</p>''',
'timed_out':'''\
-<p>Program se izvaja predolgo.</p>'''
+<p>Program se izvaja predolgo.</p>''',
+
+ 'modulo':'''\
+<p>Ostanek pri deljenju dobimo z operatorjem %. </p>''',
}
+
hint = {
'no_hint': ['''\
<p>Namig ne obstaja.</p>
@@ -57,7 +61,7 @@ pravilen rezultat: [%=testout%]</p>
'''],
'no_func_name': ['''\
-<p>Funkcija z imenom [%=func_name%] ni definirana. </p>
+<p>Funkcija z imenom <code>[%=func_name%]</code> ni definirana. </p>
'''],
'syntax_error': ['''\
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..ec26acd
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,28 @@
+The file hierarchy for problem data is below. Comments indicate the global
+variables and functions that can be defined in each file. Only the ID is
+necessary. See existing problems for examples.
+
+<language>
+├── common.py # id, hint_type, hint() [language-specific]
+├── en.py # name, description, hint [language-specific]
+├── sl.py # name, description, hint [language-specific]
+└── problems
+    └── <group>
+ ├── common.py # id, number
+ ├── en.py # name, description
+ ├── sl.py # name, description
+    └── <problem>
+       ├── common.py # id, number, test(), hint_type, hint() [problem-specific]
+       ├── en.py # name, plan, hint [problem-specific]
+       └── sl.py # name, plan, hint [problem-specific]
+
+To add a problem, create the necessary files. Pick an unused problem ID from
+the relevant range below:
+
+ Prolog: 10000-19999
+ Python: 20000-29999
+ Robot: 30000-39999
+
+Running scripts/build_web_resources.py in the codeq-server repo will generate
+JSON files for all problems, and insert new problems, groups and languages in
+the database.
diff --git a/robot/common.py b/robot/common.py
index 45dbfc3..1e7e818 100644
--- a/robot/common.py
+++ b/robot/common.py
@@ -2,6 +2,8 @@
from server.hints import Hint, HintSequence
+id = 3
+
hint_type = {
'no_hint': Hint('no_hint'),
'system_error': Hint('system_error'),
diff --git a/robot/problems/introduction/common.py b/robot/problems/introduction/common.py
new file mode 100644
index 0000000..8498d9c
--- /dev/null
+++ b/robot/problems/introduction/common.py
@@ -0,0 +1,2 @@
+id = 13
+number = 1
diff --git a/robot/problems/introduction/forward/common.py b/robot/problems/introduction/forward/common.py
index d1e1193..f6330fd 100644
--- a/robot/problems/introduction/forward/common.py
+++ b/robot/problems/introduction/forward/common.py
@@ -5,7 +5,6 @@ from python.util import has_token_sequence, string_almost_equal, \
from server.hints import Hint, HintSequence
id = 202
-group = 'introduction'
number = 1
visible = True
diff --git a/robot/problems/introduction/forward/en.py b/robot/problems/introduction/forward/en.py
index f8e1730..be73921 100644
--- a/robot/problems/introduction/forward/en.py
+++ b/robot/problems/introduction/forward/en.py
@@ -1,8 +1,5 @@
# coding=utf-8
-import server
-mod = server.problems.load_language('python', 'en')
-id = 202
name = 'Forward 3s'
slug = 'Forward 3s'
diff --git a/robot/problems/introduction/forward/sl.py b/robot/problems/introduction/forward/sl.py
index 9a37b3c..837380b 100644
--- a/robot/problems/introduction/forward/sl.py
+++ b/robot/problems/introduction/forward/sl.py
@@ -1,8 +1,5 @@
# coding=utf-8
-import server
-mod = server.problems.load_language('python', 'sl')
-id = 202
name = 'Naprej 3s'
slug = 'Naprej 3s'