174 lines
5.5 KiB
Python
Executable File
174 lines
5.5 KiB
Python
Executable File
"""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'])
|