This commit is contained in:
Hykilpikonna
2021-10-25 19:28:37 -04:00
parent 39244cd577
commit ab875a0898
4 changed files with 476 additions and 0 deletions
Executable
+137
View File
@@ -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
})
BIN
View File
Binary file not shown.
Executable
+92
View File
@@ -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
View File
@@ -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."