[+] TT1
This commit is contained in:
Executable
+137
@@ -0,0 +1,137 @@
|
||||
"""CSC110 Fall 2021: Term Test 1, Question 1 (Function Design)
|
||||
|
||||
Module Description
|
||||
==================
|
||||
This Python file contains instructions for this question. There are THREE
|
||||
parts of this question, labelled "Part (a)", "Part (b)", etc.
|
||||
The comments in this file contain instructions on how to complete each part,
|
||||
so please read those comments carefully.
|
||||
|
||||
At the bottom of the file we've provided code to run doctest, pytest, and python_ta.
|
||||
python_ta is not required for grading.
|
||||
|
||||
SUBMIT THIS FILE FOR GRADING!
|
||||
|
||||
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 Mario Badr and Tom Fairgrieve.
|
||||
"""
|
||||
|
||||
from hypothesis import given
|
||||
from hypothesis.strategies import integers, tuples
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (a)
|
||||
####################################################################################################
|
||||
# Here is a definition:
|
||||
#
|
||||
# Let p be a 3-item tuple of the form (a, b, c) where a, b and c are positive integers.
|
||||
# We say that p is a Pythagorean triple whenever c squared is equal to the sum of a squared plus b
|
||||
# squared.
|
||||
# For example, p = (3, 4, 5) is a Pythagorean triple because 25 = 9 + 16.
|
||||
#
|
||||
# Use the Function Design Recipe to define a function is_pythagorean_triple that returns
|
||||
# whether a given 3-item tuple is a Pythagorean triple. You need to write:
|
||||
#
|
||||
# 1. A precondition (as a Python expression) expressing that the items in p are positive integers.
|
||||
# 2. TWO different doctest examples.
|
||||
# 3. A correct function body.
|
||||
|
||||
|
||||
def is_pythagorean_triple(p: tuple[int, int, int]) -> bool:
|
||||
"""Return whether p is a Pythagorean triple.
|
||||
|
||||
Preconditions:
|
||||
- all(n > 0 for n in p)
|
||||
|
||||
>>> is_pythagorean_triple((3, 4, 5))
|
||||
True
|
||||
>>> is_pythagorean_triple((1, 1, 2))
|
||||
False
|
||||
"""
|
||||
a, b, c = p
|
||||
return (c ** 2) == a ** 2 + b ** 2
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (b)
|
||||
####################################################################################################
|
||||
# Here is another definition:
|
||||
#
|
||||
# Let L be a list where every item is a tuple of three positive integers that we will call (a,b,c).
|
||||
# We say that L is a *Pythagorean list* when every item in the list is a Pythagorean triple.
|
||||
# An empty list is NOT considered to be a Pythagorean triple.
|
||||
#
|
||||
# Use the Function Design Recipe to define a function is_pythagorean_list that returns
|
||||
# whether a given list is a Pythagorean list. You need to write:
|
||||
#
|
||||
# 1. A precondition (as a Python expression) expressing that every item in list lst is a tuple that
|
||||
# contains positive integers.
|
||||
# 2. TWO different doctest examples.
|
||||
# 3. A correct function body that uses a comprehension and any/all.
|
||||
# You must call is_pythagorean_triple in this function, and you may NOT use loops.
|
||||
|
||||
|
||||
def is_pythagorean_list(lst: list[tuple[int, int, int]]) -> bool:
|
||||
"""Return whether lst is a Pythagorean list.
|
||||
|
||||
Preconditions:
|
||||
- all(n > 0 for t in lst for n in t)
|
||||
|
||||
>>> is_pythagorean_list([])
|
||||
False
|
||||
>>> is_pythagorean_list([(3, 4, 5), (6, 8, 10)])
|
||||
True
|
||||
"""
|
||||
if len(lst) == 0:
|
||||
return False
|
||||
return all(is_pythagorean_triple(n) for n in lst)
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (c)
|
||||
####################################################################################################
|
||||
# Consider the following property:
|
||||
#
|
||||
# For all positive integers a, b, c and k,
|
||||
# if p = (a, b, c) is a Pythagorean triple then (k*a, k*b, k*c) is also a Pythagorean triple.
|
||||
#
|
||||
# Complete the property-based test below to express this property.
|
||||
# We have started it for you; you only need to fill in the body of the test.
|
||||
|
||||
|
||||
@given(p=tuples(integers(min_value=1), integers(min_value=1), integers(min_value=1)),
|
||||
k=integers(min_value=1))
|
||||
def test_multiplier_pyth_triple(p: tuple[int, int, int], k: int) -> None:
|
||||
"""Test the multiplier property of Pythagorean triples."""
|
||||
if is_pythagorean_triple(p):
|
||||
a, b, c = p
|
||||
assert is_pythagorean_triple((k * a, k * b, k * c))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta.contracts
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
# You can uncomment this to check your test in Part (c).
|
||||
import pytest
|
||||
pytest.main(['q1.py'])
|
||||
|
||||
import python_ta
|
||||
python_ta.check_all(config={
|
||||
'disable': ['R1729', 'C0412'],
|
||||
'extra-imports': ['python_ta.contracts', 'hypothesis.strategies'],
|
||||
'max-line-length': 100
|
||||
})
|
||||
Binary file not shown.
Executable
+92
@@ -0,0 +1,92 @@
|
||||
% 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 Mario Badr and Tom Fairgrieve.
|
||||
\documentclass{article}
|
||||
|
||||
\setlength{\parindent}{0pt}
|
||||
\setlength{\parskip}{5pt}
|
||||
|
||||
\usepackage[margin=1in]{geometry}
|
||||
|
||||
\title{CSC110 Fall 2021: Term Test 1, Question 2 (Predicate Logic)}
|
||||
\author{Azalea Gui}
|
||||
\date{Wednesday October 20, 2021}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
Let $A$ be the set of all animals and all plants.
|
||||
Suppose we define the following predicates:
|
||||
|
||||
\begin{itemize}
|
||||
\item $Plant(x):$ ``$x$ is a plant", where $x \in A$.
|
||||
\item $Omnivore(x):$ ``$x$ is an omnivore", where $x \in A$.
|
||||
\item $Herbivore(x):$ ``$x$ is a herbivore", where $x \in A$.
|
||||
\item $IsColourful(x):$ ``$x$ is colourful", where $x \in A$.
|
||||
\item $Eats(x, y):$ ``$x$ eats $y$", where $x, y \in A$.
|
||||
\end{itemize}
|
||||
(An omnivore is an animal that eats food of both plant and animal origin.
|
||||
A herbivore is an animal that only eats plants.)
|
||||
|
||||
For parts (1) to (3), translate each of the following statements from English into symbolic predicate logic.
|
||||
In part (4), you will translate an English statement into Python code.
|
||||
|
||||
No explanation is necessary.
|
||||
Do not define any of your own predicates or sets.
|
||||
|
||||
Use parentheses to indicate how you want to group logical expressions with multiple operators (especially when dealing with $\Rightarrow$ and $\Leftrightarrow$).
|
||||
|
||||
\begin{enumerate}
|
||||
\item
|
||||
At least one plant is colourful.
|
||||
|
||||
\textbf{Solution}:
|
||||
|
||||
$\exists x \in A$ s.t. $Plant(x) \land IsColourful(x)$
|
||||
|
||||
\item
|
||||
Omnivores eat any animal or plant.
|
||||
|
||||
\textbf{Solution}:
|
||||
|
||||
$\forall x, y \in A$, $Omnivore(x) \Rightarrow Eats(x, y)$
|
||||
|
||||
\item
|
||||
At least one herbivore does not eat colourful plants.
|
||||
|
||||
\textbf{Solution}:
|
||||
|
||||
$\exists x \in A$, $\forall y \in A$, $Herbivore(x) \land ((IsColorful(y) \land Plant(y)) \Rightarrow \neg Eats(x, y))$
|
||||
|
||||
\item
|
||||
Suppose we define the following in Python:
|
||||
\begin{itemize}
|
||||
\item A variable \texttt{animals\_and\_plants} which represents a set of animals and plants.
|
||||
\item Functions \texttt{is\_herbivore} and \texttt{eats} that take in argument values from \texttt{animals\_and\_plants}, and correspond to the predicates $Herbivore$ and $Eats$, respectively, defined at the top of this question.
|
||||
\item A variable \texttt{brussel\_sprouts} that refers to the plant brussel sprouts. (Note: \texttt{brussel\_sprouts in animals\_and\_plants} is True)
|
||||
\end{itemize}
|
||||
|
||||
Using these definitions, translate the following statement into a Python expression:
|
||||
\begin{quote}
|
||||
All herbivores eat brussel sprouts.
|
||||
\end{quote}
|
||||
|
||||
You must use a comprehension in your solution, and may not use any loops.
|
||||
|
||||
\begin{verbatim}
|
||||
all([eats(x, brussel_sprouts) for x in animals_and_plants if is_herbivore(x)])
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
\begin{center}
|
||||
\textbf{SUBMIT THIS FILE AND THE GENERATED PDF q2.pdf FOR GRADING}
|
||||
\end{center}
|
||||
\end{enumerate}
|
||||
\end{document}
|
||||
Executable
+247
@@ -0,0 +1,247 @@
|
||||
"""CSC110 Fall 2021: Term Test 1, Q3
|
||||
|
||||
Module Description
|
||||
==================
|
||||
This Python file contains instructions for this question. There are FOUR
|
||||
parts of this question, labelled "Part (a)", "Part (b)", etc.
|
||||
The docstrings in this file contain instructions on how to complete each part,
|
||||
so please read those comments carefully.
|
||||
|
||||
python_ta is not required for grading.
|
||||
|
||||
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 Mario Badr and Tom Fairgrieve.
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (a)
|
||||
####################################################################################################
|
||||
def create_nested_list_data() -> list[list]:
|
||||
"""Return a small dataset in a nested list format.
|
||||
|
||||
Each nested list is composed of items with type: str, str, float, in that order.
|
||||
- The first str is the title (i.e., name) of a book
|
||||
- The second str is the name of the author
|
||||
- the float is the average rating for the book
|
||||
|
||||
INSTRUCTIONS: Do NOT change this function.
|
||||
"""
|
||||
return [
|
||||
['Shogun', 'James Clavell', 4.39],
|
||||
['1984', 'George Orwell', 4.4],
|
||||
['Animal Farm', 'George Orwell', 3.96],
|
||||
['The Ex Hex', 'Erin Sterling', 3.76]
|
||||
]
|
||||
|
||||
|
||||
def comma_separated_titles(data: list[list]) -> str:
|
||||
"""Return a string of the book titles in data in the order that they appear, where each title
|
||||
ends with a comma and a space (i.e., ', ').
|
||||
|
||||
Preconditions:
|
||||
- data is in the format as specified in create_nested_list_data
|
||||
|
||||
INSTRUCTIONS: Complete the body of this function. You must follow the docstring description
|
||||
exactly. Do NOT add any more doctest examples.
|
||||
|
||||
RESTRICTIONS:
|
||||
- You must use a for loop
|
||||
- You may not use any comprehensions
|
||||
- You may not use any built-in functions/methods
|
||||
|
||||
>>> example_data = create_nested_list_data()
|
||||
>>> comma_separated_titles(example_data)
|
||||
'Shogun, 1984, Animal Farm, The Ex Hex, '
|
||||
"""
|
||||
csv = ""
|
||||
for entry in data:
|
||||
csv += entry[0] + ', '
|
||||
return csv
|
||||
|
||||
|
||||
def reset_ratings(data: list[list], author: str) -> None:
|
||||
"""Reset (i.e., MUTATE) the ratings of all books by author in data to 0.0.
|
||||
|
||||
Preconditions:
|
||||
- data is in the format as specified in create_nested_list_data
|
||||
|
||||
INSTRUCTIONS: Complete the body of this function and add ONE doctest example that demonstrates
|
||||
what the function does.
|
||||
|
||||
RESTRICTIONS:
|
||||
- You must use a for loop
|
||||
- You may not use any comprehensions
|
||||
- You may not use any built-in functions/methods
|
||||
|
||||
>>> example_data = create_nested_list_data()
|
||||
>>> reset_ratings(example_data, 'George Orwell')
|
||||
>>> example_data[1][2] == 0.0 and example_data[2][2] == 0.0
|
||||
True
|
||||
"""
|
||||
for entry in data:
|
||||
if entry[1] == author:
|
||||
entry[2] = 0.0
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (b)
|
||||
####################################################################################################
|
||||
def has_valid_ratings(data: list[list]) -> bool:
|
||||
"""Return whether every rating in data is a valid rating.
|
||||
|
||||
A valid rating is a rating between 0.0 and 5.0, inclusive.
|
||||
|
||||
Preconditions:
|
||||
- data is in the format as specified in create_nested_list_data
|
||||
- len(data) > 0
|
||||
|
||||
INSTRUCTIONS: Do NOT change this function. We know that it contains at least one bug.
|
||||
"""
|
||||
for book in data:
|
||||
if 0.0 <= book[2] <= 5.0:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def test_has_valid_ratings() -> None:
|
||||
"""Test has_valid_ratings (see instructions).
|
||||
|
||||
INSTRUCTIONS: There is at least one bug in has_valid_ratings. Complete the body of this UNIT
|
||||
TEST so that it demonstrates a bug. That is, this unit test should fail when run on
|
||||
has_valid_ratings.
|
||||
|
||||
RESTRICTIONS:
|
||||
- You may not use hypothesis
|
||||
- You may not violate the function's preconditions (including the type contract)
|
||||
"""
|
||||
data = create_nested_list_data()
|
||||
assert has_valid_ratings(data)
|
||||
|
||||
|
||||
def has_valid_ratings_bug() -> str:
|
||||
"""Return a BRIEF English description of the bug you found in has_valid_ratings.
|
||||
|
||||
INSTRUCTIONS: Complete the body of this function so that it returns your description of the
|
||||
bug in a single string.
|
||||
|
||||
RESTRICTIONS:
|
||||
- Your description must be less than 200 characters (i.e.,
|
||||
len(has_valid_ratings_bug()) < 200)
|
||||
"""
|
||||
return "The body should not return False when it found a valid rating (between 0 and 5), it should return false when it found an invalid rating instead."
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (c)
|
||||
####################################################################################################
|
||||
@dataclass
|
||||
class Book:
|
||||
"""A data class that represents a book at Indigo.
|
||||
|
||||
INSTRUCTIONS: Do NOT change this dataclass.
|
||||
|
||||
Instance Attributes:
|
||||
- title: the title (or name) of the book
|
||||
- author: the name of the author of the book
|
||||
- rating: the average rating of the book
|
||||
|
||||
Representation Invariants:
|
||||
- self.title != ''
|
||||
- self.author != ''
|
||||
- self.rating >= 0.0
|
||||
|
||||
>>> some_book = Book('1984', 'George Orwell', 4.4)
|
||||
"""
|
||||
title: str
|
||||
author: str
|
||||
rating: float
|
||||
|
||||
|
||||
def create_dataclass_data() -> list[Book]:
|
||||
"""Return a small dataset in a list of dataclass format.
|
||||
|
||||
INSTRUCTIONS: Do NOT change this function.
|
||||
"""
|
||||
return [
|
||||
Book('Shogun', 'James Clavell', 4.39),
|
||||
Book('1984', 'George Orwell', 4.4),
|
||||
Book('Animal Farm', 'George Orwell', 3.96),
|
||||
Book('The Ex Hex', 'Erin Sterling', 3.76)
|
||||
]
|
||||
|
||||
|
||||
def collect_ll_authors(data: list[Book]) -> set[str]:
|
||||
"""Return the set of all author names in data where the author name contains two adjacent
|
||||
lowercase l's (i.e., 'll').
|
||||
|
||||
INSTRUCTIONS: Complete the body of this function and add ONE doctest example that demonstrates
|
||||
what the function does.
|
||||
|
||||
RESTRICTIONS:
|
||||
- You must use a for loop
|
||||
- You may not use any comprehensions
|
||||
- You may not use any built-in functions/methods, EXCEPT FOR: set.add
|
||||
|
||||
>>> example_data = create_dataclass_data()
|
||||
>>> collect_ll_authors(example_data) == {'James Clavell', 'George Orwell'}
|
||||
True
|
||||
"""
|
||||
ll_authors = set()
|
||||
for entry in data:
|
||||
if 'll' in entry.author:
|
||||
ll_authors.add(entry.author)
|
||||
return ll_authors
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# Part (d)
|
||||
####################################################################################################
|
||||
def add_book_titles(titles: list[str], data: list[Book], author: str) -> None:
|
||||
"""Add (i.e., MUTATE) to titles, in the order that they appear, the names of the books from data
|
||||
that are written by author.
|
||||
|
||||
INSTRUCTIONS: Do NOT change this function. We know that it contains at least one bug.
|
||||
"""
|
||||
for book in data:
|
||||
if book.author == author:
|
||||
titles = titles + [book.title]
|
||||
|
||||
|
||||
def test_add_book_titles() -> None:
|
||||
"""Test add_book_titles.
|
||||
|
||||
INSTRUCTIONS: There is at least one bug in add_book_titles. Complete the body of this UNIT
|
||||
TEST so that it demonstrates a bug. That is, this unit test should fail when run on
|
||||
add_book_titles.
|
||||
|
||||
RESTRICTIONS:
|
||||
- You may not use hypothesis
|
||||
- You may not violate the function's preconditions (including the type contract)
|
||||
"""
|
||||
titles: list[str] = []
|
||||
data = create_dataclass_data()
|
||||
add_book_titles(titles, data, 'George Orwell')
|
||||
assert titles == ['1984', 'Animal Farm']
|
||||
|
||||
|
||||
def add_book_titles_bug() -> str:
|
||||
"""Return a BRIEF English description of the bug you found in add_book_titles.
|
||||
|
||||
INSTRUCTIONS: Complete the body of this function so that it returns your description of the
|
||||
bug in a single string.
|
||||
|
||||
RESTRICTIONS:
|
||||
- Your description must be less than 200 characters (i.e., len(add_book_titles_bug()) < 200)
|
||||
"""
|
||||
return "The docstring said that it should mutate the titles list, but it did not mutate the list. It created a new list each time a matching author is found. It should use list.append instead."
|
||||
Reference in New Issue
Block a user