From 39244cd5771a0e1b5475698d27592a52b816c029 Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Wed, 13 Oct 2021 15:45:46 -0400 Subject: [PATCH] [+] Prep6 --- practice/prep6.py | 173 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100755 practice/prep6.py diff --git a/practice/prep6.py b/practice/prep6.py new file mode 100755 index 0000000..3967e67 --- /dev/null +++ b/practice/prep6.py @@ -0,0 +1,173 @@ +"""CSC110 Fall 2021 Prep 6: Programming Exercises + +Instructions (READ THIS FIRST!) +=============================== + +This Python module contains several function headers and descriptions. +We have marked each place you need to fill in with the word "TODO". +As you complete your work in this file, delete each TODO comment---this is a +good habit to get into early! + +Copyright and Usage Information +=============================== + +This file is provided solely for the personal and private use of students +taking CSC110 at the University of Toronto St. George campus. All forms of +distribution of this code, whether as given or with any changes, are +expressly prohibited. For more information on copyright for CSC110 materials, +please consult our Course Syllabus. + +This file is Copyright (c) 2021 David Liu, Mario Badr, and Tom Fairgrieve. +""" +import math + +from hypothesis import given +from hypothesis.strategies import integers + + +#################################################################################################### +# Mutation practice (from Week 5) +#################################################################################################### +def only_evens(lst: list[list[int]]) -> list[list[int]]: + """Return a new list of the lists in lst that contain only even integers. + + Use a for loop with a list accumulator, and use mutating operations to update + the accumulator in the loop body. + + >>> only_evens([[1, 2, 4], [4, 0, 6], [22, 4, 3], [2]]) + [[4, 0, 6], [2]] + """ + # Accumulator + evens = [] + for one_list in lst: + if all(n % 2 == 0 for n in one_list): + evens.append(one_list) + return evens + + +def get_order_quantities(table_orders: dict[str, list[str]]) -> dict[str, int]: + """Return a mapping from food item to the number of that item ordered. + + In the input dictionary table_orders: + - Each key is the name of a person. + - Each corresponding value is a list of the food items that person has ordered. + Duplicates are allowed! + + In the returned dictionary: + - Each key a a food item. + - Each corresponding value is the number of times that food item was ordered + in table_orders, across all people. + + Use a for loop with a dictionary accumulator, and use mutating operations to update + the accumulator in the loop body. + + >>> orders = {'David': ['Vegetarian stew', 'Poutine', 'Vegetarian stew'],\ + 'Mario': ['Steak pie', 'Poutine', 'Vegetarian stew'],\ + 'Jen': ['Steak pie', 'Steak pie']} + >>> get_order_quantities(orders) == {'Vegetarian stew': 3, 'Poutine': 2, 'Steak pie': 3} + True + """ + # Accumulator + quantities = {} + for key in table_orders: + for item in table_orders[key]: + if item not in quantities: + quantities[item] = 0 + quantities[item] += 1 + return quantities + + +#################################################################################################### +# Number theory +#################################################################################################### +def is_coprime(m: int, n: int) -> bool: + """Return whether m and n are coprime (review the reading for the definition of coprime). + + Hints: + - Use the math module's gcd function to calculate the gcd of two numbers. + + >>> is_coprime(3, 7) + True + >>> is_coprime(3, 9) + False + """ + return math.gcd(m, n) == 1 + + +def find_gcd(numbers: set[int]) -> int: + """Return the greatest common divisor of all the given numbers. + + Preconditions: + - len(numbers) >= 2 + + Hints: + - Use the math module's gcd function to calculate the gcd of two numbers. + - Use an accumulator to store the gcd of the numbers seen so far. + - For all ints x, gcd(x, 0) = x. + - For all ints a, b, c, the gcd of all three numbers is equal to gcd((gcd(a, b), c). + That is, you can calculate the gcd of a and b first, then calculate the gcd of + that number and c. + + >>> find_gcd({18, 12}) + 6 + >>> find_gcd({121, 99, -11, 0}) + 11 + """ + temp = numbers.copy() + gcd = temp.pop() + for n in temp: + gcd = math.gcd(gcd, n) + return gcd + + +def equivalent_mod(a: int, b: int, n: int) -> bool: + """Return whether a is equivalent to b modulo n. + + You can compute this by comparing remainders. + + Preconditions: + - n >= 1 + + >>> equivalent_mod(10, 66, 4) # Both have remainder 2 + True + >>> equivalent_mod(13, 19, 5) + False + """ + return a % n == b % n + + +@given(a=integers(), n=integers(min_value=1)) +def test_equivalence_reflexive(a: int, n: int) -> None: + """Test that a is equivalent to a modulo n. + + (This property holds for all ints a and n, if n > 1.) + """ + assert equivalent_mod(a, a, n) + + +@given(a=integers(), b=integers(), n=integers(min_value=1)) +def test_equivalence_add_multiples(a: int, b: int, n: int) -> None: + """Test that a is equivalent to (a + bn) modulo n. + + (This property holds for all ints a, b, and n, if n > 1.) + """ + assert equivalent_mod(a, a + b * n, n) + + +if __name__ == '__main__': + import python_ta + python_ta.check_all(config={ + 'max-line-length': 100, + 'extra-imports': ['math', 'python_ta.contracts', 'hypothesis.strategies'], + 'disable': ['R1705', 'W1114'] + }) + + import python_ta.contracts + python_ta.contracts.DEBUG_CONTRACTS = False + python_ta.contracts.check_all_contracts() + + import doctest + doctest.testmod(verbose=True) + + import pytest + pytest.main(['prep6.py'])