Merge branch 'main' of https://github.com/hykilpikonna/CSC110
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
\documentclass[fontsize=11pt]{article}
|
||||
\usepackage{amsmath}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[margin=0.75in]{geometry}
|
||||
|
||||
\title{CSC110 Assignment 3: Loops, Mutation, and Applications}
|
||||
\author{Azalea Gui \& Peter Lin}
|
||||
\date{\today}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
|
||||
\section*{Part 1: Text generation, uniformly random model}
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item[1.]
|
||||
\begin{enumerate}
|
||||
\item[(a)]
|
||||
TODO: Complete the table below (you will need to add more rows).
|
||||
|
||||
You may find this tutorial useful: https://www.overleaf.com/learn/latex/Tables.
|
||||
|
||||
\begin{tabular}{|l|l|l|l|}
|
||||
\hline
|
||||
Iteration & \verb|word| & \verb|words| & \verb|word_frequencies|\\
|
||||
\hline
|
||||
0 & N/A & \texttt{[]} & \texttt{[]} \\
|
||||
1 & \texttt{'Hello'} & \texttt{['Hello']} & \texttt{[2]} \\
|
||||
2 & \texttt{'Amy'} & \texttt{['Hello', 'Amy']} & \texttt{[2, 1]} \\
|
||||
3 & \texttt{'was'} & \texttt{['Hello', 'Amy', 'was']} & \texttt{[2, 1, 1]} \\
|
||||
4 & \texttt{'here'} & \texttt{['Hello', 'Amy', 'was', 'here']} & \texttt{[2, 1, 1, 1]} \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
|
||||
\item[(b)]
|
||||
Including a specific example as the doctest's expected output when a function is random isn't a good idea because the function's output will be different from the expected output each time it is executed. Since the doctest only verifies if the actual output matches the expected output, specifying a single random outcome as the expected output among many other possibilities will likely produce an error when running the test.
|
||||
|
||||
\item[(c)]
|
||||
For example, you can use $\texttt{words = \{'Hello': 1\}}$ as the words dictionary. In this case, \texttt{generate\_text\_uniform(words, 5)} has only one possible outcome, which is \texttt{'Hello Hello Hello Hello Hello'}, so we can use that as our statement and expected output in the doctest.
|
||||
\end{enumerate}
|
||||
|
||||
\item[2.]
|
||||
Complete this part in the provided \texttt{a3\_part1.py} starter file.
|
||||
Do \textbf{not} include your solution in this file.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
\newpage
|
||||
|
||||
\section*{Part 2: Text generation, One-Word Context Model}
|
||||
|
||||
\begin{enumerate}
|
||||
|
||||
\item[0.]
|
||||
This question is not to be handed in.
|
||||
|
||||
\item[1.]
|
||||
One-word context model:
|
||||
|
||||
\begin{verbatim}
|
||||
# TODO: Write your one-word context model here as a Python value.
|
||||
# Write each key-value pair on a separate line, like on the assignment handout.
|
||||
{
|
||||
'Love': ['is', 'is'],
|
||||
'is': ['patient.', 'kind.', 'not'],
|
||||
'patient.': ['Love'],
|
||||
'kind.': ['It'],
|
||||
'It': ['does', 'does', 'is'],
|
||||
'does': ['not', 'not'],
|
||||
'not': ['envy.', 'boast.', 'proud.'],
|
||||
'envy.': ['It'],
|
||||
'boast.': ['It']
|
||||
}
|
||||
\end{verbatim}
|
||||
|
||||
\item[2.]
|
||||
Complete this part in the provided \texttt{a3\_part2.py} starter file.
|
||||
Do \textbf{not} include your solution in this file.
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
\newpage
|
||||
|
||||
\section*{Part 3: Loops and Mutation Debugging Exercise}
|
||||
|
||||
\begin{enumerate}
|
||||
\item[1.]
|
||||
The test \texttt{test\_star\_wars} passed, and the tests
|
||||
\texttt{test\_legally\_blonde} and \texttt{test\_transformers} failed.
|
||||
|
||||
\item[2.]
|
||||
\begin{enumerate}
|
||||
\item[i.] The test \texttt{test\_legally\_blonde} failed because of a mistake in the funtion \texttt{clean\_text}. Since string values are not mutable, and the function \texttt{str.lower(str)} does not mutate the string, \texttt{str.lower(text)} did not convert the words in the string to lower case but created a new string with lower-cased letters of the original string instead. However, since the result of \texttt{str.lower(text)}, the new lower-cased string, wasn't stored back into text, the string value in the variable text is not lower-cased. Since the non-lower-cased string is used when processing the words, some of the words could not be matched to the VADER intensities dictionary, and they were not counted in the intensity calculation even though they should be counted.
|
||||
\item[ii.] The test \texttt{test\_transformers} failed because of a mistake in the function \texttt{count\_keywords}. It should loop through the word list, find words that have VADER intensity data, and create a dictionary of the number of occurences of these words. When creating the dictionary, it uses an accumulator \texttt{occurences\_so\_far}. The keys of the dictionary represent these words and the values represent the number of times these words appear. When a new word \texttt{word} is found that isn't in the accumulator, it should initialize \texttt{occurences\_so\_far[word]} to 1, and when a word \texttt{word} that's already in the accumulator is found, it should add one to \texttt{occurences\_so\_far[word]}. The given code completed the first part (initializing the counts of new words to 1) correctly, but it didn't add one when existing words are detected, so the returned result always reported one occurence for each word when some words actually appeared multiple times. Since the reported word occurences were incorrect, the calculated intensity were multiplied by potentially the wrong amount, which lead to the incorrect intensity.
|
||||
\end{enumerate}
|
||||
|
||||
\item[3.]
|
||||
The test \texttt{test\_star\_wars} passed because the review did not contain repeating or non-lower-cased words. The review text only contains three words that are in the small subset of the VADAR lexicon used in the program: \textit{magnificent} , \textit{adventure} , and \textit{succeeded}. The problem in 2.i didn't affect this text because these three words are all already lower-cased, and the problem in 2.ii didn't affect this text because these three words all appeared only once in the text.
|
||||
\end{enumerate}
|
||||
|
||||
\section*{Part 4: Forest Fires}
|
||||
|
||||
\begin{enumerate}
|
||||
\item[1.]
|
||||
Complete this part in the provided \texttt{a3\_part4.py} starter file.
|
||||
Do \textbf{not} include your solution in this file.
|
||||
|
||||
\item[2.]
|
||||
Complete this part in the provided \texttt{a3\_part4\_tests.py} starter file.
|
||||
Do \textbf{not} include your solution in this file.
|
||||
|
||||
\item[3.]
|
||||
|
||||
\begin{enumerate}
|
||||
\item[a.]
|
||||
TODO: Write your answer here.
|
||||
|
||||
\item [b.]
|
||||
TODO: Write your answer here.
|
||||
|
||||
\item[c.]
|
||||
TODO: Write your answer here.
|
||||
\end{enumerate}
|
||||
|
||||
\end{enumerate}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,291 @@
|
||||
"""CSC110 Fall 2021 Assignment 3: Forest Fire Weather Index System
|
||||
|
||||
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.
|
||||
"""
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
|
||||
# Initial values that can be used for FFMC, DMC, and DC
|
||||
INITIAL_FFMC = 85.0
|
||||
INITIAL_DMC = 6.0
|
||||
INITIAL_DC = 15.0
|
||||
|
||||
# Per-month lookup tables
|
||||
DMC_DAY_LENGTH_EFFECTIVE = {
|
||||
1: 6.5, 2: 7.5, 3: 9.0, 4: 12.8, 5: 13.9, 6: 13.9,
|
||||
7: 12.4, 8: 10.9, 9: 9.4, 10: 8.0, 11: 7.0, 12: 6.0
|
||||
}
|
||||
DC_DAY_LENGTH_FACTORS = {
|
||||
1: -1.6, 2: -1.6, 3: -1.6, 4: 0.9, 5: 3.8, 6: 5.8,
|
||||
7: 6.4, 8: 5.0, 9: 2.4, 10: 0.4, 11: -1.6, 12: -1.6
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class WeatherMetrics:
|
||||
"""A bundle of metrics that are measured by weather stations.
|
||||
|
||||
Instance Attributes:
|
||||
- month: The month of the year (e.g., January is 1, December is 12)
|
||||
- day: the day of the month
|
||||
- temperature: The noon temperature in degrees Celsius
|
||||
- humidity: The noon relative humidity, in %
|
||||
- wind_speed: The noon wind speed, in km/h
|
||||
- precipitation: The rainfall at noon, in mm
|
||||
|
||||
Representation Invariants:
|
||||
- self.month in {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
|
||||
- self.humidity >= 0.0
|
||||
- self.wind_speed >= 0.0
|
||||
- self.precipitation >= 0.0
|
||||
"""
|
||||
month: int
|
||||
day: int
|
||||
temperature: float
|
||||
humidity: float
|
||||
wind_speed: float
|
||||
precipitation: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class FfwiOutput:
|
||||
"""A bundle of the output metrics in the Canadian Forest Fire Weather Index System.
|
||||
|
||||
Instance Attributes:
|
||||
- ffmc: the Fine Fuel Moisture Code
|
||||
- dmc: the Duff Moisture Code
|
||||
- dc: the Drought Code
|
||||
- isi: the Initial Spread Index
|
||||
- bui: the Buildup Index
|
||||
- fwi: the Fire Weather Index
|
||||
|
||||
Representation Invariants:
|
||||
- 0.0 <= self.ffmc <= 101.0
|
||||
- self.dmc >= 1.0
|
||||
- self.bui >= 0.0
|
||||
"""
|
||||
ffmc: float
|
||||
dmc: float
|
||||
dc: float
|
||||
isi: float
|
||||
bui: float
|
||||
fwi: float
|
||||
|
||||
|
||||
def calculate_mr(precipitation: float, mo: float) -> float:
|
||||
"""Return the fine fuel moisture content after rain (mr) based on the effective
|
||||
rainfall in precipitation and the fine fuel moisture content from the previous day.
|
||||
|
||||
Preconditions:
|
||||
- precipitation > 0.5
|
||||
"""
|
||||
# Equation 2
|
||||
rf = precipitation - 0.5
|
||||
|
||||
if mo > 150.0:
|
||||
# Equation 3b
|
||||
mr = (mo + 42.5 * rf * math.exp(-100.0 / (251.0 - mo)) * (1.0 - math.exp(-6.93 / rf))) + (
|
||||
0.0015 * (mo - 150.0) ** 2) * math.sqrt(rf)
|
||||
else:
|
||||
# Equation 3a
|
||||
mr = mo + 42.5 * rf * math.exp(-100.0 / (251.0 - mo)) * (1.0 - math.exp(-6.93 / rf))
|
||||
|
||||
return mr
|
||||
|
||||
|
||||
def calculate_m(wm: WeatherMetrics, ed: float, mo: float) -> float:
|
||||
"""Return the fine fuel moisture content after drying (m) based on the measurements in wm, the
|
||||
EMC for drying in ed, and the fine fuel moisture content from the previous day in mo.
|
||||
|
||||
Preconditions:
|
||||
- mo <= 250.0
|
||||
"""
|
||||
if mo == ed:
|
||||
return mo
|
||||
|
||||
if mo < ed:
|
||||
# Equation 5
|
||||
ew = 0.618 * (wm.humidity ** .753) + (10.0 * math.exp((wm.humidity - 100.0) / 10.0)) \
|
||||
+ 0.18 * (21.1 - wm.temperature) * (1.0 - 1.0 / math.exp(0.115 * wm.humidity))
|
||||
|
||||
if mo <= ew:
|
||||
# Use log wetting rate
|
||||
# Equation 7a
|
||||
k1 = 0.424 * (1.0 - ((100.0 - wm.humidity) / 100.0) ** 1.7) + \
|
||||
(.0694 * math.sqrt(wm.wind_speed)) * (1.0 - ((100.0 - wm.humidity) / 100.0) ** 8)
|
||||
kw = k1 * (0.581 * math.exp(0.0365 * wm.temperature)) # Equation 7b
|
||||
return ew - (ew - mo) / 10.0 ** kw # Equation 9
|
||||
else:
|
||||
return mo
|
||||
|
||||
# Use log drying rate
|
||||
# Equation 6a
|
||||
k0 = 0.424 * (1.0 - (wm.humidity / 100.0) ** 1.7) + (
|
||||
(0.0694 * math.sqrt(wm.wind_speed)) * (1.0 - (wm.humidity / 100.0) ** 8))
|
||||
kd = k0 * (0.581 * math.exp(0.0365 * wm.temperature)) # Equation 6b
|
||||
m = ed + (mo - ed) / 10.0 ** kd # Equation 8
|
||||
|
||||
return m
|
||||
|
||||
|
||||
def calculate_ffmc(wm: WeatherMetrics, f0: float) -> float:
|
||||
"""Return the Fine Fuel Moisture Code (FFMC) based on the measurements in wm and the previous
|
||||
day's FFMC in f0.
|
||||
"""
|
||||
# Calculate the fine fuel moisture content from the previous day
|
||||
mo = (147.2 * (101.0 - f0)) / (59.5 + f0) # Equation 1
|
||||
if wm.precipitation > 0.5:
|
||||
mo = calculate_mr(wm.precipitation, mo)
|
||||
|
||||
if mo > 250.0:
|
||||
mo = 250.0
|
||||
|
||||
# Equation 4 - Fine Fuel equilibrium moisture content (EMC) for drying
|
||||
ed = 0.942 * (wm.humidity ** .679) + (11.0 * math.exp((wm.humidity - 100.0) / 10.0)) + (
|
||||
0.18 * (21.1 - wm.temperature) * (1.0 - 1.0 / math.exp(0.1150 * wm.humidity)))
|
||||
|
||||
m = calculate_m(wm, ed, mo)
|
||||
|
||||
# Equation 10
|
||||
f = (59.5 * (250.0 - m)) / (147.2 + m)
|
||||
|
||||
if f > 101.0:
|
||||
f = 101.0
|
||||
elif f <= 0.0:
|
||||
f = 0.0
|
||||
|
||||
return f
|
||||
|
||||
|
||||
def calculate_dmr(precipitation: float, dm0: float) -> float:
|
||||
"""Calculate the Duff moisture content after rain based on the current precipitation and the
|
||||
previous day's DMC in dm0.
|
||||
|
||||
Preconditions:
|
||||
- precipitation > 1.5
|
||||
"""
|
||||
rw = 0.92 * precipitation - 1.27 # Equation 11
|
||||
wmi = 20.0 + 280.0 / math.exp(0.023 * dm0) # Equation 12
|
||||
|
||||
if dm0 <= 33.0:
|
||||
b = 100.0 / (0.5 + 0.3 * dm0) # Equation 13a
|
||||
else:
|
||||
if dm0 <= 65.0:
|
||||
b = 14.0 - 1.3 * math.log(dm0) # Equation 13b
|
||||
else:
|
||||
b = 6.2 * math.log(dm0) - 17.2 # Equation 13c
|
||||
|
||||
return wmi + (1000 * rw) / (48.77 + b * rw) # Equation 14
|
||||
|
||||
|
||||
def calculate_dmc_k(temperature: float, humidity: float, month: int) -> float:
|
||||
"""Return the log drying rate in DMC based on the temperature, humidity, and month."""
|
||||
if temperature < -1.1:
|
||||
# Cannot use temperatures less than -1.1 in Equation 16
|
||||
temperature = -1.1
|
||||
|
||||
# Equations 16 and 17
|
||||
return 1.894 * (temperature + 1.1) * (100.0 - humidity) * (
|
||||
DMC_DAY_LENGTH_EFFECTIVE[month] * 0.0001)
|
||||
|
||||
|
||||
def calculate_dmc(wm: WeatherMetrics, dm0: float) -> float:
|
||||
"""Return the Duff Moisture Code (DMC) based on the measurements in wm and the previous day's
|
||||
DMC in dm0.
|
||||
"""
|
||||
if wm.precipitation <= 1.5:
|
||||
pr = dm0
|
||||
else:
|
||||
dmr = calculate_dmr(wm.precipitation, dm0)
|
||||
pr = 43.43 * (5.6348 - math.log(dmr - 20.0)) # Equation 15
|
||||
|
||||
# The DMC after rain cannot, theoretically, be less than 0; ensure it is at least 0
|
||||
pr = max(0.0, pr)
|
||||
|
||||
rk = calculate_dmc_k(wm.temperature, wm.humidity, wm.month)
|
||||
d = pr + rk
|
||||
|
||||
if d <= 1.0:
|
||||
d = 1.0
|
||||
return d
|
||||
|
||||
|
||||
def calculate_qr(precipitation: float, dc0: float) -> float:
|
||||
"""Return the moisture equivalent after rain based on the current precipitation and the
|
||||
previous day's DC in dc0.
|
||||
|
||||
Preconditions:
|
||||
- precipitation > 2.8
|
||||
"""
|
||||
rd = 0.83 * precipitation - 1.27 # Equation 18
|
||||
qo = 800.0 * math.exp(-dc0 / 400.0) # Equation 19
|
||||
qr = qo + 3.937 * rd # Equation 20
|
||||
|
||||
return qr
|
||||
|
||||
|
||||
def calculate_dc(wm: WeatherMetrics, dc0: float) -> float:
|
||||
"""Return the Drought Code (DC) based on the measurements in wm and the previous day's DC in
|
||||
dc0.
|
||||
"""
|
||||
temperature = wm.temperature
|
||||
if wm.temperature < -2.8:
|
||||
temperature = -2.8
|
||||
|
||||
v = 0.36 * (temperature + 2.8) + DC_DAY_LENGTH_FACTORS[wm.month] # Equation 22
|
||||
# The potential evapotranspiration cannot, theoretically, be less than 0; ensure it's at least 0
|
||||
v = max(0.0, v)
|
||||
|
||||
if wm.precipitation > 2.8:
|
||||
qr = calculate_qr(wm.precipitation, dc0)
|
||||
dr = 400 * math.log(800 / qr) # Equation 21
|
||||
return dr + 0.5 * v # Equation 23
|
||||
else:
|
||||
return dc0 + 0.5 * v # Equation 23
|
||||
|
||||
|
||||
def calculate_isi(wm: WeatherMetrics, ffmc: float) -> float:
|
||||
"""Return the Initial Spread Index (ISI) based on the measurements in wm and the current ffmc.
|
||||
"""
|
||||
mo = 147.2 * (101.0 - ffmc) / (59.5 + ffmc)
|
||||
ff = 19.115 * math.exp(mo * -0.1386) * (1.0 + (mo ** 5.31) / 49300000.0)
|
||||
|
||||
return ff * math.exp(0.05039 * wm.wind_speed)
|
||||
|
||||
|
||||
def calculate_bui(dmc: float, dc: float) -> float:
|
||||
"""Return the Buildup Index (BUI) based on the current dmc and the current dc.
|
||||
"""
|
||||
if dmc <= 0.4 * dc:
|
||||
b = (0.8 * dc * dmc) / (dmc + 0.4 * dc)
|
||||
else:
|
||||
b = dmc - (1.0 - 0.8 * dc / (dmc + 0.4 * dc)) * (0.92 + (0.0114 * dmc) ** 1.7)
|
||||
|
||||
if b < 0.0:
|
||||
b = 0.0
|
||||
|
||||
return b
|
||||
|
||||
|
||||
def calculate_fwi(isi: float, bui: float) -> float:
|
||||
"""Return the Fire Weather Index (FWI) based on the current isi and the current bui.
|
||||
"""
|
||||
if bui <= 80.0:
|
||||
f_d = 0.626 * bui ** 0.809 + 2.0 # Equation 28a
|
||||
else:
|
||||
f_d = 1000.0 / (25. + 108.64 * math.exp(-0.023 * bui)) # Equation 28b
|
||||
|
||||
bb = 0.1 * isi * f_d # Equation 29
|
||||
if bb <= 1.0:
|
||||
return bb # Equation 30b
|
||||
else:
|
||||
return math.exp(2.72 * (0.434 * math.log(bb)) ** 0.647) # Equation 30a
|
||||
@@ -0,0 +1,94 @@
|
||||
"""CSC110 Fall 2021 Assignment 3, Part 1: Text Generation, Uniformly Random Model (SOLUTIONS)
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
Implement each of the functions in this file. As usual, do not change any function headers
|
||||
or preconditions. You do NOT need to add doctests.
|
||||
|
||||
You may create some additional helper functions to help break up your code into smaller parts.
|
||||
|
||||
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.
|
||||
"""
|
||||
import random
|
||||
|
||||
|
||||
def generate_text_uniform(model: dict[str, int], n: int) -> str:
|
||||
"""Return a string of n randomly-generated words chosen from the given model.
|
||||
|
||||
Each word in the returned string is separated by a single space.
|
||||
|
||||
Preconditions:
|
||||
- n >= 0
|
||||
- model != {}
|
||||
"""
|
||||
# Unpack model into two lists whose indexes correspond to one another
|
||||
words = []
|
||||
word_frequencies = []
|
||||
for word in model:
|
||||
words.append(word)
|
||||
word_frequencies.append(model[word])
|
||||
|
||||
new_words = random.choices(words, weights=word_frequencies, k=n)
|
||||
return str.join(' ', new_words)
|
||||
|
||||
|
||||
def create_model_uniform(text: str) -> dict[str, int]:
|
||||
"""Return a model of the words in text.
|
||||
|
||||
The model is a mapping of words to the number of times the word occurs in text. A "word"
|
||||
contains no spaces.
|
||||
|
||||
This function should return model that is valid input to generate_text_uniform.
|
||||
|
||||
Preconditions:
|
||||
- text != ''
|
||||
|
||||
IMPLEMENTATION NOTE: Use the str.split method to get a list of words.
|
||||
"""
|
||||
words = text.split()
|
||||
return {unique: words.count(unique) for unique in set(words)}
|
||||
|
||||
|
||||
def run_example(filename: str, num_words: int) -> str:
|
||||
"""Run an example to demonstrate random text generation with num_words words based on the data
|
||||
in filename.
|
||||
|
||||
To call this function:
|
||||
- Make sure you see that the 'data' folder is in the same directory as this file
|
||||
- Use an argument for filename like: 'data/texts/sample_text_raw.txt'
|
||||
- Try out the other plaintext files in 'data/texts', too
|
||||
"""
|
||||
with open(filename) as f:
|
||||
file_text = f.read()
|
||||
|
||||
stripped_text = str.strip(file_text) # str.strip removes leading/trailing whitespace
|
||||
model_from_file = create_model_uniform(stripped_text)
|
||||
generated_words = generate_text_uniform(model_from_file, num_words)
|
||||
|
||||
return generated_words
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta
|
||||
import python_ta.contracts
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
|
||||
# When you are ready to check your work with python_ta, uncomment the following lines.
|
||||
# (Delete the "#" and space before each line.)
|
||||
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
|
||||
python_ta.check_all(config={
|
||||
'allowed-io': ['run_example'],
|
||||
'extra-imports': ['python_ta.contracts', 'random'],
|
||||
'max-line-length': 100,
|
||||
'disable': ['R1705', 'C0200']
|
||||
})
|
||||
@@ -0,0 +1,161 @@
|
||||
"""CSC110 Fall 2021 Assignment 3, Part 2: Text Generation, One-Word Context Model (SOLUTIONS)
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
Implement each of the functions in this file. As usual, do not change any function headers
|
||||
or preconditions. You do NOT need to add doctests.
|
||||
|
||||
You may create some additional helper functions to help break up your code into smaller parts.
|
||||
|
||||
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.
|
||||
"""
|
||||
import random
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Question 2
|
||||
###############################################################################
|
||||
def update_follow_list(model: dict[str, list[str]], word: str, follow_word: str) -> None:
|
||||
"""Add follow_word and, when applicable, word to model.
|
||||
|
||||
If word is not already present in model, add it to the model with the follow list
|
||||
[follow_word]. Otherwise, add follow_word to the follow list of word.
|
||||
"""
|
||||
if word not in model:
|
||||
model[word] = []
|
||||
model[word].append(follow_word)
|
||||
|
||||
|
||||
def create_model_owc(text: str) -> tuple[int, dict[str, list[str]]]:
|
||||
"""Return a tuple of the number of words in text and one-word context model of the given text,
|
||||
as described in the handout.
|
||||
|
||||
Your implementation MUST use the update_follow_list helper function. We recommend completing
|
||||
that function first, as it's simpler and will get you thinking about how to use it here.
|
||||
|
||||
Preconditions:
|
||||
- text != ''
|
||||
- len(str.split(text)) > 1
|
||||
"""
|
||||
words = text.split()
|
||||
model: dict[str, list[str]] = {}
|
||||
|
||||
for i in range(1, len(words)):
|
||||
update_follow_list(model, words[i - 1], words[i])
|
||||
|
||||
return len(words), model
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Question 3
|
||||
###############################################################################
|
||||
def choose_from_keys(transitions: dict[str, list[str]]) -> str:
|
||||
"""Return a random key from transitions.
|
||||
|
||||
Preconditions:
|
||||
- transitions != {}
|
||||
"""
|
||||
return random.choice(list(transitions.keys()))
|
||||
|
||||
|
||||
def choose_from_follow_list(key: str, transitions: dict[str, list[str]]) -> str:
|
||||
"""Return a random word from the follow list in transitions that is associated with key.
|
||||
|
||||
Also remove one occurrence of the random word from the follow list. If the follow list is then
|
||||
empty, remove the key-value pair from transitions.
|
||||
|
||||
Preconditions:
|
||||
- transitions != {}
|
||||
- key in transitions
|
||||
- transitions[key] != []
|
||||
"""
|
||||
word = random.choice(transitions[key])
|
||||
transitions[key].remove(word)
|
||||
|
||||
if len(transitions[key]) == 0:
|
||||
del transitions[key]
|
||||
|
||||
return word
|
||||
|
||||
|
||||
def generate_text_owc(count: int, transitions: dict[str, list[str]]) -> str:
|
||||
"""Return a string containing (count - 1) randomly generated words based on the data in
|
||||
transitions, which maps words to a list of words that follow it.
|
||||
|
||||
A randomly generated word is selected from the keys of transitions when:
|
||||
- it is the first word; or
|
||||
- the last randomly generated word is not a key in transitions.
|
||||
|
||||
A randomly generated word is selected from the follow list of a key in transitions when the
|
||||
last randomly generated word is a key in transitions. In addition, one occurrence of the word
|
||||
selected from the follow list is removed from the follow list (i.e., mutation). When there are
|
||||
no words in the follow list for a key, the key-value pair is also removed from transitions
|
||||
(i.e., mutation).
|
||||
|
||||
Your implementation MUST use the helper functions: choose_from_keys and choose_from_follow_list.
|
||||
We recommend completing these functions first, as they simpler and will get you thinking about
|
||||
how to use it here.
|
||||
|
||||
Preconditions:
|
||||
- model is in the format described by the assignment handout
|
||||
"""
|
||||
# ACCUMULATOR: a list of the randomly-generated words so far
|
||||
words_so_far = []
|
||||
|
||||
# We've provided this template as a starting point; you may modify it as necessary.
|
||||
for _ in range(count - 1):
|
||||
|
||||
# Choose random key if it's the first word
|
||||
# or the last randomly generated word not in transitions
|
||||
if len(words_so_far) == 0 or words_so_far[-1] not in transitions:
|
||||
words_so_far.append(choose_from_keys(transitions))
|
||||
|
||||
else:
|
||||
words_so_far.append(choose_from_follow_list(words_so_far[-1], transitions))
|
||||
|
||||
return str.join(' ', words_so_far)
|
||||
|
||||
|
||||
def run_example(filename: str) -> str:
|
||||
"""Run an example to demonstrate random text generation based on the data in filename.
|
||||
|
||||
To call this function:
|
||||
- Make sure you see that the 'data' folder is in the same directory as this file
|
||||
- Use an argument for filename like: 'data/texts/sample_text_raw.txt'
|
||||
- Try out the other plaintext files in 'data/texts', too
|
||||
"""
|
||||
with open(filename) as f:
|
||||
file_text = f.read()
|
||||
|
||||
stripped_text = str.strip(file_text) # str.strip removes leading/trailing whitespace
|
||||
word_count, transition_model = create_model_owc(stripped_text)
|
||||
generated_words = generate_text_owc(word_count, transition_model)
|
||||
|
||||
return generated_words
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta
|
||||
import python_ta.contracts
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
|
||||
# When you are ready to check your work with python_ta, uncomment the following lines.
|
||||
# (Delete the "#" and space before each line.)
|
||||
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
|
||||
python_ta.check_all(config={
|
||||
'allowed-io': ['run_example'],
|
||||
'extra-imports': ['python_ta.contracts', 'random'],
|
||||
'max-line-length': 100,
|
||||
'max-nested-blocks': 4,
|
||||
'disable': ['R1705', 'C0200']
|
||||
})
|
||||
@@ -0,0 +1,189 @@
|
||||
"""CSC110 Fall 2020 Assignment 3, Part 3: Loops and Mutation Debugging Exercise
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
|
||||
This Python module contains the program and tests described in Part 3.
|
||||
Run this file to see the pytest report containing at least one failing test.
|
||||
|
||||
While you are making small changes to this file, we will NOT run python_ta
|
||||
on this file when 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) 2020 David Liu and Mario Badr.
|
||||
"""
|
||||
import csv
|
||||
import math
|
||||
|
||||
# Constant for different punctuation marks to remove from review strings.
|
||||
PUNCTUATION = '!\"#$%&()*+,-./:;<=>?@[]^_`{|}~'
|
||||
|
||||
# Constant representing VADER word intensities.
|
||||
# (This is a small subset of the full VADER lexicon.)
|
||||
WORD_TO_INTENSITY = {
|
||||
'adventure': 1.3,
|
||||
'amusing': 1.6,
|
||||
'brilliantly': 3.0,
|
||||
'comedy': 1.5,
|
||||
'excellent': 2.7,
|
||||
'guilty': -1.8,
|
||||
'magnificent': 2.9,
|
||||
'succeeded': 1.8,
|
||||
'terrible': -2.1
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Mario's Program
|
||||
###############################################################################
|
||||
def report_sentiment(review: str) -> tuple[str, float]:
|
||||
"""Return the VADER sentiment of the review in text.
|
||||
|
||||
The VADER sentiment is a tuple of the polarity, intensity of the review.
|
||||
"""
|
||||
# First clean the review text and split into a list of words.
|
||||
word_list = clean_text(review)
|
||||
|
||||
# Extract the number of times each VADER keyword appears in the review.
|
||||
occurrences = count_keywords(word_list)
|
||||
|
||||
# Calculate the average intensity of the keywords in the review.
|
||||
average_intensity = calculate_average_intensity(occurrences)
|
||||
|
||||
if average_intensity >= 0.05:
|
||||
return ('positive', average_intensity)
|
||||
elif average_intensity <= -0.05:
|
||||
return ('negative', average_intensity)
|
||||
else:
|
||||
return ('neutral', average_intensity)
|
||||
|
||||
|
||||
def clean_text(text: str) -> list[str]:
|
||||
"""Return text as a list of words that have been cleaned up.
|
||||
|
||||
Cleaning up involves:
|
||||
- removing punctuation
|
||||
- converting all letters to lowercase (because our VADER keywords
|
||||
are all written as lowercase)
|
||||
"""
|
||||
# Remove punctuation from text
|
||||
for p in PUNCTUATION:
|
||||
text = str.replace(text, p, ' ')
|
||||
|
||||
# Convert text to lowercase
|
||||
text = text.lower()
|
||||
|
||||
# Split text into words and return
|
||||
return str.split(text)
|
||||
|
||||
|
||||
def count_keywords(word_list: list[str]) -> dict[str, int]:
|
||||
"""Return a frequency mapping of the VADER keywords in text.
|
||||
"""
|
||||
# ACCUMULATOR: A mapping of keyword frequencies seen so far
|
||||
occurrences_so_far = {}
|
||||
|
||||
for word in word_list:
|
||||
if word in WORD_TO_INTENSITY:
|
||||
if word not in occurrences_so_far:
|
||||
occurrences_so_far[word] = 0
|
||||
occurrences_so_far[word] += 1
|
||||
|
||||
return occurrences_so_far
|
||||
|
||||
|
||||
def calculate_average_intensity(occurrences: dict[str, int]) -> float:
|
||||
"""Return the average intensity of the given keyword occurrences.
|
||||
|
||||
Preconditions:
|
||||
- occurrences != {}
|
||||
- all({occurrences[keyword] >= 1 for keyword in occurrences})
|
||||
"""
|
||||
num_keywords = sum([occurrences[word] for word in occurrences])
|
||||
total_intensity = sum([WORD_TO_INTENSITY[word] * occurrences[word]
|
||||
for word in occurrences])
|
||||
return total_intensity / num_keywords
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Tests for report_sentiment (THERE ARE NO ERRORS IN THIS PART)
|
||||
###############################################################################
|
||||
def read_critic_data(filename: str) -> str:
|
||||
"""Return the movie review stored in the given file.
|
||||
|
||||
The file is a CSV file with two rows, a header row and a row of actual
|
||||
movie review data. These files are based on real movie review data from Metacritic,
|
||||
though they have been altered slightly to fit this assignment.
|
||||
|
||||
There ARE NO ERRORS in this function; it's used for testing purposes only.
|
||||
"""
|
||||
with open(filename) as file:
|
||||
reader = csv.reader(file)
|
||||
|
||||
# Skip header row
|
||||
next(reader)
|
||||
|
||||
# Read the movie review, which is the last entry in the row
|
||||
row = next(reader)
|
||||
review = row[len(row) - 1]
|
||||
|
||||
return review
|
||||
|
||||
|
||||
def test_star_wars() -> None:
|
||||
"""Test that the review for Star Wars gives the correct polarity and intensity.
|
||||
|
||||
There is NO ERROR in this test.
|
||||
"""
|
||||
review = read_critic_data('data/reviews/review_star_wars.csv')
|
||||
|
||||
actual = report_sentiment(review)
|
||||
expected_polarity = 'positive'
|
||||
expected_intensity = 2.25
|
||||
assert actual[0] == expected_polarity
|
||||
assert math.isclose(actual[1], expected_intensity)
|
||||
|
||||
|
||||
def test_legally_blonde() -> None:
|
||||
"""Test that the review for Legally Blonde gives the correct polarity and intensity.
|
||||
|
||||
There is NO ERROR in this test.
|
||||
"""
|
||||
review = read_critic_data('data/reviews/review_legally_blonde.csv')
|
||||
|
||||
actual = report_sentiment(review)
|
||||
expected_polarity = 'positive'
|
||||
expected_intensity = 0.8333333333333333
|
||||
assert actual[0] == expected_polarity
|
||||
assert math.isclose(actual[1], expected_intensity)
|
||||
|
||||
|
||||
def test_transformers() -> None:
|
||||
"""Test that the review for Transformers gives the correct polarity and intensity.
|
||||
|
||||
There is NO ERROR in this test.
|
||||
"""
|
||||
review = read_critic_data('data/reviews/review_transformers.csv')
|
||||
|
||||
actual = report_sentiment(review)
|
||||
expected_polarity = 'negative'
|
||||
expected_intensity = -0.9
|
||||
assert actual[0] == expected_polarity
|
||||
assert math.isclose(actual[1], expected_intensity)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta.contracts
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
|
||||
import pytest
|
||||
pytest.main(['a3_part3.py', '-v'])
|
||||
@@ -0,0 +1,153 @@
|
||||
"""CSC110 Fall 2021 Assignment 3, Part 4: Forest Fires (SOLUTIONS)
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
Implement each of the functions in this file. As usual, do not change any function headers
|
||||
or preconditions. You do NOT need to add doctests.
|
||||
|
||||
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.
|
||||
"""
|
||||
import csv
|
||||
import plotly.graph_objects as go
|
||||
|
||||
from a3_ffwi_system import WeatherMetrics, FfwiOutput
|
||||
import a3_ffwi_system as ffwi
|
||||
|
||||
|
||||
def load_data(filename: str) -> tuple[list[WeatherMetrics], list[FfwiOutput]]:
|
||||
"""Return a tuple of two parallel lists based on the data in filename. The first list contains
|
||||
WeatherMetrics. The second list contains the corresponding FfwiOutput.
|
||||
|
||||
The data in filename is in a csv format with 12 columns. The first six columns correspond to
|
||||
the month, day, temperature, relative humidity, wind speed, and precipitation, in that order.
|
||||
The last six columns correspond to the FFMC, DMC, DC, ISI, BUI, and FWI values that would be
|
||||
calculated based on the first six columns and the previous day's values.
|
||||
"""
|
||||
# ACCUMULATOR inputs_so_far: The WeatherMetrics parsed from filename so far
|
||||
inputs_so_far = []
|
||||
# ACCUMULATOR outputs_so_far: The FfwiOutputs parsed from filename so far
|
||||
outputs_so_far = []
|
||||
|
||||
with open(filename) as f:
|
||||
reader = csv.reader(f, delimiter=',')
|
||||
next(reader) # skip the header
|
||||
|
||||
for row in reader:
|
||||
assert len(row) == 12, 'Expected every row to contain 12 elements.'
|
||||
month, day, temp, humidity, wind, rain, \
|
||||
ffmc, dmc, dc, isi, bui, fwi = [float(a) for a in row]
|
||||
inputs_so_far.append(WeatherMetrics(int(month), int(day), temp, humidity, wind, rain))
|
||||
outputs_so_far.append(FfwiOutput(ffmc, dmc, dc, isi, bui, fwi))
|
||||
|
||||
return inputs_so_far, outputs_so_far
|
||||
|
||||
|
||||
def calculate_ffwi_outputs(readings: list[WeatherMetrics]) -> dict[tuple[int, int], FfwiOutput]:
|
||||
"""Return a dictionary mapping (month, day) tuples to their corresponding FfwiOutput based on
|
||||
the daily weather measurements found in readings.
|
||||
|
||||
Use the functions in a3_ffwi_system for initial FFMC, DMC, and DC values and to calculate each
|
||||
attribute needed for FfwiOutput.
|
||||
|
||||
Preconditions:
|
||||
- Every reading in readings has a unique (month, day) pair
|
||||
"""
|
||||
# Sort by month and day
|
||||
readings = sorted(readings, key=lambda x: (x.month, x.day))
|
||||
|
||||
# Accumulator
|
||||
output: dict[tuple[int, int], FfwiOutput] = {}
|
||||
|
||||
# Initial values
|
||||
# ASSUME that the input dates are CONTINUOUS
|
||||
# ASSUME that the input dates does not wrap around a year
|
||||
last = FfwiOutput(ffwi.INITIAL_FFMC, ffwi.INITIAL_DMC, ffwi.INITIAL_DC, 0, 0, 0)
|
||||
|
||||
# Loop through inputs
|
||||
for x in readings:
|
||||
ffmc = ffwi.calculate_ffmc(x, last.ffmc)
|
||||
dmc = ffwi.calculate_dmc(x, last.dmc)
|
||||
dc = ffwi.calculate_dc(x, last.dc)
|
||||
isi = ffwi.calculate_isi(x, ffmc)
|
||||
bui = ffwi.calculate_bui(dmc, dc)
|
||||
fwi = ffwi.calculate_fwi(isi, bui)
|
||||
output[(x.month, x.day)] = FfwiOutput(ffmc, dmc, dc, isi, bui, fwi)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def get_xy_data(outputs: dict[tuple[int, int], FfwiOutput], attribute: str) -> \
|
||||
tuple[list[str], list[float]]:
|
||||
"""Return a tuple of two parallel lists. The first list contains the keys of outputs as
|
||||
strings in the format 'month, day'. The second list contains the corresponding value of
|
||||
the attribute of FfwiOutput.
|
||||
|
||||
You can access an attribute from a data class using the getattr built-in function. For example,
|
||||
>>> output = FfwiOutput(2.0, 3.0, 4.0, 5.0, 6.0, 7.0)
|
||||
>>> getattr(output, 'ffmc')
|
||||
2.0
|
||||
"""
|
||||
# Accumulators
|
||||
days: list[str] = []
|
||||
data: list[float] = []
|
||||
|
||||
for k in outputs.keys():
|
||||
month, day = k
|
||||
days.append(f'{month}, {day}')
|
||||
data.append(getattr(outputs[k], attribute))
|
||||
|
||||
return days, data
|
||||
|
||||
|
||||
def plot_ffwi_attribute(outputs: dict[tuple[int, int], FfwiOutput], attribute: str) -> None:
|
||||
"""Plot an attribute from FfwiOutput as a time series.
|
||||
|
||||
Preconditions:
|
||||
- attribute in {'ffmc', 'dmc', 'dc', 'isi', 'bui', 'fwi'}
|
||||
- outputs != {}
|
||||
"""
|
||||
# Convert the outputs into parallel x and y lists
|
||||
x_data, y_data = get_xy_data(outputs, attribute)
|
||||
|
||||
# Create the figure
|
||||
fig = go.Figure()
|
||||
fig.add_trace(go.Scatter(x=x_data, y=y_data, name=attribute))
|
||||
|
||||
# Configure the figure
|
||||
fig.update_layout(title=f'Time Series of {attribute}',
|
||||
xaxis_title='(Month, Day)',
|
||||
yaxis_title=f'Calculated {attribute}')
|
||||
|
||||
# Show the figure in the browser
|
||||
fig.show()
|
||||
# Is the above not working for you? Comment it out, and uncomment the following:
|
||||
# fig.write_html('my_figure.html')
|
||||
# You will need to manually open the my_figure.html file created above.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta
|
||||
import python_ta.contracts
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
|
||||
# When you are ready to check your work with python_ta, uncomment the following lines.
|
||||
# (Delete the "#" and space before each line.)
|
||||
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
|
||||
python_ta.check_all(config={
|
||||
'allowed-io': ['load_data'],
|
||||
'extra-imports': ['python_ta.contracts', 'csv', 'plotly.graph_objects', 'a3_ffwi_system'],
|
||||
'max-line-length': 100,
|
||||
'max-args': 6,
|
||||
'max-locals': 25,
|
||||
'disable': ['R1705'],
|
||||
})
|
||||
@@ -0,0 +1,105 @@
|
||||
"""CSC110 Fall 2021 Assignment 3: Part 4 (Student Test Suite)
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
Complete the unit tests in this file based on their docstring descriptions.
|
||||
|
||||
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.
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from a3_part4 import load_data
|
||||
from a3_ffwi_system import WeatherMetrics, FfwiOutput
|
||||
|
||||
import a3_ffwi_system as ffwi
|
||||
|
||||
|
||||
class TestCalculateMr:
|
||||
"""A collection of unit tests for calculate_mr."""
|
||||
|
||||
def test_equation_3a_branch(self) -> None:
|
||||
"""Test the branch calculate_mr that contains Equation 3a."""
|
||||
assert 123.82 == pytest.approx(ffwi.calculate_mr(2.4, 80))
|
||||
|
||||
def test_equation_3b_branch(self) -> None:
|
||||
"""Test the branch calculate_mr that contains Equation 3b."""
|
||||
assert 182.80 == pytest.approx(ffwi.calculate_mr(2.4, 155))
|
||||
|
||||
|
||||
class TestCalculateM:
|
||||
"""A collection of unit tests for calculate_m."""
|
||||
|
||||
def test_no_mutation_mo_equals_ed(self) -> None:
|
||||
"""Test that calculate_m does not mutate the WeatherMetrics argument when mo == ed."""
|
||||
# TODO: Complete this unit test and remove this TODO
|
||||
|
||||
def test_no_mutation_mo_leq_ew(self) -> None:
|
||||
"""Test that calculate_m does not mutate the WeatherMetrics argument when mo <= ew."""
|
||||
# TODO: Complete this unit test and remove this TODO
|
||||
|
||||
def test_no_mutation_mo_greater_than_ew(self) -> None:
|
||||
"""Test that calculate_m does not mutate the WeatherMetrics argument when mo > ew."""
|
||||
# TODO: Complete this unit test and remove this TODO
|
||||
|
||||
def test_no_mutation_mo_greater_than_ed(self) -> None:
|
||||
"""Test that calculate_m does not mutate the WeatherMetrics argument when mo > ed."""
|
||||
# TODO: Complete this unit test and remove this TODO
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_data() -> tuple[list[WeatherMetrics], list[FfwiOutput]]:
|
||||
"""A pytest fixture containing the data in data/ffwi/sample_data.csv
|
||||
|
||||
NOTE: Do not change this function. Do not call this function directly. It is a pytest fixture,
|
||||
so pytest will call it automatically and pass it to test_ffmc_against_ground_truth below.
|
||||
"""
|
||||
return load_data('data/ffwi/sample_data.csv')
|
||||
|
||||
|
||||
def test_ffmc_against_ground_truth(sample_data) -> None:
|
||||
"""Test the correctness of calculate_ffmc, calculate_dmc, calculate_dc, calculate_isi,
|
||||
calculate_bui, and calculate_fwi based on sample_data.
|
||||
|
||||
Ensure that, for every WeatherMetric element in sample_data[0] passed to each of the calculate_
|
||||
functions mentioned above, the return value, rounded to the nearest decimal, matches the
|
||||
corresponding value from the FfwiOutput element in sample_data[1].
|
||||
|
||||
Hints:
|
||||
- You will need to use the built-in function round.
|
||||
- You may want to use pytest.approx since you are comparing float values.
|
||||
"""
|
||||
ffmc = ffwi.INITIAL_FFMC
|
||||
dmc = ffwi.INITIAL_DMC
|
||||
dc = ffwi.INITIAL_DC
|
||||
|
||||
inputs, outputs = sample_data
|
||||
# TODO: Complete this test and remove this TODO.
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main(['a3_part4_tests.py'])
|
||||
|
||||
# When you are ready to check your work with python_ta, uncomment the following lines.
|
||||
# (Delete the "#" and space before each line.)
|
||||
# IMPORTANT: keep this code indented inside the "if __name__ == '__main__'" block
|
||||
# import python_ta
|
||||
# import python_ta.contracts
|
||||
# python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
# python_ta.contracts.check_all_contracts()
|
||||
# python_ta.check_all(config={
|
||||
# 'allowed-io': ['load_data'],
|
||||
# 'extra-imports': ['a3_ffwi_system', 'a3_part4', 'pytest'],
|
||||
# 'max-line-length': 100,
|
||||
# 'max-args': 6,
|
||||
# 'max-locals': 25,
|
||||
# 'disable': ['R1705', 'R0201', 'C0103', 'W0621', 'E9970'],
|
||||
# })
|
||||
@@ -0,0 +1,129 @@
|
||||
"""CSC110 Fall 2021 Assignment 3, Example Tests
|
||||
|
||||
Instructions (READ THIS FIRST!)
|
||||
===============================
|
||||
This Python module contains example tests you can run for Parts 1 and 2 of this assignment. Please
|
||||
note that passing all these tests does NOT mean you have a 100% correct solution.
|
||||
|
||||
Some of the tests are empty, consider completing them. Also consider adding more of your own tests.
|
||||
|
||||
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.
|
||||
"""
|
||||
import a3_part1
|
||||
import a3_part2
|
||||
|
||||
|
||||
class TestCreateModelUniform:
|
||||
"""Some example tests for A3 Part 1 - create_model_uniform."""
|
||||
|
||||
def test_two_words(self) -> None:
|
||||
"""Test that the correct model is produced when the text contains two words."""
|
||||
test_text = 'Hello, World!'
|
||||
expected = {'Hello,': 1, 'World!': 1}
|
||||
|
||||
assert a3_part1.create_model_uniform(test_text) == expected
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
class TestUpdateFollowList:
|
||||
"""Some example tests for A3 Part 2 - update_follow_list."""
|
||||
|
||||
def test_empty(self) -> None:
|
||||
"""Test that an empty dictionary is mutated correctly."""
|
||||
test_model = {}
|
||||
a3_part2.update_follow_list(test_model, 'I', 'like')
|
||||
|
||||
assert test_model == {'I': ['like']}
|
||||
|
||||
def test_not_empty_key_exists(self) -> None:
|
||||
"""Test that a non-empty dictionary is mutated correctly when the key already exists."""
|
||||
test_model = {'I': ['like']}
|
||||
a3_part2.update_follow_list(test_model, 'I', 'really')
|
||||
|
||||
assert test_model == {'I': ['like', 'really']}
|
||||
|
||||
def test_not_empty_key_does_not_exist(self) -> None:
|
||||
"""Test that a non-empty dictionary is mutated correctly when the key already exists."""
|
||||
# TODO: Consider completing this test based on its docstring
|
||||
test_model = {'I': ['like']}
|
||||
a3_part2.update_follow_list(test_model, 'like', 'chocolate')
|
||||
|
||||
assert test_model == {'I': ['like'], 'like': ['chocolate']}
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
class TestCreateModelOwc:
|
||||
"""Some example tests for A3 Part 2 - create_model_owc."""
|
||||
|
||||
def test_two_words(self) -> None:
|
||||
"""Test that the correct model is produced when the text contains two words."""
|
||||
test_text = 'Hello, World!'
|
||||
|
||||
expected_word_count = 2
|
||||
expected_model = {'Hello,': ['World!']}
|
||||
|
||||
actual_word_count, actual_model = a3_part2.create_model_owc(test_text)
|
||||
assert actual_word_count == expected_word_count
|
||||
assert actual_model == expected_model
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
class TestChooseFromKeys:
|
||||
"""Some example tests for A3 Part 2 - choose_from_keys."""
|
||||
|
||||
def test_one_possibility(self) -> None:
|
||||
"""Test that the only possible key is returned."""
|
||||
test_transitions = {'The': ['cat']}
|
||||
|
||||
assert a3_part2.choose_from_keys(test_transitions) == 'The'
|
||||
|
||||
def test_two_possibilities(self) -> None:
|
||||
"""Test that one of two possible keys is returned."""
|
||||
test_transitions = {'The': ['cat'], 'cat': ['in']}
|
||||
possibilities = {'The', 'cat'}
|
||||
|
||||
assert a3_part2.choose_from_keys(test_transitions) in possibilities
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
class TestChooseFromFollowList:
|
||||
"""Some example tests for A3 Part 2 - choose_from_follow_list."""
|
||||
|
||||
def test_one_possibility(self) -> None:
|
||||
"""Test that the only possible value for a key is returned."""
|
||||
test_transitions = {'The': ['cat'], 'cat': ['in'], 'in': ['the'], 'the': ['hat.']}
|
||||
|
||||
assert a3_part2.choose_from_follow_list('The', test_transitions) == 'cat'
|
||||
|
||||
def test_one_possibility_mutation(self) -> None:
|
||||
"""Test that the dictionary is mutated correctly."""
|
||||
test_transitions = {'The': ['cat'], 'cat': ['in'], 'in': ['the'], 'the': ['hat.']}
|
||||
a3_part2.choose_from_follow_list('The', test_transitions)
|
||||
|
||||
assert test_transitions == {'cat': ['in'], 'in': ['the'], 'the': ['hat.']}
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
class TestGenerateTextOwc:
|
||||
"""Some example tests for A3 Part 2 - generate_text_owc."""
|
||||
|
||||
# TODO: Consider adding more tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import pytest
|
||||
pytest.main(['a3_example_tests.py'])
|
||||
@@ -0,0 +1,50 @@
|
||||
Month,Day,Temp,Humidity,Wind,Rain,FFMC,DMC,DC,ISI,BUI,FWI
|
||||
4,13,17.0,42.0,25.0,0.0,87.7,8.5,19.0,10.9,8.5,10.1
|
||||
4,14,20.0,21.0,25.0,2.4,86.2,10.4,23.6,8.8,10.4,9.3
|
||||
4,15,8.5,40.0,17.0,0.0,87.0,11.8,26.1,6.5,11.7,7.6
|
||||
4,16,6.5,25.0,6.0,0.0,88.8,13.2,28.2,4.9,13.1,6.2
|
||||
4,17,13.0,34.0,24.0,0.0,89.1,15.4,31.5,12.6,15.3,14.8
|
||||
4,18,6.0,40.0,22.0,0.4,88.7,16.5,33.5,10.7,16.4,13.5
|
||||
4,19,5.5,52.0,6.0,0.0,87.4,17.2,35.4,4.0,17.1,5.9
|
||||
4,20,8.5,46.0,16.0,0.0,87.4,18.5,37.9,6.6,18.4,9.7
|
||||
4,21,9.5,54.0,20.0,0.0,86.8,19.7,40.6,7.4,19.6,11.0
|
||||
4,22,7.0,93.0,14.0,9.0,29.9,10.1,29.5,0.0,10.9,0.0
|
||||
4,23,6.5,71.0,17.0,1.0,49.4,10.7,31.6,0.4,11.6,0.2
|
||||
4,24,6.0,59.0,17.0,0.0,67.3,11.4,33.7,1.3,12.3,0.9
|
||||
4,25,13.0,52.0,4.0,0.0,77.8,13.0,37.0,1.1,13.9,0.8
|
||||
4,26,15.5,40.0,11.0,0.0,85.5,15.4,40.7,3.9,15.9,5.5
|
||||
4,27,23.0,25.0,9.0,0.0,91.5,19.8,45.8,8.4,19.8,12.2
|
||||
4,28,19.0,46.0,16.0,0.0,89.9,22.5,50.2,9.5,22.4,14.3
|
||||
4,29,18.0,41.0,20.0,0.0,90.0,25.2,54.4,11.7,25.1,17.7
|
||||
4,30,14.5,51.0,16.0,0.0,88.4,27.0,57.9,7.7,27.0,13.3
|
||||
5,1,14.5,69.0,11.0,0.0,85.7,28.3,63.0,4.0,28.2,8.0
|
||||
5,2,15.5,42.0,8.0,0.0,87.4,30.8,68.2,4.4,30.8,9.1
|
||||
5,3,21.0,37.0,8.0,0.0,89.4,34.5,74.3,5.9,34.4,12.3
|
||||
5,4,23.0,32.0,16.0,0.0,91.0,38.8,80.9,11.1,38.7,21.0
|
||||
5,5,23.0,32.0,14.0,0.0,91.2,43.1,87.4,10.3,43.0,21.1
|
||||
5,6,27.0,33.0,12.0,0.0,91.7,48.1,94.7,9.9,47.9,21.7
|
||||
5,7,28.0,17.0,27.0,0.0,95.2,54.5,102.1,34.5,54.3,52.6
|
||||
5,8,23.5,54.0,20.0,0.0,89.7,57.4,108.8,11.3,57.2,25.9
|
||||
5,9,16.0,50.0,22.0,12.2,62.2,29.9,91.8,1.4,33.0,3.0
|
||||
5,10,11.5,58.0,20.0,0.0,76.7,31.3,96.3,2.3,34.5,5.4
|
||||
5,11,16.0,54.0,16.0,0.0,83.5,33.4,101.6,3.8,36.7,8.9
|
||||
5,12,21.5,37.0,9.0,0.0,88.7,37.1,107.8,5.6,39.9,12.8
|
||||
5,13,14.0,61.0,22.0,0.2,86.7,38.7,112.8,8.1,41.6,17.3
|
||||
5,14,15.0,30.0,27.0,0.0,89.6,41.7,117.9,15.9,44.2,28.8
|
||||
5,15,20.0,23.0,11.0,0.0,92.1,45.9,123.9,10.1,47.7,21.9
|
||||
5,16,14.0,95.0,3.0,16.4,21.3,20.1,97.0,0.0,26.5,0.0
|
||||
5,17,20.0,53.0,4.0,2.8,51.0,18.3,103.0,0.2,25.3,0.2
|
||||
5,18,19.5,30.0,16.0,0.0,82.3,22.1,108.9,3.3,29.3,6.8
|
||||
5,19,25.5,51.0,20.0,6.0,75.4,16.4,106.4,2.1,23.7,3.8
|
||||
5,20,10.0,38.0,24.0,0.0,84.3,18.2,110.6,6.4,25.8,11.3
|
||||
5,21,19.0,27.0,16.0,0.0,90.3,22.1,116.4,10.0,29.9,17.2
|
||||
5,22,26.0,46.0,11.0,4.2,77.6,18.7,117.7,1.6,26.8,2.9
|
||||
5,23,30.0,38.0,22.0,0.0,90.2,23.8,125.5,13.4,32.3,22.0
|
||||
5,24,25.5,67.0,19.0,12.6,65.3,13.1,108.5,1.4,20.2,1.9
|
||||
5,25,12.0,53.0,28.0,11.8,55.4,7.7,91.6,1.2,12.8,0.8
|
||||
5,26,21.0,38.0,8.0,0.0,80.8,11.3,97.8,1.9,17.6,2.6
|
||||
5,27,13.0,70.0,20.0,3.8,61.7,8.4,97.9,1.2,13.8,0.9
|
||||
5,28,9.0,78.0,24.0,1.4,64.5,9.0,101.9,1.7,14.7,2.0
|
||||
5,29,11.0,54.0,16.0,0.0,77.6,10.5,106.3,2.0,16.8,2.8
|
||||
5,30,15.5,39.0,9.0,0.0,85.4,13.1,111.5,3.5,20.3,5.8
|
||||
5,31,18.0,36.0,5.0,0.0,88.5,16.3,117.1,4.4,24.2,7.9
|
||||
|
@@ -0,0 +1,2 @@
|
||||
critic_name,media,movie_title,review_date,individual_meta_score,text
|
||||
Kenneth Turan,Los Angeles Times,Legally Blonde,,50,"Guilty of squandering resources. Amusing as it goes about setting up its premise, in Witherspoon, the gifted veteran of ""Election"" and ""Pleasantville,"" it has an actress willing to throw herself completely into the part to excellent effect."
|
||||
|
@@ -0,0 +1,2 @@
|
||||
critic_name,media,movie_title,review_date,individual_meta_score,text
|
||||
,Variety,Star Wars: Episode IV - A New Hope,,100,"A magnificent film. George Lucas set out to make the biggest possible adventure fantasy out of his memories of serials and older action epics, and he succeeded brilliantly."
|
||||
|
@@ -0,0 +1,2 @@
|
||||
critic_name,media,movie_title,review_date,individual_meta_score,text
|
||||
Tasha Robinson,The A.V. Club,Transformers,,42,"Turns the franchise into a terrible, terrible '80s comedy."
|
||||
|
@@ -0,0 +1,542 @@
|
||||
You left with no goodbye,
|
||||
Not a single word was said,
|
||||
No final kiss to seal any seams,
|
||||
I had no idea of the state we were in,
|
||||
|
||||
I know I have a fickle heart and a bitterness,
|
||||
And a wandering eye, and heaviness in my head,
|
||||
|
||||
But don't you remember?
|
||||
Don't you remember?
|
||||
The reason you loved me before,
|
||||
Baby, please remember me once more,
|
||||
|
||||
When was the last time you thought of me?
|
||||
Or have you completely erased me from your memory?
|
||||
I often think about where I went wrong,
|
||||
The more I do, the less I know,
|
||||
|
||||
But I know I have a fickle heart and a bitterness,
|
||||
And a wandering eye, and a heaviness in my head,
|
||||
|
||||
But don't you remember?
|
||||
Don't you remember?
|
||||
The reason you loved me before,
|
||||
Baby, please remember me once more,
|
||||
|
||||
Gave you space so you could breathe,
|
||||
I kept my distance so you would be free,
|
||||
And hoped that you'd find the missing piece,
|
||||
To bring you back to me,
|
||||
|
||||
Why don't you remember?
|
||||
Don't you remember?
|
||||
The reason you loved me before,
|
||||
Baby, please remember me once more,
|
||||
|
||||
When will I see you again?
|
||||
on.
|
||||
|
||||
Daydreamer
|
||||
Sitting on the sea
|
||||
Soaking up the sun
|
||||
He is a real lover
|
||||
Of making up the past
|
||||
And feeling up his girl
|
||||
Like he's never felt her figure before
|
||||
|
||||
A jaw dropper
|
||||
Looks good when he walks
|
||||
Is the subject of their talk
|
||||
He would be hard to chase
|
||||
But good to catch
|
||||
And he could change the world
|
||||
With his hands behind his back, oh
|
||||
|
||||
You can find him sittin' on your doorstep
|
||||
Waiting for a surprise
|
||||
And he will feel like he's been there for hours
|
||||
And you can tell that he'll be there for life
|
||||
|
||||
Daydreamer
|
||||
With eyes that make you melt
|
||||
He lends his coat for shelter
|
||||
Plus he's there for you
|
||||
When he shouldn't be
|
||||
But he stays all the same
|
||||
Waits for you
|
||||
Then sees you through
|
||||
|
||||
There's no way I
|
||||
Could describe him
|
||||
What I'll say is
|
||||
Just what I'm hoping for
|
||||
|
||||
But I will find him sittin' on my doorstep
|
||||
Waiting for a surprise
|
||||
And he will feel like he's been there for hours
|
||||
And I can tell that he'll be there for life
|
||||
And I can tell that he'll be there for life
|
||||
|
||||
I heard that you're settled down
|
||||
That you found a girl and you're married now.
|
||||
I heard that your dreams came true.
|
||||
Guess she gave you things I didn't give to you.
|
||||
|
||||
Old friend, why are you so shy?
|
||||
Ain't like you to hold back or hide from the light.
|
||||
|
||||
I hate to turn up out of the blue uninvited
|
||||
But I couldn't stay away, I couldn't fight it.
|
||||
I had hoped you'd see my face and that you'd be reminded
|
||||
That for me it isn't over.
|
||||
|
||||
Never mind, I'll find someone like you
|
||||
I wish nothing but the best for you too
|
||||
Don't forget me, I beg
|
||||
I remember you said,
|
||||
"Sometimes it lasts in love but sometimes it hurts instead,
|
||||
Sometimes it lasts in love but sometimes it hurts instead, "
|
||||
Yeah
|
||||
|
||||
You know how the time flies
|
||||
Only yesterday was the time of our lives
|
||||
We were born and raised
|
||||
In a summer haze
|
||||
Bound by the surprise of our glory days
|
||||
|
||||
I hate to turn up out of the blue uninvited
|
||||
But I couldn't stay away, I couldn't fight it.
|
||||
I'd hoped you'd see my face and that you'd be reminded
|
||||
That for me it isn't over.
|
||||
|
||||
Never mind, I'll find someone like you
|
||||
I wish nothing but the best for you too
|
||||
Don't forget me, I beg
|
||||
I remember you said,
|
||||
"Sometimes it lasts in love but sometimes it hurts instead."
|
||||
Yeah
|
||||
|
||||
Nothing compares
|
||||
No worries or cares
|
||||
Regrets and mistakes
|
||||
They are memories made.
|
||||
Who would have known how bittersweet this would taste?
|
||||
|
||||
Never mind, I'll find someone like you
|
||||
I wish nothing but the best for you
|
||||
Don't forget me, I beg
|
||||
I remember you said,
|
||||
"Sometimes it lasts in love but sometimes it hurts instead."
|
||||
|
||||
Never mind, I'll find someone like you
|
||||
I wish nothing but the best for you too
|
||||
Don't forget me, I beg
|
||||
I remember you said,
|
||||
"Sometimes it lasts in love but sometimes it hurts instead,
|
||||
Sometimes it lasts in love but sometimes it hurts instead."
|
||||
Yeah
|
||||
I let it fall, my heart,
|
||||
And as it fell you rose to claim it
|
||||
It was dark and I was over
|
||||
Until you kissed my lips and you saved me
|
||||
|
||||
My hands, they're strong
|
||||
But my knees were far too weak
|
||||
To stand in your arms
|
||||
Without falling to your feet
|
||||
|
||||
But there's a side to you
|
||||
That I never knew, never knew.
|
||||
All the things you'd say
|
||||
They were never true, never true,
|
||||
And the games you play
|
||||
You would always win, always win.
|
||||
|
||||
[Chorus:]
|
||||
But I set fire to the rain,
|
||||
Watched it pour as I touched your face,
|
||||
Well, it burned while I cried
|
||||
'Cause I heard it screaming out your name, your name!
|
||||
|
||||
When I lay with you
|
||||
I could stay there
|
||||
Close my eyes
|
||||
Feel you here forever
|
||||
You and me together
|
||||
Nothing is better
|
||||
|
||||
'Cause there's a side to you
|
||||
That I never knew, never knew,
|
||||
All the things you'd say,
|
||||
They were never true, never true,
|
||||
And the games you play
|
||||
You would always win, always win.
|
||||
|
||||
[Chorus:]
|
||||
But I set fire to the rain,
|
||||
Watched it pour as I touched your face,
|
||||
Well, it burned while I cried
|
||||
'Cause I heard it screaming out your name, your name!
|
||||
|
||||
I set fire to the rain
|
||||
And I threw us into the flames
|
||||
Where it felt something die
|
||||
'Cause I knew that that was the last time, the last time!
|
||||
|
||||
Sometimes I wake up by the door,
|
||||
That heart you caught must be waiting for you
|
||||
Even now when we're already over
|
||||
I can't help myself from looking for you.
|
||||
|
||||
[Chorus:]
|
||||
I set fire to the rain,
|
||||
Watched it pour as I touched your face,
|
||||
Well, it burned while I cried
|
||||
'Cause I heard it screaming out your name, your name
|
||||
|
||||
I set fire to the rain,
|
||||
And I threw us into the flames
|
||||
Where it felt something die
|
||||
'Cause I knew that that was the last time, the last time, oh, ohhhh!
|
||||
|
||||
Oh noooo
|
||||
Let it burn
|
||||
Oh oh ohhhh
|
||||
Let it burn
|
||||
Oh oh ohhhh
|
||||
Let it burn
|
||||
Oh oh ohhhh
|
||||
|
||||
|
||||
Wait, do you see my heart on my sleeve?
|
||||
It's been there for days on end and
|
||||
It's been waiting for you to open up
|
||||
Yours too baby, come on now
|
||||
I'm trying to tell you just how
|
||||
I'd like to hear the words roll out of your mouth finally
|
||||
Say that it's always been me
|
||||
|
||||
This made you feel a way you've never felt before
|
||||
And I'm all you need and that you never want more
|
||||
Then you'd say all of the right things without a clue
|
||||
But you'd save the best for last
|
||||
Like I'm the one for you
|
||||
|
||||
You should know that you're just a temporary fix
|
||||
This isn't a routine with you it don't mean that much to me
|
||||
You're just a filler in the space that happened to be free
|
||||
How dare you think you'd get away with trying to play me
|
||||
|
||||
Why is it every time I think I've tried my hardest
|
||||
It turns out it ain't enough, you're still not mentioning love
|
||||
What am I supposed to do to make you want me properly?
|
||||
I'm taking these chances and getting nowhere
|
||||
And though I'm trying my hardest you go back to her
|
||||
And I think that I know things may never change
|
||||
I'm still hoping one day I might hear you say
|
||||
|
||||
I make you feel a way you've never felt before
|
||||
And I'm all you need and that you never want more
|
||||
Then you'd say all of the right things without a clue
|
||||
But you'd save the best for last
|
||||
Like I'm the one for you
|
||||
|
||||
You should know that you're just a temporary fix
|
||||
This isn't a routine with you it don't mean that much to me
|
||||
You're just a filler in the space that happened to be free
|
||||
How dare you think you'd get away with trying to play me
|
||||
|
||||
But, despite the truth that I know
|
||||
I find it hard to let go and give up on you
|
||||
Seems I love the things you do
|
||||
Like the meaner you treat me more eager I am
|
||||
To persist with this heartbreak, running around
|
||||
And I will do until I find myself with you and
|
||||
|
||||
Make you feel a way you've never felt before
|
||||
And be all you need so that you'll never want more
|
||||
And you'll say all of the right things without a clue
|
||||
And you'll be the one for me and me the one for you
|
||||
|
||||
I've made up my mind,
|
||||
Don't need to think it over
|
||||
If I'm wrong, I am right
|
||||
Don't need to look no further,
|
||||
This ain't lust
|
||||
I know this is love
|
||||
But, if I tell the world
|
||||
I'll never say enough
|
||||
'cause it was not said to you
|
||||
And that's exactly what I need to do
|
||||
If I end up with you
|
||||
|
||||
[Chorus]
|
||||
Should I give up,
|
||||
Or should I just keep chasin' pavements?
|
||||
Even if it leads nowhere
|
||||
Or would it be a waste
|
||||
Even if I knew my place
|
||||
Should I leave it there
|
||||
Should I give up,
|
||||
Or should I just keep chasin' pavements
|
||||
Even if it leads nowhere
|
||||
|
||||
I build myself up
|
||||
And fly around in circles
|
||||
Waitin' as my heart drops
|
||||
And my back begins to tingle
|
||||
Finally, could this be it
|
||||
|
||||
[Chorus]
|
||||
Or should I give up
|
||||
Or should I just keep chasin' pavements
|
||||
Even if it leads nowhere
|
||||
Or would it be a waste
|
||||
Even if I knew my place
|
||||
Should I leave it there
|
||||
|
||||
Should I give up
|
||||
Or should I just keep chasin' pavements
|
||||
Even if it leads nowhere
|
||||
Or would it be a waste
|
||||
Even if I knew my place should I leave it there
|
||||
Should I give up
|
||||
Or should I just keep on chasin' pavements
|
||||
Should I just keep on chasin' pavements
|
||||
Ohh oh
|
||||
|
||||
[Chorus x2]
|
||||
elf today
|
||||
Singing out loud your name,
|
||||
You said I'm crazy,
|
||||
If I am I'm crazy for you.
|
||||
|
||||
Sometimes sitting in the dark
|
||||
Wishing you were here
|
||||
Turns me crazy,
|
||||
But it's you who makes me lose my head.
|
||||
|
||||
And every time I'm meant to be acting sensible
|
||||
You drift into my head
|
||||
And turn me into a crumbling fool.
|
||||
|
||||
Tell me to run and I'll race,
|
||||
If you want me to stop I'll freeze,
|
||||
And if you want me gone, I'll leave,
|
||||
Just hold me closer, baby,
|
||||
And make me crazy for you.
|
||||
Crazy for you.
|
||||
|
||||
Lately with this state I'm in
|
||||
I can't help myself but spin.
|
||||
I wish you'd come over,
|
||||
Send me spinning closer to you.
|
||||
|
||||
My oh my, how my blood boils,
|
||||
It's sweet taste for you,
|
||||
Strips me down bare
|
||||
And gets me into my favourite mood.
|
||||
|
||||
I keep on trying, fighting these feelings away,
|
||||
But the more I do,
|
||||
The crazier I turn into.
|
||||
|
||||
Pacing floors and opening doors,
|
||||
Hoping you'll walk through
|
||||
And save me boy,
|
||||
Because I'm too crazy for you.
|
||||
Crazy for you
|
||||
Right under my feet there's air made of bricks
|
||||
Pulls me down turns me weak for you
|
||||
I find myself repeating like a broken tune
|
||||
And I'm forever excusing your intentions
|
||||
And I give in to my pretendings
|
||||
Which forgive you each time
|
||||
Without me knowing
|
||||
They melt my heart to stone
|
||||
|
||||
And I hear your words that I made up
|
||||
You say my name like there could be an us
|
||||
I best tidy up my head I'm the only one in love
|
||||
I'm the only one in love
|
||||
|
||||
Each and every time I turn around to leave
|
||||
I feel my heart begin to burst and bleed
|
||||
So desperately I try to link it with my head
|
||||
But instead I fall back to my knees
|
||||
As you tear your way right through me
|
||||
I forgive you once again
|
||||
Without me knowing
|
||||
You've burnt my heart to stone
|
||||
|
||||
And I hear your words that I made up
|
||||
You say my name like there could be an us
|
||||
I best tidy up my head I'm the only one in love
|
||||
I'm the only one in love
|
||||
|
||||
Why do you steal my hand
|
||||
Whenever I'm standing my own ground
|
||||
You build me up, then leave me dead
|
||||
|
||||
Well I hear your words you made up
|
||||
I say your name like there should be an us
|
||||
I best tidy up my head I'm the only one in love
|
||||
I'm the only one in love
|
||||
|
||||
So little to say but so much time,
|
||||
Despite my empty mouth the words are in my mind.
|
||||
Please wear the face, the one where you smile,
|
||||
Because you lighten up my heart when I start to cry.
|
||||
|
||||
Forgive me first love, but I'm tired.
|
||||
I need to get away to feel again.
|
||||
Try to understand why,
|
||||
don't get so close to change my mind.
|
||||
Please wipe that look out of your eyes,
|
||||
it's bribing me to doubt myself;
|
||||
Simply, it's tiring.
|
||||
|
||||
This love has dried up and stayed behind,
|
||||
And if I stay I'll be a lie
|
||||
Then choke on words I'd always hide.
|
||||
Excuse me first love, but we're through.
|
||||
I need to taste a kiss from someone new.
|
||||
|
||||
Forgive me first love, but I'm too tired.
|
||||
I'm bored to say the least and I, I lack desire.
|
||||
Forgive me first love,
|
||||
Forgive me first love,
|
||||
Forgive me first love,
|
||||
Forgive me first love,
|
||||
Forgive me,
|
||||
Forgive me first love,
|
||||
Forgive me first love
|
||||
|
||||
Who wants to be right as rain
|
||||
It's better when something is wrong
|
||||
You get excitement in your bones
|
||||
And everything you do's a game
|
||||
When night comes and you're on your own
|
||||
You can say "I chose to be alone"
|
||||
Who wants to be right as rain
|
||||
It's harder when you're on top
|
||||
|
||||
'Cause when hard work don't pay off
|
||||
And I'm tired there ain't no room in my bed
|
||||
As far as I'm concerned
|
||||
So wipe that dirty smile off
|
||||
We won't be making up
|
||||
I've cried my heart out
|
||||
And now I've had enough of love
|
||||
|
||||
Who wants to be riding high
|
||||
When you'll just crumble back on down
|
||||
You give up everything you are
|
||||
And even then you don't get far
|
||||
They make believe that everything
|
||||
Is exactly what it seems
|
||||
But at least when you're at your worst
|
||||
You know how to feel things
|
||||
|
||||
See when hard work don't pay off and I'm tired
|
||||
There ain't no room in my bed
|
||||
As far as I'm concerned
|
||||
So wipe that dirty smile off
|
||||
We won't be making up
|
||||
I've cried my heart out
|
||||
And now I've had enough of love
|
||||
|
||||
Go ahead and still my heart
|
||||
To make me cry again
|
||||
'Cause it will never hurt
|
||||
As much as it did then
|
||||
When we were both right
|
||||
And no one had blame
|
||||
But now I give up
|
||||
On this endless game
|
||||
|
||||
'Cause who wants to be right as rain
|
||||
It's better when something is wrong
|
||||
I get excitement in my bones
|
||||
Even thought everything's a strain
|
||||
When night comes and I'm on my own
|
||||
You should know I chose to be alone
|
||||
Who wants to be right as rain
|
||||
It's harder when you're on top
|
||||
|
||||
'Cause when hard work don't pay off and I'm tired
|
||||
There ain't no room in my bed
|
||||
As far as I'm concerned
|
||||
So wipe that dirty smile off
|
||||
We won't be making up
|
||||
I've cried my heart out
|
||||
And now I've had enough of love
|
||||
|
||||
When the rain is blowing in your face,
|
||||
And the whole world is on your case,
|
||||
I could offer you a warm embrace
|
||||
To make you feel my love.
|
||||
|
||||
When the evening shadows and the stars appear,
|
||||
And there is no one there to dry your tears,
|
||||
I could hold you for a million years
|
||||
To make you feel my love.
|
||||
|
||||
I know you haven't made your mind up yet,
|
||||
But I would never do you wrong.
|
||||
I've known it from the moment that we met,
|
||||
No doubt in my mind where you belong.
|
||||
|
||||
I'd go hungry; I'd go black and blue,
|
||||
I'd go crawling down the avenue.
|
||||
No, there's nothing that I wouldn't do
|
||||
To make you feel my love.
|
||||
|
||||
The storms are raging on the rolling sea
|
||||
And on the highway of regret.
|
||||
Though winds of change are blowing wild and free,
|
||||
You ain't seen nothing like me yet.
|
||||
|
||||
I could make you happy, make your dreams come true.
|
||||
Nothing that I wouldn't do.
|
||||
Go to the ends of the Earth for you,
|
||||
To make you feel my love
|
||||
To make you feel my love
|
||||
|
||||
u said I'm stubborn and I never give in
|
||||
I think you're stubborn 'cept you're always softening
|
||||
You say I'm selfish, I agree with you on that
|
||||
I think you're giving out in way too much in fact
|
||||
I say we've only known each other one year
|
||||
You say I've known you longer my dear
|
||||
You like to be so close, I like to be alone
|
||||
I like to sit on chairs and you prefer the floor
|
||||
Walking with each other, think we'll never match at all, but we do
|
||||
But we do, but we do, but we do
|
||||
|
||||
I thought I knew myself, somehow you know me more
|
||||
I've never known this, never before
|
||||
You're the first to make out whenever we are two
|
||||
I don't know who I'd be if I didn't know you
|
||||
You're so provocative, I'm so conservative
|
||||
You're so adventurous, I'm so very cautious, combining
|
||||
You think we would and we do, but we do, but we do, but we do
|
||||
|
||||
Instrumental bit!
|
||||
|
||||
Favouritism ain't my thing but,
|
||||
In this situation I'll be glad...
|
||||
|
||||
Favouritism ain't my thing but,in this situation I'll be glad to make an exception
|
||||
|
||||
You said I'm stubborn and I never give in
|
||||
I think you're stubborn 'cept you're always softening
|
||||
You say I'm selfish, I agree with you on that
|
||||
I think you're giving out in way too much in fact
|
||||
I say we've only known each other one year
|
||||
You say I've known you longer my dear
|
||||
You like to be so close, I like to be alone
|
||||
I like to sit on chairs and you prefer the floor
|
||||
Walking with each other, think we'll never match at all, but we do
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,340 @@
|
||||
[Roll up! Roll up for the magical mystery tour!
|
||||
Step right this way!]
|
||||
|
||||
Roll up, roll up for the mystery tour
|
||||
Roll up, roll up for the mystery tour
|
||||
Roll up (And that's an invitation), roll up for the mystery tour
|
||||
Roll up (To make a reservation), roll up for the mystery tour
|
||||
The magical mystery tour is waiting to take you away
|
||||
Waiting to take you away
|
||||
|
||||
Roll up, roll up for the mystery tour
|
||||
Roll up, roll up for the mystery tour
|
||||
Roll up (We've got everything you need), roll up for the mystery tour
|
||||
Roll up (Satisfaction guaranteed), roll up for the mystery tour
|
||||
The magical mystery tour is hoping to take you away
|
||||
Hoping to take you away
|
||||
|
||||
Mystery trip
|
||||
|
||||
Aaaah... the magical mystery tour
|
||||
Roll up, roll up for the mystery tour
|
||||
Roll up (And that's an invitation), roll up for the mystery tour
|
||||
Roll up (To make a reservation), roll up for the mystery tour
|
||||
The magical mystery tour is coming to take you away
|
||||
Coming to take you away
|
||||
The magical mystery tour is dying to take you away
|
||||
Dying to take you away, take you today
|
||||
|
||||
Day after day, alone on the hill
|
||||
The man with the foolish grin is keeping perfectly still
|
||||
But nobody wants to know him
|
||||
They can see that he's just a fool
|
||||
As he never gives an answer
|
||||
But the fool on the hill
|
||||
Sees the sun going down
|
||||
And the eyes in his head
|
||||
See the world spinning around
|
||||
|
||||
Well on the way, head in a cloud
|
||||
The man of a thousand voices talking percetly loud
|
||||
But nobody ever hears him
|
||||
Or the sound he appears to make
|
||||
And he never seems to notice
|
||||
But the fool on the hill
|
||||
Sees the sun going down
|
||||
And the eyes in his head
|
||||
See the world spinning around
|
||||
|
||||
And nobody seems to like him
|
||||
They can tell what he wants to do
|
||||
And he never shows his feelings
|
||||
But the fool on the hill
|
||||
Sees the sun going down
|
||||
And the eyes in his head
|
||||
See the world spinning around
|
||||
|
||||
He never listen to them
|
||||
He knows that they're the fools
|
||||
They don't like him
|
||||
The fool on the hill
|
||||
Sees the sun going down
|
||||
And the eyes in his head
|
||||
See the world spinning around
|
||||
|
||||
I am he as you are he as you are me
|
||||
And we are all together
|
||||
See how they run like pigs from a gun see how they fly
|
||||
I'm crying
|
||||
|
||||
Sitting on a cornflake waiting for the van to come
|
||||
Corporation teeshirt, stupid bloody Tuesday
|
||||
Man you been a naughty boy. You let your face grow long
|
||||
I am the eggman, they are the eggmen
|
||||
I am the walrus, goo goo goo joob
|
||||
|
||||
Mister City Policeman sitting, pretty little policemen in a row
|
||||
See how they fly like Lucy in the sky, see how they run
|
||||
I'm crying, I'm crying
|
||||
I'm crying, I'm crying
|
||||
|
||||
Yellow matter custard dripping from a dead dog's eye
|
||||
Crabalocker fishwife pornographic priestess
|
||||
Boy you been a naughty girl, you let your knickers down
|
||||
I am the eggman, they are the eggmen
|
||||
I am the walrus, goo goo goo joob
|
||||
|
||||
Sitting in an English garden waiting for the sun
|
||||
If the sun don't come
|
||||
You get a tan from standing in the English rain
|
||||
I am the eggman, they are the eggmen
|
||||
I am the walrus, goo goo goo joob goo goo goo goo joob
|
||||
|
||||
Expert textpert choking smokers
|
||||
Don't you think the joker laughs at you? (Ha ha ha! He he he! Ha ha ha!)
|
||||
See how they smile like pigs in a sty, see how they snied
|
||||
I'm crying
|
||||
|
||||
Semolina pilchard climbing up the Eiffel Tower
|
||||
Elementary penguin singing Hare Krishna
|
||||
Man you should have seen them kicking Edgar Alan Poe
|
||||
I am the eggman, they are the eggmen
|
||||
I am the walrus, goo goo goo joob goo goo goo joob
|
||||
Goo goo goo joob goo goo goo joob
|
||||
Goo gooooooooooo jooba jooba jooba jooba jooba jooba
|
||||
Jooba jooba
|
||||
Jooba jooba
|
||||
Jooba jooba
|
||||
|
||||
Let me take you down, cos I'm going to Strawberry Fields
|
||||
Nothing is real and nothing to get hung about
|
||||
Strawberry Fields forever
|
||||
|
||||
Living is easy with eyes closed
|
||||
Misunderstanding all you see
|
||||
It's getting hard to be someone but it all works out
|
||||
It doesn't matter much to me
|
||||
Let me take you down, cos I'm going to Strawberry Fields
|
||||
Nothing is real and nothing to get hung about
|
||||
Strawberry Fields forever
|
||||
|
||||
No one I think is in my tree
|
||||
I mean it must be high or low
|
||||
That is you can't you know tune in but it's all right
|
||||
That is I think it's not too bad
|
||||
Let me take you down, cos I'm going to Strawberry Fields
|
||||
Nothing is real and nothing to get hung about
|
||||
Strawberry Fields forever
|
||||
|
||||
Always, no sometimes, think it's me
|
||||
But you know I know when it's a dream
|
||||
I think I know I mean a "Yes" but it's all wrong
|
||||
That is I think I disagree
|
||||
Let me take you down, cos I'm going to Strawberry Fields
|
||||
Nothing is real and nothing to get hung about
|
||||
Strawberry Fields forever
|
||||
Strawberry Fields forever
|
||||
Strawberry Fields forever
|
||||
|
||||
You say yes, I say no
|
||||
You say stop and I say go go go, oh no
|
||||
You say goodbye and I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
|
||||
I say high, you say low
|
||||
You say why and I say I don't know, oh no
|
||||
You say goodbye and I say hello
|
||||
(Hello goodbye hello goodbye) Hello hello
|
||||
(Hello goodbye) I don't know why you say goodbye, I say hello
|
||||
(Hello goodbye hello goodbye) Hello hello
|
||||
(Hello goodbye) I don't know why you say goodbye
|
||||
(Hello goodbye) I say hello/goodbye
|
||||
|
||||
Why why why why why why do you say goodbye goodbye, oh no?
|
||||
|
||||
You say goodbye and I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
|
||||
You say yes (I say yes) I say no (But I may mean no)
|
||||
You say stop (I can stay) and I say go go go (Till it's time to go), oh
|
||||
Oh no
|
||||
You say goodbye and I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello
|
||||
Hello hello
|
||||
I don't know why you say goodbye, I say hello hello
|
||||
|
||||
Hela heba helloa
|
||||
Hela heba helloa, cha cha cha
|
||||
Hela heba helloa, wooo
|
||||
Hela heba helloa, hela
|
||||
Hela heba helloa, cha cha cha
|
||||
Hela heba helloa, wooo
|
||||
Hela heba helloa, cha cah cah
|
||||
|
||||
Blackbird singing in the dead of night
|
||||
Take these broken wings and learn to fly
|
||||
All your life
|
||||
You were only waiting for this moment to arise.
|
||||
|
||||
Blackbird singing in the dead of night
|
||||
Take these sunken eyes and learn to see
|
||||
All your life
|
||||
You were only waiting for this moment to be free.
|
||||
|
||||
Blackbird fly Blackbird fly
|
||||
Into the light of the dark black night.
|
||||
|
||||
Blackbird fly Blackbird fly
|
||||
Into the light of the dark black night.
|
||||
|
||||
Blackbird singing in the dead of night
|
||||
Take these broken wings and learn to fly
|
||||
All your life
|
||||
You were only waiting for this moment to arise
|
||||
You were only waiting for this moment to arise
|
||||
You were only waiting for this moment to arise.
|
||||
|
||||
In the town where I was born
|
||||
Lived a man who sailed to sea
|
||||
And he told us of his life
|
||||
In the land of submarines
|
||||
|
||||
So we sailed up to the sun
|
||||
Till we found the sea of green
|
||||
And we lived beneath the waves
|
||||
In our yellow submarine
|
||||
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
|
||||
And our friends are all on board
|
||||
Many more of them live next door
|
||||
And the band begins to play
|
||||
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
|
||||
[Full speed ahead, Mr. Parker, full speed ahead!
|
||||
Full speed over here, sir!
|
||||
Action station! Action station!
|
||||
Aye, aye, sir, fire!
|
||||
Heaven! Heaven!]
|
||||
|
||||
As we live a life of ease (A life of ease)
|
||||
Everyone of us (Everyone of us) has all we need (Has all we need)
|
||||
Sky of blue (Sky of blue) and sea of green (Sea of green)
|
||||
In our yellow (In our yellow) submarine (Submarine, ha, ha)
|
||||
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
We all live in a yellow submarine
|
||||
Yellow submarine, yellow submarine
|
||||
|
||||
When I find myself in times of trouble
|
||||
Mother Mary comes to me
|
||||
Speaking words of wisdom, let it be
|
||||
And in my hour of darkness
|
||||
She is standing right in front of me
|
||||
Speaking words of wisdom, let it be
|
||||
Let it be, let it be
|
||||
Let it be, let it be
|
||||
Whisper words of wisdom, let it be
|
||||
|
||||
And when the broken hearted people
|
||||
Living in the world agree
|
||||
There will be an answer, let it be
|
||||
For though they may be parted
|
||||
There is still a chance that they will see
|
||||
There will be an answer, let it be
|
||||
Let it be, let it be
|
||||
Let it be, let it be
|
||||
Yeah there will be an answer, let it be
|
||||
Let it be, let it be
|
||||
Let it be, let it be
|
||||
Whisper words of wisdom, let it be
|
||||
|
||||
Let it be, let it be
|
||||
Ah let it be, yeah let it be
|
||||
Whisper words of wisdom, let it be
|
||||
And when the night is cloudy
|
||||
There is still a light that shines on me
|
||||
Shine on until tomorrow, let it be
|
||||
I wake up to the sound of music,
|
||||
Mother Mary comes to me
|
||||
Speaking words of wisdom, let it be
|
||||
Yeah let it be, let it be
|
||||
Let it be, yeah let it be
|
||||
Oh there will be an answer, let it be
|
||||
Let it be, let it be
|
||||
Let it be, yeah let it be
|
||||
Oh there will be an answer, let it be
|
||||
Let it be, let it be
|
||||
Ah let it be, yeah let it be
|
||||
Whisper words of wisdom, let it be
|
||||
|
||||
Hey Jude, don't make it bad
|
||||
Take a sad song and make it better
|
||||
Remember to let her into your heart
|
||||
Then you can start to make it better
|
||||
|
||||
Hey Jude, don't be afraid
|
||||
You were made to go out and get her
|
||||
The minute you let her under your skin
|
||||
Then you begin to make it better
|
||||
|
||||
And anytime you feel the pain, hey Jude, refrain
|
||||
Don't carry the world upon your shoulders
|
||||
For well you know that it's a fool who plays it cool
|
||||
By making his world a little colder
|
||||
Nah nah nah nah nah nah nah nah nah
|
||||
|
||||
Hey Jude, don't let me down
|
||||
You have found her, now go and get her
|
||||
Remember to let her into your heart
|
||||
Then you can start to make it better
|
||||
|
||||
So let it out and let it in, hey Jude, begin
|
||||
You're waiting for someone to perform with
|
||||
And don't you know that it's just you, hey Jude, you'll do
|
||||
The movement you need is on your shoulder
|
||||
Nah nah nah nah nah nah nah nah nah yeah
|
||||
|
||||
Hey Jude, don't make it bad
|
||||
Take a sad song and make it better
|
||||
Remember to let her under your skin
|
||||
Then you'll begin to make it
|
||||
Better better better better better better, oh
|
||||
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
Nah nah nah nah nah nah, nah nah nah, hey Jude
|
||||
@@ -0,0 +1,447 @@
|
||||
My lover's got humour
|
||||
She's the giggle at a funeral
|
||||
Knows everybody's disapproval
|
||||
I should've worshipped her sooner
|
||||
If the heavens ever did speak
|
||||
She's the last true mouthpiece
|
||||
Every Sunday's getting more bleak
|
||||
A fresh poison each week"We were born sick"
|
||||
You heard them say it
|
||||
My church offers no absolutes
|
||||
She tells me, "Worship in the bedroom"
|
||||
The only heaven I'll be sent to
|
||||
Is when I'm alone with you
|
||||
I was born sick, but I love it
|
||||
Command me to be well
|
||||
A-amen, amen, amen
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, and you can sharpen your knife
|
||||
Offer me that deathless death
|
||||
Good God, let me give you my life
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, and you can sharpen your knife
|
||||
Offer me that deathless death
|
||||
Good God, let me give you my life
|
||||
If I'm a pagan of the good times
|
||||
My lover's the sunlight
|
||||
To keep the Goddess on my side
|
||||
She demands a sacrifice
|
||||
Drain the whole sea
|
||||
Get something shiny
|
||||
Something meaty for the main course
|
||||
That's a fine-looking high horse
|
||||
What you got in the stable?
|
||||
We've a lot of starving faithful
|
||||
That looks tasty
|
||||
That looks plenty
|
||||
This is hungry work
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, so you can sharpen your knife
|
||||
Offer me my deathless death
|
||||
Good God, let me give you my life
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, so you can sharpen your knife
|
||||
Offer me my deathless death
|
||||
Good God, let me give you my life
|
||||
No masters or kings when the ritual begins
|
||||
There is no sweeter innocence than our gentle sin
|
||||
In the madness and soil of that sad earthly scene
|
||||
Only then I am human
|
||||
Only then I am clean
|
||||
Oh, oh, amen, amen, amen
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, and you can sharpen your knife
|
||||
Offer me that deathless death
|
||||
Good God, let me give you my life
|
||||
Take me to church
|
||||
I'll worship like a dog at the shrine of your lies
|
||||
I'll tell you my sins, and you can sharpen your knife
|
||||
Offer me that deathless death
|
||||
Good God, let me give you my life
|
||||
|
||||
|
||||
|
||||
Babe
|
||||
There's something tragic about you
|
||||
Something so magic about you
|
||||
Don't you agreeBabe
|
||||
There's something lonesome about you
|
||||
Something so wholesome about you
|
||||
Get closer to me..
|
||||
No tired sigh, no rolling eyes
|
||||
No irony
|
||||
No 'who cares', no vacant stare
|
||||
No time for me
|
||||
Honey you're familiar
|
||||
Like my mirror years ago
|
||||
Idealism sits in prison
|
||||
Chivalry fell on his sword
|
||||
Innocence died screaming
|
||||
Honey, ask me, I should know
|
||||
I slithered here from Eden
|
||||
Just to sit outside your doorBabe
|
||||
There's something wretched about this
|
||||
Something so precious about this
|
||||
Where to beginBabe
|
||||
there's something broken about this
|
||||
But I might be hoping about this
|
||||
Oh what a sin
|
||||
To the strand, a picnic planned for you and me
|
||||
A rope in hand, for your other man
|
||||
To hang from a treeHoney you're familiar
|
||||
Like my mirror years ago
|
||||
Idealism sits in prison
|
||||
Chivalry fell on his sword
|
||||
Innocence died screaming
|
||||
Honey, ask me, I should know
|
||||
I slithered here from Eden
|
||||
Just to sit outside your door
|
||||
Honey, you're familiar
|
||||
Like my mirror years ago
|
||||
Idealism sits in prison
|
||||
Chilvary fell on his sword
|
||||
Innocence died screaming
|
||||
Honey, ask me, I should know
|
||||
I slithered here from Eden
|
||||
Just to hide outside your door
|
||||
|
||||
|
||||
Boys workin on empty
|
||||
Is that the kinda way to face the burning heat?
|
||||
I just think about my baby
|
||||
I'm so full of love I could barely eat
|
||||
There's nothing sweeter than my baby
|
||||
I never want once from the cherry tree
|
||||
Cause my baby's sweet as can be
|
||||
She give me toothaches just from kissin me
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
That's when my baby found me
|
||||
I was three days on a drunken sin
|
||||
I woke with her walls around me
|
||||
Nothin in her room but an empty crib
|
||||
And I was burnin up a fever
|
||||
I didn't care much how long I lived
|
||||
But I swear I thought I dreamed her
|
||||
She never asked me once about the wrong I did
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
My baby never fret none
|
||||
About what my hands and my body done
|
||||
If the Lord don't forgive me
|
||||
I'd still have my baby and my babe would have me
|
||||
When I was kissing on my baby
|
||||
And she put her love down soft and sweet
|
||||
In the low lamp light I was free
|
||||
Heaven and hell were words to me
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
|
||||
|
||||
When I was a child, I heard voices...
|
||||
Some would sing and some would scream
|
||||
You soon find you have few choices...
|
||||
I learned the voices died with me
|
||||
When I was a child I'd sit for hours
|
||||
Staring into open flame
|
||||
Something in it had a power
|
||||
Could barely tear my eyes away
|
||||
All you have is your fire...
|
||||
And the place you need to reach
|
||||
Don't you ever, tame your demon
|
||||
But always keep 'em on a leash
|
||||
When I was 16 my senses fooled me
|
||||
Thought gasoline was on my clothes
|
||||
I knew that something would always rule me...
|
||||
I knew the scent was mine alone
|
||||
All you have is your fire
|
||||
And the place you need to reach
|
||||
Don't you ever, tame your demon -
|
||||
But always keep 'em on a leash
|
||||
When I was a man I thought it ended
|
||||
When I knew loves perfect ache
|
||||
But my peace has always depended
|
||||
On all the ashes in my way
|
||||
All you have is your fire
|
||||
And the place you need to reach
|
||||
Don't you ever, tame your demons
|
||||
But always keep 'em on a leash...
|
||||
|
||||
|
||||
Her eyes and words are so icy
|
||||
Oh but she burns like rum on the fire
|
||||
Hot and fast and angry as she can be
|
||||
I walk my days on a wireit looks ugly, but it's clean
|
||||
Oh momma, don't fuss over me
|
||||
The way she tells me l'm hers and she is mine
|
||||
Open hand or close fist would be fine
|
||||
The blood is red and sweet as cherry wine
|
||||
Calls of guilty thrown at me
|
||||
All while she stains
|
||||
The sheets of some other
|
||||
Thrown at me so powerfully
|
||||
Just like she throws with the arm of her brother
|
||||
But I want it, it's a crime
|
||||
That she's not around most of the time
|
||||
The way she shows me I'm hers and she is mine
|
||||
Open hand or closed fist would be fine
|
||||
The blood is red and sweet as cherry wine
|
||||
Her fight and fury is fiery
|
||||
Oh but she loves like sleep to the freezing
|
||||
Sweet and right and merciful
|
||||
I'm all but washed in the tide of her breathing
|
||||
And it's worth it, it's divine
|
||||
And I have this some of the time
|
||||
The way she shows me I'm hers and she is mine
|
||||
Open hand or closed fist would be fine
|
||||
The blood is red and sweet as cherry wine
|
||||
|
||||
|
||||
So tired trying to see from behind the red in my eyes
|
||||
No better version of me I could pretend to be tonight
|
||||
So deep in this swill with the most familiar of swine
|
||||
For reasons wretched and divine
|
||||
She blows outta nowhere, roman candle of the wild
|
||||
Laughing away through my feeble disguise
|
||||
No other version of me I would rather be tonight.
|
||||
And, Lord, she found me just in time
|
||||
'Cause with my mid-youth crisis all said and done
|
||||
I need to be youthfully felt 'cause, God, I never felt young
|
||||
She's gonna save me,
|
||||
Call me "baby"
|
||||
Run her hands through my hair
|
||||
She'll know me crazy
|
||||
Soothe me daily
|
||||
Better yet she wouldn't care
|
||||
We'll steal her Lexus,
|
||||
Be detectives,
|
||||
Ride 'round picking up clues
|
||||
We'll name our children
|
||||
Jackie and Wilson
|
||||
Raise 'em on rhythm and blues
|
||||
Lord, it'd be great to find a place we could escape sometime
|
||||
Me and my Isis growing black irises in the sunshine
|
||||
Every version of me dead and buried in the yard outside
|
||||
Sit back and watch the world go by.
|
||||
Happy to lie back watch it burn and rust
|
||||
We tried the world, good God, it wasn't for us.
|
||||
She's gonna save me,
|
||||
Call me "baby"
|
||||
Run her hands through my hair
|
||||
She'll know me crazy,
|
||||
Soothe me daily
|
||||
Better yet she wouldn't care
|
||||
We'll steal her Lexus,
|
||||
Be detectives,
|
||||
Ride 'round picking up clues
|
||||
We'll name our children
|
||||
Jackie and Wilson,
|
||||
Raise 'em on rhythm and blues
|
||||
Cut clean from the dream at night let my mind reset
|
||||
Looking up from a cigarette, and she's already left
|
||||
I start digging up the yard for what's left of me and our little vignette
|
||||
For whatever poor soul is coming next
|
||||
She's gonna save me,
|
||||
Call me "baby"
|
||||
Run her hands through my hair
|
||||
She'll know me crazy,
|
||||
Soothe me daily
|
||||
Better yet she wouldn't care
|
||||
We'll steal her Lexus,
|
||||
Be detectives,
|
||||
Ride 'round picking up clues
|
||||
We'll name our children
|
||||
Jackie and Wilson
|
||||
Raise 'em on rhythm and blues
|
||||
|
||||
|
||||
|
||||
I have never known peace like the damp grass that yields to me
|
||||
I have never known hunger like these insects that feast on me
|
||||
A thousand teeth and yours among them, I know
|
||||
Our hungers appeased, our heart beats becoming slow
|
||||
We'll lay here for years or for hours
|
||||
Thrown here or found, to freeze or to thaw
|
||||
So long, we'd become the flowers
|
||||
Two corpses we were, two corpses I saw
|
||||
And they'd find us in a week
|
||||
When the weather gets hot
|
||||
After the insects have made their claim
|
||||
I'll be home with you, I'll be home with you
|
||||
I have never known sleep like this slumber that creeps to me
|
||||
I have never known colors like this morning reveals to me
|
||||
And you haven't moved an inch such that I would not know
|
||||
If you sleep always like this, flesh calmly going cold
|
||||
We'll lay here for years or for hours
|
||||
Your hand in my hand, so still and discreet
|
||||
So long, we'd become the flowers
|
||||
We'd feed well the land and worry the sheep
|
||||
And they'd find us in a week
|
||||
When the cattle'd show fear
|
||||
After the insects have made their claim
|
||||
After the foxes have known our taste
|
||||
I'll be home with you, I'll be home with you
|
||||
And they'd find us in a week
|
||||
When the weather gets hot
|
||||
And they'd find us in a week
|
||||
When the cattle'd show fear
|
||||
And they'd find us in a week
|
||||
When the buzzards get loud
|
||||
After the insects have made their claim
|
||||
After the foxes have known our taste
|
||||
After the raven has had his say
|
||||
I'll be home with you, I'll be home with you
|
||||
I'll be home with you, I'll be home with you
|
||||
I'll be home with you, I'll be home with you
|
||||
|
||||
|
||||
Don't take this the wrong way
|
||||
You knew who I was every step that I ran to you
|
||||
Only blue or black days
|
||||
Electing strange perfections in any stranger I choose.
|
||||
Would things be easier if there was a right way
|
||||
Honey there is no right way.
|
||||
And so I fall in love just a little ol' little bit
|
||||
Every day with someone new
|
||||
I fall in love just a little ol' little bit every day with someone new
|
||||
There's an art to life's distractions
|
||||
Somehow escapes the burning weight the art of scraping through
|
||||
Some like to imagine
|
||||
The dark thrills of someone else I guess any thrill will do.
|
||||
Would things be easier if there was a right way
|
||||
Honey there is no right way.
|
||||
And so I fall in love just a little ol' little bit
|
||||
Every day with someone new
|
||||
I fall in love just a little ol' little bit every day with someone new
|
||||
I wake at the first crink of morning
|
||||
And my heart's already sinned.
|
||||
How pure, how sweet a love, Aretha, that you would pray for him?
|
||||
'Cause God knows I fall in love just a little ol' little bit
|
||||
Every day with someone new
|
||||
I fall in love just a little ol' little bit every day with someone new
|
||||
I fall in love just a little ol' little bit every day.
|
||||
Love with every stranger the stranger the better
|
||||
I fall in love just a little ol' little bit every day with someone new
|
||||
|
||||
|
||||
I had a thought, dear
|
||||
However scary
|
||||
About that night
|
||||
The bugs and the dirt
|
||||
Why were you digging?
|
||||
What did you bury
|
||||
Before those hands pulled me
|
||||
From the earth?
|
||||
I will not ask you where you came from
|
||||
I will not ask and neither should you
|
||||
Honey just put your sweet lips on my lips
|
||||
We should just kiss like real people do
|
||||
I knew that look dear
|
||||
Eyes always seeking
|
||||
Was there in someone
|
||||
That dug long ago
|
||||
So I will not ask you
|
||||
Why you were creeping
|
||||
In some sad way I already know
|
||||
So I will not ask you where you came from
|
||||
I would not ask and neither would you
|
||||
Honey just put your sweet lips on my lips
|
||||
We should just kiss like real people do
|
||||
|
||||
|
||||
Never feel too good in crowds
|
||||
With folks around when they're playing
|
||||
The anthems of rape, culture loud
|
||||
Crude and proud creatures baying
|
||||
All I've ever done is hide
|
||||
From our times when you're near me
|
||||
Honey, when you kill the lights and kiss my eyes
|
||||
I feel like a person for a moment of my life
|
||||
But you don't know what hell you put me through
|
||||
To have someone kiss the skin that crawls from you
|
||||
To feel your weight in arms I'd never use
|
||||
It's the god that heroin prays to
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
To be alone with you
|
||||
There are questions I can't ask
|
||||
Now at last the worst is over
|
||||
See the way you hold yourself
|
||||
Reel against your body's borders
|
||||
And I know that you hate this place
|
||||
Not a trace of me would argue
|
||||
Honey, we should run away, oh, someday
|
||||
Our baby and her momma
|
||||
And the damaged love she makes
|
||||
But I don't know what else that I would do
|
||||
Than try to kiss the skin that crawls from you
|
||||
Than feel your weight in arms I'd never use
|
||||
It's the god that heroin prays to
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
To be alone with you
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
It feels good, girl, it feels good
|
||||
To be alone with you
|
||||
|
||||
|
||||
Just a little rush, babe
|
||||
To feel dizzy, to derail the mind of me
|
||||
Just a little hush, babe
|
||||
Our veins are busy but my heart's in atrophy
|
||||
Any way to distract and sedate
|
||||
Adding shadows to the walls of the cave
|
||||
You and I nursing on a poison that never stung
|
||||
Our teeth and lungs are lined with the scum of it
|
||||
Some whiff of this, death and guts
|
||||
We are deaf, we are numb
|
||||
Free and young and we can feel none of it
|
||||
Something isn't right, babe
|
||||
I keep catching little words but the meaning's thin
|
||||
I'm somewhere outside my life, babe
|
||||
I keep scratching but somehow I can't get in
|
||||
So we're slaves to any semblance of touch
|
||||
Lord we should quit but we love it too much
|
||||
Sedated we're nursing on a poison that never stung
|
||||
Our teeth and lungs are lined with the scum of it
|
||||
Some whiff of this, death and guts
|
||||
We are deaf, we are numb
|
||||
Free and young and we can feel none of it
|
||||
Darlin', don't you, stand there watching, won't you
|
||||
Come and save me from it
|
||||
Darlin', don't you, join in, you're supposed to
|
||||
Drag me away from it
|
||||
Any way to distract and sedate
|
||||
Adding shadows to the walls of the cave
|
||||
You and I nursing on a poison that never stung
|
||||
Our teeth and lungs are lined with the scum of it
|
||||
Some whiff of this, death and guts
|
||||
We are deaf, we are numb
|
||||
Free and young and we can feel none of it
|
||||
Sedated we're nursing on a poison that never stung
|
||||
Our teeth and lungs are lined with the scum of it
|
||||
Some whiff of this, death and guts
|
||||
We are deaf, we are numb
|
||||
Free and young and we can feel none of it
|
||||
@@ -0,0 +1,70 @@
|
||||
Title: Take Me To Church
|
||||
|
||||
My lover's got humour
|
||||
She's the giggle at a funeral
|
||||
Knows everybody's disapproval
|
||||
I should've worshipped her sooner
|
||||
|
||||
If the heavens ever did speak
|
||||
She's the last true mouthpiece
|
||||
Every Sunday's getting more bleak
|
||||
A fresh poison each week
|
||||
|
||||
"We were born sick"
|
||||
You heard them say it
|
||||
|
||||
My church offers no absolutes
|
||||
She tells me, "Worship in the bedroom"
|
||||
The only heaven I'll be sent to
|
||||
Is when I'm alone with you
|
||||
|
||||
|
||||
Title: From Eden
|
||||
|
||||
Babe
|
||||
There's something tragic about you
|
||||
Something so magic about you
|
||||
Don't you agree
|
||||
|
||||
Babe
|
||||
There's something lonesome about you
|
||||
Something so wholesome about you
|
||||
Get closer to me..
|
||||
|
||||
No tired sigh, no rolling eyes
|
||||
No irony
|
||||
No 'who cares', no vacant stare
|
||||
No time for me
|
||||
|
||||
Honey you're familiar
|
||||
Like my mirror years ago
|
||||
Idealism sits in prison
|
||||
Chivalry fell on his sword
|
||||
Innocence died screaming
|
||||
|
||||
|
||||
Title: Work Song
|
||||
|
||||
Boys workin on empty
|
||||
Is that the kinda way to face the burning heat?
|
||||
I just think about my baby
|
||||
I'm so full of love I could barely eat
|
||||
There's nothing sweeter than my baby
|
||||
I never want once from the cherry tree
|
||||
Cause my baby's sweet as can be
|
||||
She give me toothaches just from kissin me
|
||||
|
||||
When, my, time comes around
|
||||
Lay me gently in the cold dark earth
|
||||
No grave can hold my body down
|
||||
I'll crawl home to her
|
||||
|
||||
That's when my baby found me
|
||||
I was three days on a drunken sin
|
||||
I woke with her walls around me
|
||||
Nothin in her room but an empty crib
|
||||
And I was burnin up a fever
|
||||
I didn't care much how long I lived
|
||||
But I swear I thought I dreamed her
|
||||
She never asked me once about the wrong I did
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.
|
||||
Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.
|
||||
A small river named Duden flows by their place and supplies it with the necessary regelialia.
|
||||
It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
|
||||
Even the all powerful Pointing has no control about the blind texts it is an almost unorthographic life One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
|
||||
The Big Oxmox advised her not to do so, because there were thousands of bad Commas, wild Question Marks and devious Semikoli, but the Little Blind Text didn't listen. She packed her seven versalia, put her initial into the belt and made herself on the way.
|
||||
When she reached the first hills of the Italic Mountains, she had a last view back on the skyline of her hometown Bookmarksgrove, the headline of Alphabet Village and the subline of her own road, the Line Lane.
|
||||
Pityful a rethoric question ran over her cheek, then she continued her way. On her way she met a copy. The copy warned the Little Blind Text, that where it came from it would have been rewritten a thousand times and everything that was left from its origin would be the word "and" and the Little Blind Text should turn around and return to its own, safe country.
|
||||
But nothing the copy said could convince her and so it didn't take long until a few insidious Copy Writers ambushed her, made her drunk with Longe and Parole and dragged her into their agency, where they abused her for their projects again and again. And if she hasn't been rewritten, then they are still using her.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,218 @@
|
||||
Its Dark in Here
|
||||
|
||||
I am writing these poems
|
||||
From inside a lion,
|
||||
And it's rather dark in here.
|
||||
|
||||
So please excuse the handwriting
|
||||
Which may not be too clear.
|
||||
|
||||
But this afternoon by the lion's cage
|
||||
I'm afraid I got too near.
|
||||
|
||||
And I'm writing these lines
|
||||
From inside a lion,
|
||||
And it's rather dark in here.
|
||||
|
||||
|
||||
Boa Constrictor
|
||||
|
||||
Oh, I'm being eaten
|
||||
By a boa constrictor,
|
||||
A boa constrictor,
|
||||
A boa constrictor,
|
||||
I'm being eaten by a boa constrictor,
|
||||
And I don't like it--one bit.
|
||||
|
||||
Well, what do you know?
|
||||
It's nibblin' my toe.
|
||||
|
||||
Oh, gee,
|
||||
It's up to my knee.
|
||||
|
||||
Oh my,
|
||||
It's up to my thigh.
|
||||
|
||||
Oh, fiddle,
|
||||
It's up to my middle.
|
||||
|
||||
Oh, heck,
|
||||
It's up to my neck.
|
||||
|
||||
Oh, dread,
|
||||
It's upmmmmmmmmmmffffffffff .
|
||||
.
|
||||
.
|
||||
|
||||
|
||||
Where the Sidewalk Ends
|
||||
|
||||
There is a place where the sidewalk ends
|
||||
And before the street begins,
|
||||
And there the grass grows soft and white,
|
||||
And there the sun burns crimson bright,
|
||||
And there the moon-bird rests from his flight
|
||||
To cool in the peppermint wind.
|
||||
|
||||
Let us leave this place where the smoke blows black
|
||||
And the dark street winds and bends.
|
||||
Past the pits where the asphalt flowers grow
|
||||
We shall walk with a walk that is measured and slow,
|
||||
And watch where the chalk-white arrows go
|
||||
To the place where the sidewalk ends.
|
||||
|
||||
Yes we'll walk with a walk that is measured and slow,
|
||||
And we'll go where the chalk-white arrows go,
|
||||
For the children, they mark, and the children, they know
|
||||
|
||||
|
||||
One Inch Tall
|
||||
|
||||
If you were only one inch tall, you'd ride a worm to school.
|
||||
|
||||
The teardrop of a crying ant would be your swimming pool.
|
||||
|
||||
A crumb of cake would be a feast
|
||||
And last you seven days at least,
|
||||
A flea would be a frightening beast
|
||||
If you were one inch tall.
|
||||
|
||||
|
||||
If you were only one inch tall, you'd walk beneath the door,
|
||||
And it would take about a month to get down to the store.
|
||||
|
||||
A bit of fluff would be your bed,
|
||||
You'd swing upon a spider's thread,
|
||||
And wear a thimble on your head
|
||||
If you were one inch tall.
|
||||
|
||||
|
||||
You'd surf across the kitchen sink upon a stick of gum.
|
||||
|
||||
You couldn't hug your mama, you'd just have to hug her thumb.
|
||||
|
||||
You'd run from people's feet in fright,
|
||||
To move a pen would take all night,
|
||||
(This poem took fourteen years to write--
|
||||
'Cause I'm just one inch tall).
|
||||
|
||||
|
||||
Rain
|
||||
|
||||
I opened my eyes
|
||||
And looked up at the rain,
|
||||
And it dripped in my head
|
||||
And flowed into my brain,
|
||||
And all that I hear as I lie in my bed
|
||||
Is the slishity-slosh of the rain in my head.
|
||||
|
||||
|
||||
I step very softly,
|
||||
I walk very slow,
|
||||
I can't do a handstand--
|
||||
I might overflow,
|
||||
So pardon the wild crazy thing I just said--
|
||||
I'm just not the same since there's rain in my head.
|
||||
|
||||
|
||||
|
||||
Whatif
|
||||
|
||||
|
||||
Last night, while I lay thinking here,
|
||||
some Whatifs crawled inside my ear
|
||||
and pranced and partied all night long
|
||||
and sang their same old Whatif song:
|
||||
Whatif I'm dumb in school?
|
||||
Whatif they've closed the swimming pool?
|
||||
Whatif I get beat up?
|
||||
Whatif there's poison in my cup?
|
||||
Whatif I start to cry?
|
||||
Whatif I get sick and die?
|
||||
Whatif I flunk that test?
|
||||
Whatif green hair grows on my chest?
|
||||
Whatif nobody likes me?
|
||||
Whatif a bolt of lightning strikes me?
|
||||
Whatif I don't grow talle?
|
||||
Whatif my head starts getting smaller?
|
||||
Whatif the fish won't bite?
|
||||
Whatif the wind tears up my kite?
|
||||
Whatif they start a war?
|
||||
Whatif my parents get divorced?
|
||||
Whatif the bus is late?
|
||||
Whatif my teeth don't grow in straight?
|
||||
Whatif I tear my pants?
|
||||
Whatif I never learn to dance?
|
||||
Everything seems well, and then
|
||||
the nighttime Whatifs strike again!
|
||||
|
||||
|
||||
I cannot go to school today!
|
||||
|
||||
I cannot go to school today!
|
||||
by Shel Silverstein
|
||||
"I cannot go to school today"
|
||||
Said little Peggy Ann McKay.
|
||||
"I have the measles and the mumps,
|
||||
A gash, a rash and purple bumps.
|
||||
|
||||
My mouth is wet, my throat is dry.
|
||||
I'm going blind in my right eye.
|
||||
My tonsils are as big as rocks,
|
||||
I've counted sixteen chicken pox.
|
||||
|
||||
And there's one more - that's seventeen,
|
||||
And don't you think my face looks green?
|
||||
My leg is cut, my eyes are blue,
|
||||
It might be the instamatic flu.
|
||||
|
||||
I cough and sneeze and gasp and choke,
|
||||
I'm sure that my left leg is broke.
|
||||
My hip hurts when I move my chin,
|
||||
My belly button's caving in.
|
||||
|
||||
My back is wrenched, my ankle's sprained,
|
||||
My 'pendix pains each time it rains.
|
||||
My toes are cold, my toes are numb,
|
||||
I have a sliver in my thumb.
|
||||
|
||||
My neck is stiff, my voice is weak,
|
||||
I hardly whisper when I speak.
|
||||
My tongue is filling up my mouth,
|
||||
I think my hair is falling out.
|
||||
|
||||
My elbow's bent, my spine ain't straight,
|
||||
My temperature is one-o-eight.
|
||||
My brain is shrunk, I cannot hear,
|
||||
There is a hole inside my ear.
|
||||
|
||||
I have a hangnail, and my heart is ...
|
||||
What? What's that? What's that you say?
|
||||
You say today is .............. Saturday?
|
||||
G'bye, I'm going out to play!"
|
||||
|
||||
|
||||
Messy Room
|
||||
|
||||
Whosever room this is should be ashamed!
|
||||
His underwear is hanging on the lamp.
|
||||
|
||||
His raincoat is there in the overstuffed chair,
|
||||
And the chair is becoming quite mucky and damp.
|
||||
|
||||
His workbook is wedged in the window,
|
||||
His sweater's been thrown on the floor.
|
||||
|
||||
His scarf and one ski are beneath the TV,
|
||||
And his pants have been carelessly hung on the door.
|
||||
|
||||
His books are all jammed in the closet,
|
||||
His vest has been left in the hall.
|
||||
|
||||
A lizard named Ed is asleep in his bed,
|
||||
And his smelly old sock has been stuck to the wall.
|
||||
|
||||
Whosever room this is should be ashamed!
|
||||
Donald or Robert or Willie or--
|
||||
Huh? You say it's mine? Oh, dear,
|
||||
I knew it looked familiar!
|
||||
@@ -0,0 +1,2 @@
|
||||
Did you get the sword from the old man on top of the waterfall?
|
||||
It's too dangerous to go alone from the old waterfall.
|
||||
@@ -0,0 +1,964 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- saved from url=(0070)https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/ -->
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
|
||||
<meta name="generator" content="pandoc">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
<title>CSC110 Assignment 3: Loops, Mutation, and Applications</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||
div.sourceCode { margin: 1em 0; }
|
||||
pre.sourceCode { margin: 0; }
|
||||
@media screen {
|
||||
div.sourceCode { overflow: auto; }
|
||||
}
|
||||
@media print {
|
||||
pre > code.sourceCode { white-space: pre-wrap; }
|
||||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||
}
|
||||
pre.numberSource code
|
||||
{ counter-reset: source-line 0; }
|
||||
pre.numberSource code > span
|
||||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||
pre.numberSource code > span > a:first-child::before
|
||||
{ content: counter(source-line);
|
||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||
border: none; display: inline-block;
|
||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||
-khtml-user-select: none; -moz-user-select: none;
|
||||
-ms-user-select: none; user-select: none;
|
||||
padding: 0 4px; width: 4em;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
||||
div.sourceCode
|
||||
{ }
|
||||
@media screen {
|
||||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||
}
|
||||
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
||||
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
||||
code span.at { color: #7d9029; } /* Attribute */
|
||||
code span.bn { color: #40a070; } /* BaseN */
|
||||
code span.bu { } /* BuiltIn */
|
||||
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
||||
code span.ch { color: #4070a0; } /* Char */
|
||||
code span.cn { color: #880000; } /* Constant */
|
||||
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
||||
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
||||
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
||||
code span.dt { color: #902000; } /* DataType */
|
||||
code span.dv { color: #40a070; } /* DecVal */
|
||||
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
||||
code span.ex { } /* Extension */
|
||||
code span.fl { color: #40a070; } /* Float */
|
||||
code span.fu { color: #06287e; } /* Function */
|
||||
code span.im { } /* Import */
|
||||
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
||||
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
||||
code span.op { color: #666666; } /* Operator */
|
||||
code span.ot { color: #007020; } /* Other */
|
||||
code span.pp { color: #bc7a00; } /* Preprocessor */
|
||||
code span.sc { color: #4070a0; } /* SpecialChar */
|
||||
code span.ss { color: #bb6688; } /* SpecialString */
|
||||
code span.st { color: #4070a0; } /* String */
|
||||
code span.va { color: #19177c; } /* Variable */
|
||||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||
</style>
|
||||
<link rel="stylesheet" href="./handout_files/pandoc.css">
|
||||
<script src="./handout_files/tex-mml-chtml.js" type="text/javascript"></script><style type="text/css">.CtxtMenu_InfoClose { top:.2em; right:.2em;}
|
||||
.CtxtMenu_InfoContent { overflow:auto; text-align:left; font-size:80%; padding:.4em .6em; border:1px inset; margin:1em 0px; max-height:20em; max-width:30em; background-color:#EEEEEE; white-space:normal;}
|
||||
.CtxtMenu_Info.CtxtMenu_MousePost {outline:none;}
|
||||
.CtxtMenu_Info { position:fixed; left:50%; width:auto; text-align:center; border:3px outset; padding:1em 2em; background-color:#DDDDDD; color:black; cursor:default; font-family:message-box; font-size:120%; font-style:normal; text-indent:0; text-transform:none; line-height:normal; letter-spacing:normal; word-spacing:normal; word-wrap:normal; white-space:nowrap; float:none; z-index:201; border-radius: 15px; /* Opera 10.5 and IE9 */ -webkit-border-radius:15px; /* Safari and Chrome */ -moz-border-radius:15px; /* Firefox */ -khtml-border-radius:15px; /* Konqueror */ box-shadow:0px 10px 20px #808080; /* Opera 10.5 and IE9 */ -webkit-box-shadow:0px 10px 20px #808080; /* Safari 3 & Chrome */ -moz-box-shadow:0px 10px 20px #808080; /* Forefox 3.5 */ -khtml-box-shadow:0px 10px 20px #808080; /* Konqueror */ filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="gray", Positive="true"); /* IE */}
|
||||
</style><style type="text/css">.CtxtMenu_MenuClose { position:absolute; cursor:pointer; display:inline-block; border:2px solid #AAA; border-radius:18px; -webkit-border-radius: 18px; /* Safari and Chrome */ -moz-border-radius: 18px; /* Firefox */ -khtml-border-radius: 18px; /* Konqueror */ font-family: "Courier New", Courier; font-size:24px; color:#F0F0F0}
|
||||
.CtxtMenu_MenuClose span { display:block; background-color:#AAA; border:1.5px solid; border-radius:18px; -webkit-border-radius: 18px; /* Safari and Chrome */ -moz-border-radius: 18px; /* Firefox */ -khtml-border-radius: 18px; /* Konqueror */ line-height:0; padding:8px 0 6px /* may need to be browser-specific */}
|
||||
.CtxtMenu_MenuClose:hover { color:white!important; border:2px solid #CCC!important}
|
||||
.CtxtMenu_MenuClose:hover span { background-color:#CCC!important}
|
||||
.CtxtMenu_MenuClose:hover:focus { outline:none}
|
||||
</style><style type="text/css">.CtxtMenu_Menu { position:absolute; background-color:white; color:black; width:auto; padding:5px 0px; border:1px solid #CCCCCC; margin:0; cursor:default; font: menu; text-align:left; text-indent:0; text-transform:none; line-height:normal; letter-spacing:normal; word-spacing:normal; word-wrap:normal; white-space:nowrap; float:none; z-index:201; border-radius: 5px; /* Opera 10.5 and IE9 */ -webkit-border-radius: 5px; /* Safari and Chrome */ -moz-border-radius: 5px; /* Firefox */ -khtml-border-radius: 5px; /* Konqueror */ box-shadow:0px 10px 20px #808080; /* Opera 10.5 and IE9 */ -webkit-box-shadow:0px 10px 20px #808080; /* Safari 3 & Chrome */ -moz-box-shadow:0px 10px 20px #808080; /* Forefox 3.5 */ -khtml-box-shadow:0px 10px 20px #808080; /* Konqueror */}
|
||||
.CtxtMenu_MenuItem { padding: 1px 2em; background:transparent;}
|
||||
.CtxtMenu_MenuArrow { position:absolute; right:.5em; padding-top:.25em; color:#666666; font-family: null; font-size: .75em}
|
||||
.CtxtMenu_MenuActive .CtxtMenu_MenuArrow {color:white}
|
||||
.CtxtMenu_MenuArrow.CtxtMenu_RTL {left:.5em; right:auto}
|
||||
.CtxtMenu_MenuCheck { position:absolute; left:.7em; font-family: null}
|
||||
.CtxtMenu_MenuCheck.CtxtMenu_RTL { right:.7em; left:auto }
|
||||
.CtxtMenu_MenuRadioCheck { position:absolute; left: .7em;}
|
||||
.CtxtMenu_MenuRadioCheck.CtxtMenu_RTL { right: .7em; left:auto}
|
||||
.CtxtMenu_MenuInputBox { padding-left: 1em; right:.5em; color:#666666; font-family: null;}
|
||||
.CtxtMenu_MenuInputBox.CtxtMenu_RTL { left: .1em;}
|
||||
.CtxtMenu_MenuComboBox { left:.1em; padding-bottom:.5em;}
|
||||
.CtxtMenu_MenuSlider { left: .1em;}
|
||||
.CtxtMenu_SliderValue { position:absolute; right:.1em; padding-top:.25em; color:#333333; font-size: .75em}
|
||||
.CtxtMenu_SliderBar { outline: none; background: #d3d3d3}
|
||||
.CtxtMenu_MenuLabel { padding: 1px 2em 3px 1.33em; font-style:italic}
|
||||
.CtxtMenu_MenuRule { border-top: 1px solid #DDDDDD; margin: 4px 3px;}
|
||||
.CtxtMenu_MenuDisabled { color:GrayText}
|
||||
.CtxtMenu_MenuActive { background-color: #606872; color: white;}
|
||||
.CtxtMenu_MenuDisabled:focus { background-color: #E8E8E8}
|
||||
.CtxtMenu_MenuLabel:focus { background-color: #E8E8E8}
|
||||
.CtxtMenu_ContextMenu:focus { outline:none}
|
||||
.CtxtMenu_ContextMenu .CtxtMenu_MenuItem:focus { outline:none}
|
||||
.CtxtMenu_SelectionMenu { position:relative; float:left; border-bottom: none; -webkit-box-shadow:none; -webkit-border-radius:0px; }
|
||||
.CtxtMenu_SelectionItem { padding-right: 1em;}
|
||||
.CtxtMenu_Selection { right: 40%; width:50%; }
|
||||
.CtxtMenu_SelectionBox { padding: 0em; max-height:20em; max-width: none; background-color:#FFFFFF;}
|
||||
.CtxtMenu_SelectionDivider { clear: both; border-top: 2px solid #000000;}
|
||||
.CtxtMenu_Menu .CtxtMenu_MenuClose { top:-10px; left:-10px}
|
||||
</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
<style id="MJX-CHTML-styles">
|
||||
mjx-container[jax="CHTML"] {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
mjx-container [space="1"] {
|
||||
margin-left: .111em;
|
||||
}
|
||||
|
||||
mjx-container [space="2"] {
|
||||
margin-left: .167em;
|
||||
}
|
||||
|
||||
mjx-container [space="3"] {
|
||||
margin-left: .222em;
|
||||
}
|
||||
|
||||
mjx-container [space="4"] {
|
||||
margin-left: .278em;
|
||||
}
|
||||
|
||||
mjx-container [space="5"] {
|
||||
margin-left: .333em;
|
||||
}
|
||||
|
||||
mjx-container [rspace="1"] {
|
||||
margin-right: .111em;
|
||||
}
|
||||
|
||||
mjx-container [rspace="2"] {
|
||||
margin-right: .167em;
|
||||
}
|
||||
|
||||
mjx-container [rspace="3"] {
|
||||
margin-right: .222em;
|
||||
}
|
||||
|
||||
mjx-container [rspace="4"] {
|
||||
margin-right: .278em;
|
||||
}
|
||||
|
||||
mjx-container [rspace="5"] {
|
||||
margin-right: .333em;
|
||||
}
|
||||
|
||||
mjx-container [size="s"] {
|
||||
font-size: 70.7%;
|
||||
}
|
||||
|
||||
mjx-container [size="ss"] {
|
||||
font-size: 50%;
|
||||
}
|
||||
|
||||
mjx-container [size="Tn"] {
|
||||
font-size: 60%;
|
||||
}
|
||||
|
||||
mjx-container [size="sm"] {
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
mjx-container [size="lg"] {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
mjx-container [size="Lg"] {
|
||||
font-size: 144%;
|
||||
}
|
||||
|
||||
mjx-container [size="LG"] {
|
||||
font-size: 173%;
|
||||
}
|
||||
|
||||
mjx-container [size="hg"] {
|
||||
font-size: 207%;
|
||||
}
|
||||
|
||||
mjx-container [size="HG"] {
|
||||
font-size: 249%;
|
||||
}
|
||||
|
||||
mjx-container [width="full"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mjx-box {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mjx-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mjx-itable {
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
mjx-row {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
mjx-row > * {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
mjx-mtext {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mjx-mstyle {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mjx-merror {
|
||||
display: inline-block;
|
||||
color: red;
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
mjx-mphantom {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
_::-webkit-full-page-media, _:future, :root mjx-container {
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
mjx-assistive-mml {
|
||||
position: absolute !important;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
padding: 1px 0px 0px 0px !important;
|
||||
border: 0px !important;
|
||||
display: block !important;
|
||||
width: auto !important;
|
||||
overflow: hidden !important;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
mjx-assistive-mml[display="block"] {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
mjx-math {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
line-height: 0;
|
||||
text-indent: 0;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 100%;
|
||||
font-size-adjust: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
word-spacing: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
padding: 1px 0;
|
||||
}
|
||||
|
||||
mjx-container[jax="CHTML"][display="true"] {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
mjx-container[jax="CHTML"][display="true"][width="full"] {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
mjx-container[jax="CHTML"][display="true"] mjx-math {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
mjx-container[jax="CHTML"][justify="left"] {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
mjx-container[jax="CHTML"][justify="right"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
mjx-mo {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
mjx-stretchy-h {
|
||||
display: inline-table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > * {
|
||||
display: table-cell;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > * > mjx-c {
|
||||
display: inline-block;
|
||||
transform: scalex(1.0000001);
|
||||
}
|
||||
|
||||
mjx-stretchy-h > * > mjx-c::before {
|
||||
display: inline-block;
|
||||
width: initial;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > mjx-ext {
|
||||
/* IE */ overflow: hidden;
|
||||
/* others */ overflow: clip visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > mjx-ext > mjx-c::before {
|
||||
transform: scalex(500);
|
||||
}
|
||||
|
||||
mjx-stretchy-h > mjx-ext > mjx-c {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > mjx-beg > mjx-c {
|
||||
margin-right: -.1em;
|
||||
}
|
||||
|
||||
mjx-stretchy-h > mjx-end > mjx-c {
|
||||
margin-left: -.1em;
|
||||
}
|
||||
|
||||
mjx-stretchy-v {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > * {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > mjx-beg {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > mjx-end > mjx-c {
|
||||
display: block;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > * > mjx-c {
|
||||
transform: scaley(1.0000001);
|
||||
transform-origin: left center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > mjx-ext {
|
||||
display: block;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0px solid transparent;
|
||||
/* IE */ overflow: hidden;
|
||||
/* others */ overflow: visible clip;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > mjx-ext > mjx-c::before {
|
||||
width: initial;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
mjx-stretchy-v > mjx-ext > mjx-c {
|
||||
transform: scaleY(500) translateY(.075em);
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
mjx-mark {
|
||||
display: inline-block;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
mjx-c {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
mjx-utext {
|
||||
display: inline-block;
|
||||
padding: .75em 0 .2em 0;
|
||||
}
|
||||
|
||||
mjx-mn {
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
mjx-c::before {
|
||||
display: block;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.MJX-TEX {
|
||||
font-family: MJXZERO, MJXTEX;
|
||||
}
|
||||
|
||||
.TEX-B {
|
||||
font-family: MJXZERO, MJXTEX-B;
|
||||
}
|
||||
|
||||
.TEX-I {
|
||||
font-family: MJXZERO, MJXTEX-I;
|
||||
}
|
||||
|
||||
.TEX-MI {
|
||||
font-family: MJXZERO, MJXTEX-MI;
|
||||
}
|
||||
|
||||
.TEX-BI {
|
||||
font-family: MJXZERO, MJXTEX-BI;
|
||||
}
|
||||
|
||||
.TEX-S1 {
|
||||
font-family: MJXZERO, MJXTEX-S1;
|
||||
}
|
||||
|
||||
.TEX-S2 {
|
||||
font-family: MJXZERO, MJXTEX-S2;
|
||||
}
|
||||
|
||||
.TEX-S3 {
|
||||
font-family: MJXZERO, MJXTEX-S3;
|
||||
}
|
||||
|
||||
.TEX-S4 {
|
||||
font-family: MJXZERO, MJXTEX-S4;
|
||||
}
|
||||
|
||||
.TEX-A {
|
||||
font-family: MJXZERO, MJXTEX-A;
|
||||
}
|
||||
|
||||
.TEX-C {
|
||||
font-family: MJXZERO, MJXTEX-C;
|
||||
}
|
||||
|
||||
.TEX-CB {
|
||||
font-family: MJXZERO, MJXTEX-CB;
|
||||
}
|
||||
|
||||
.TEX-FR {
|
||||
font-family: MJXZERO, MJXTEX-FR;
|
||||
}
|
||||
|
||||
.TEX-FRB {
|
||||
font-family: MJXZERO, MJXTEX-FRB;
|
||||
}
|
||||
|
||||
.TEX-SS {
|
||||
font-family: MJXZERO, MJXTEX-SS;
|
||||
}
|
||||
|
||||
.TEX-SSB {
|
||||
font-family: MJXZERO, MJXTEX-SSB;
|
||||
}
|
||||
|
||||
.TEX-SSI {
|
||||
font-family: MJXZERO, MJXTEX-SSI;
|
||||
}
|
||||
|
||||
.TEX-SC {
|
||||
font-family: MJXZERO, MJXTEX-SC;
|
||||
}
|
||||
|
||||
.TEX-T {
|
||||
font-family: MJXZERO, MJXTEX-T;
|
||||
}
|
||||
|
||||
.TEX-V {
|
||||
font-family: MJXZERO, MJXTEX-V;
|
||||
}
|
||||
|
||||
.TEX-VB {
|
||||
font-family: MJXZERO, MJXTEX-VB;
|
||||
}
|
||||
|
||||
mjx-stretchy-v mjx-c, mjx-stretchy-h mjx-c {
|
||||
font-family: MJXZERO, MJXTEX-S1, MJXTEX-S4, MJXTEX, MJXTEX-A ! important;
|
||||
}
|
||||
|
||||
@font-face /* 0 */ {
|
||||
font-family: MJXZERO;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Zero.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 1 */ {
|
||||
font-family: MJXTEX;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 2 */ {
|
||||
font-family: MJXTEX-B;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 3 */ {
|
||||
font-family: MJXTEX-I;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 4 */ {
|
||||
font-family: MJXTEX-MI;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 5 */ {
|
||||
font-family: MJXTEX-BI;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 6 */ {
|
||||
font-family: MJXTEX-S1;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 7 */ {
|
||||
font-family: MJXTEX-S2;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 8 */ {
|
||||
font-family: MJXTEX-S3;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 9 */ {
|
||||
font-family: MJXTEX-S4;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 10 */ {
|
||||
font-family: MJXTEX-A;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 11 */ {
|
||||
font-family: MJXTEX-C;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 12 */ {
|
||||
font-family: MJXTEX-CB;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 13 */ {
|
||||
font-family: MJXTEX-FR;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 14 */ {
|
||||
font-family: MJXTEX-FRB;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 15 */ {
|
||||
font-family: MJXTEX-SS;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 16 */ {
|
||||
font-family: MJXTEX-SSB;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 17 */ {
|
||||
font-family: MJXTEX-SSI;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 18 */ {
|
||||
font-family: MJXTEX-SC;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 19 */ {
|
||||
font-family: MJXTEX-T;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 20 */ {
|
||||
font-family: MJXTEX-V;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff") format("woff");
|
||||
}
|
||||
|
||||
@font-face /* 21 */ {
|
||||
font-family: MJXTEX-VB;
|
||||
src: url("https://cdn.jsdelivr.net/npm/mathjax@3/es5/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff") format("woff");
|
||||
}
|
||||
|
||||
mjx-c.mjx-c2265::before {
|
||||
padding: 0.636em 0.778em 0.138em 0;
|
||||
content: "\2265";
|
||||
}
|
||||
|
||||
mjx-c.mjx-c30::before {
|
||||
padding: 0.666em 0.5em 0.022em 0;
|
||||
content: "0";
|
||||
}
|
||||
|
||||
mjx-c.mjx-c2E::before {
|
||||
padding: 0.12em 0.278em 0 0;
|
||||
content: ".";
|
||||
}
|
||||
|
||||
mjx-c.mjx-c35::before {
|
||||
padding: 0.666em 0.5em 0.022em 0;
|
||||
content: "5";
|
||||
}
|
||||
|
||||
mjx-c.mjx-c2212::before {
|
||||
padding: 0.583em 0.778em 0.082em 0;
|
||||
content: "\2212";
|
||||
}
|
||||
|
||||
mjx-c.mjx-c2264::before {
|
||||
padding: 0.636em 0.778em 0.138em 0;
|
||||
content: "\2264";
|
||||
}
|
||||
</style></head>
|
||||
<body>
|
||||
<div style="display:none">
|
||||
<mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="0" style="font-size: 113.1%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"></math></mjx-assistive-mml></mjx-container>
|
||||
</div>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">CSC110 Assignment 3: Loops, Mutation, and Applications</h1>
|
||||
</header>
|
||||
<p>In this assignment, you’ll take what you learned about using loops and mutation over the past few weeks, and apply these programming techniques to a few new problem domains. In Parts 1 and 2, you will generate English texts by creating and using simple computational models. In Part 3, you will learn about <em>sentiment analysis</em> and debug a small program that analyses the sentiments found in movie reviews. And finally, in Part 4 you will work with the Canadian Forest Fire Weather Index system. What an exciting assignment!</p>
|
||||
<h2 id="logistics">Logistics</h2>
|
||||
<ul>
|
||||
<li>Due date: Tuesday, November 2nd before 9 am Eastern Time.</li>
|
||||
<li>This assignment can be done with one partner or individually.</li>
|
||||
<li>You will submit your assignment solutions on MarkUs (see submission instructions at the end of this handout).</li>
|
||||
<li>Review the Course Syllabus section on <a href="https://q.utoronto.ca/courses/233887/assignments/syllabus">Academic Integrity</a>.</li>
|
||||
</ul>
|
||||
<h3 id="starter-files">Starter files</h3>
|
||||
<p>To obtain the starter files for this assignment:</p>
|
||||
<ol type="1">
|
||||
<li>Download the starter files from MarkUs. The downloaded file should be a zip file.</li>
|
||||
<li>Extract the contents of this zip file into your <code>csc110/assignments/</code> folder. Put all the starter files in a new <code>a3</code> folder. This should look similar to what you had for <a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a1/handout">Assignment 1</a>.</li>
|
||||
<li>Mark the <code>a3</code> folder as “Sources Root” by right-clicking on it and selecting <em>Mark Directory as -> Sources Root</em>.</li>
|
||||
</ol>
|
||||
<h3 id="general-instructions">General instructions</h3>
|
||||
<p>This assignment contains a mixture of both written and programming questions. All of your written work should be completed in the <code>a3.tex</code> starter file using the LaTeX typesetting language. You went through the process of getting started with LaTeX in the <a href="https://q.utoronto.ca/courses/160038/pages/setting-up-your-computer-start-here?module_item_id=1346385">Software Installation Guide</a>, but for a quick start we recommend using the online platform <a href="https://www.overleaf.com/">Overleaf</a> for LaTeX. Overleaf also provides many <a href="https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes">tutorials</a> to help you get started with LaTeX.</p>
|
||||
<p>Your programming work should be completed in the different starter files provided (each part has its own starter files). We have provided code at the bottom of each file for running tests and/or PythonTA on each file. We are <em>not</em> grading doctests on this assignment, but encourage you to add some as a way to understand each function we’ve asked you to complete. We <em>are</em> using PythonTA to grade your work, so please run that on every Python file you submit using the code we’ve provided.</p>
|
||||
<p><strong>Warning</strong>: one of the purposes of this assignment is to evaluate your understanding and mastery of the concepts that we have covered so far. So on this assignment, you may only use parts of the Python programming language that we have covered in the first five weeks of lecture (i.e., up to and including all of Chapter 5 in the notes). Other parts are not allowed, and parts of your submissions that use them may receive a grade as low as <strong>zero</strong> for doing so.</p>
|
||||
<ul>
|
||||
<li>You <em>may</em> use augmented assignment operations (e.g., <code>+=</code>)</li>
|
||||
<li>You <em>may</em> use the alternate method call syntax (e.g., <code>text.lower()</code> rather than <code>str.lower(text)</code>)</li>
|
||||
</ul>
|
||||
<h2 id="part-1-text-generation-uniformly-random-model">Part 1: Text generation, uniformly random model</h2>
|
||||
<p>Computers have become very good at predicting the next word in a sentence. Consider, for example, the touch-based keyboards on a smartphone. The accuracy of these predictions are based on two things: the model and the data used to “train” that model. In Parts 1 and 2, we will see how we can use textual data to create a model that generates a series of semi-sensible sentences.</p>
|
||||
<h3 id="the-model">The model</h3>
|
||||
<p>Consider the short sentence <code>'Hello Hello Amy was here'</code>. We can create a dictionary of each word in the sentence to the number of times it appears in this sentence.</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-1"></a>{</span>
|
||||
<span id="cb1-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-2"></a> <span class="st">'Hello'</span>: <span class="dv">2</span>,</span>
|
||||
<span id="cb1-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-3"></a> <span class="st">'Amy'</span>: <span class="dv">1</span>,</span>
|
||||
<span id="cb1-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-4"></a> <span class="st">'was'</span>: <span class="dv">1</span>,</span>
|
||||
<span id="cb1-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-5"></a> <span class="st">'here'</span>: <span class="dv">1</span></span>
|
||||
<span id="cb1-6"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb1-6"></a>}</span></code></pre></div>
|
||||
<p>One naive way to generate new sentences from this data is to <em>randomly select words</em> from this sentence and join them together to generate a new sentence. Here the start of a function to do so:</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-1"></a><span class="kw">def</span> generate_text_uniform(model: <span class="bu">dict</span>[<span class="bu">str</span>, <span class="bu">int</span>], n: <span class="bu">int</span>) <span class="op">-></span> <span class="bu">str</span>:</span>
|
||||
<span id="cb2-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-2"></a> <span class="co">"""Return a string of n randomly-generated words chosen from the given model.</span></span>
|
||||
<span id="cb2-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-3"></a></span>
|
||||
<span id="cb2-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-4"></a><span class="co"> Each word in the returned string is separated by a single space.</span></span>
|
||||
<span id="cb2-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-5"></a></span>
|
||||
<span id="cb2-6"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-6"></a><span class="co"> Preconditions:</span></span>
|
||||
<span id="cb2-7"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-7"></a><span class="co"> - n >= 0</span></span>
|
||||
<span id="cb2-8"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-8"></a><span class="co"> - model != {}</span></span>
|
||||
<span id="cb2-9"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb2-9"></a><span class="co"> """</span></span></code></pre></div>
|
||||
<p>For example, here is how we might call this function on the words in our given sentence:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb3-1"></a><span class="op">>>></span> words <span class="op">=</span> {<span class="st">'Hello'</span>: <span class="dv">2</span>, <span class="st">'Amy'</span>: <span class="dv">1</span>, <span class="st">'was'</span>: <span class="dv">1</span>, <span class="st">'here'</span>: <span class="dv">1</span>}</span>
|
||||
<span id="cb3-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb3-2"></a><span class="op">>>></span> generate_text_uniform(words, <span class="dv">5</span>)</span>
|
||||
<span id="cb3-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb3-3"></a><span class="co">'was Amy was was here'</span></span>
|
||||
<span id="cb3-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb3-4"></a><span class="op">>>></span> generate_text_uniform(words, <span class="dv">5</span>)</span>
|
||||
<span id="cb3-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb3-5"></a><span class="co">'Hello Hello Amy here Hello'</span></span></code></pre></div>
|
||||
<p>This function makes <code>n</code> random choices from the given words, and can be implemented using a loop with the following structure:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-1"></a><span class="kw">def</span> generate_text_uniform(model: <span class="bu">dict</span>[<span class="bu">str</span>, <span class="bu">int</span>], n: <span class="bu">int</span>) <span class="op">-></span> <span class="bu">str</span>:</span>
|
||||
<span id="cb4-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-2"></a> <span class="co">"""Return a string of n randomly-generated words chosen from the given model.</span></span>
|
||||
<span id="cb4-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-3"></a></span>
|
||||
<span id="cb4-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-4"></a><span class="co"> Each word in the returned string is separated by a single space.</span></span>
|
||||
<span id="cb4-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-5"></a></span>
|
||||
<span id="cb4-6"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-6"></a><span class="co"> Preconditions:</span></span>
|
||||
<span id="cb4-7"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-7"></a><span class="co"> - n >= 0</span></span>
|
||||
<span id="cb4-8"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-8"></a><span class="co"> - model != {}</span></span>
|
||||
<span id="cb4-9"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-9"></a><span class="co"> """</span></span>
|
||||
<span id="cb4-10"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-10"></a> <span class="co"># Unpack model into two lists whose indexes correspond to one another</span></span>
|
||||
<span id="cb4-11"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-11"></a> words <span class="op">=</span> []</span>
|
||||
<span id="cb4-12"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-12"></a> word_frequencies <span class="op">=</span> []</span>
|
||||
<span id="cb4-13"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-13"></a> <span class="cf">for</span> word <span class="kw">in</span> model:</span>
|
||||
<span id="cb4-14"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-14"></a> words.append(word)</span>
|
||||
<span id="cb4-15"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-15"></a> word_frequencies.append(model[word])</span>
|
||||
<span id="cb4-16"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-16"></a></span>
|
||||
<span id="cb4-17"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-17"></a> new_words <span class="op">=</span> random.choices(words, weights<span class="op">=</span>word_frequencies, k<span class="op">=</span>n)</span>
|
||||
<span id="cb4-18"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb4-18"></a> <span class="cf">return</span> <span class="bu">str</span>.join(<span class="st">' '</span>, new_words)</span></code></pre></div>
|
||||
<p>First, we created two <em>parallel lists</em> <code>words</code> (a <code>list[str]</code>) and <code>word_frequencies</code> (a <code>list[int]</code>). So index 0 in <code>words</code> is a string that appears <code>word_frequencies[0]</code> number of times. We use these parallel lists in <code>random.choices</code>, a function we have not seen yet (not to be confused by <code>random.choice</code>). Our call to the function <code>random.choices</code> will randomly choose strings from <code>words</code> based on the <em>weights</em> in <code>word_frequencies</code>. In addition, we specify the <code>k</code> argument so that <code>random.choices</code> returns a <code>list[str]</code> containing <code>n</code> elements. Finally, recall that the built-in method <code>str.join</code> takes a separator <code>str</code> and <code>list[str]</code>, and returns a new string containing all the words in the given list, separated by the separator.</p>
|
||||
<ol type="1">
|
||||
<li><p>Open <code>a3.tex</code> and answer the following questions.</p>
|
||||
<ol type="a">
|
||||
<li><p>Complete the <em>loop accumulation table</em> for the example call to <code>generate_text_uniform(words, 5)</code> where <code>words = {'Hello': 2, 'Amy': 1, 'was': 1, 'here': 1}</code>. For this question, you can assume that the for loop goes in the order in which the key-value pairs appear in (so <code>'Hello'</code>, then <code>'Amy'</code>, then…).</p></li>
|
||||
<li><p>Explain why it wouldn’t be a good idea to include this example for <code>generate_text_uniform</code> to check with <code>doctest</code>:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb5-1"></a><span class="co">"""</span></span>
|
||||
<span id="cb5-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb5-2"></a><span class="co">>>> words = {'Hello': 2, 'Amy': 1, 'was': 1, 'here': 1}</span></span>
|
||||
<span id="cb5-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb5-3"></a><span class="co">>>> generate_text_uniform(words, 5)</span></span>
|
||||
<span id="cb5-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb5-4"></a><span class="co">'Hello Hello Amy here Hello'</span></span>
|
||||
<span id="cb5-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb5-5"></a><span class="co">"""</span></span></code></pre></div></li>
|
||||
<li><p>What inputs to <code>generate_text_uniform</code> could we write doctest examples for? (i.e., inputs where the problem you described in part (b) doesn’t apply.)</p></li>
|
||||
</ol></li>
|
||||
<li><p>Open <code>a3_part1.py</code> and complete the function <code>create_model_uniform</code> according to its docstring. You may want to check out <code>a3_sample_tests.py</code>, which does not need to be submitted.</p></li>
|
||||
</ol>
|
||||
<h2 id="part-2-text-generation-one-word-context-model">Part 2: Text Generation, One-Word Context Model</h2>
|
||||
<p><code>generate_text_uniform</code> doesn’t return meaningful sentences, whether we give it a “small” dictionary of words or the entire collection of words in the English language. The reason is its model, which makes <em>independent random choices</em> for each word in the generated output. The reason independent word choices generate nonsensical sentences is that in English (and every other language), word order matters: each word in a sentence is very much tied to the previous and next words.</p>
|
||||
<p>In this part, we’ll develop and use a text model that stores not just the words from our input data, but some <em>context</em> of how each word is used as well.</p>
|
||||
<h3 id="the-model-1">The model</h3>
|
||||
<p>Consider the following sentence:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb6-1"></a><span class="co">'I really really like chocolate'</span></span></code></pre></div>
|
||||
<p>The <strong>one-word context model</strong> for this text is a dictionary where:</p>
|
||||
<ul>
|
||||
<li>Each key is a word from the text.</li>
|
||||
<li>Each key’s corresponding value is a list of words that <em>immediately follow</em> that word in the text. We call this set the <em>follow list</em> of the key.</li>
|
||||
</ul>
|
||||
<p>The one-word context model for <code>'I really really like chocolate'</code> is the following:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb7-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb7-1"></a>{</span>
|
||||
<span id="cb7-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb7-2"></a> <span class="st">'I'</span>: [<span class="st">'really'</span>],</span>
|
||||
<span id="cb7-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb7-3"></a> <span class="st">'really'</span>: [<span class="st">'really'</span>, <span class="st">'like'</span>],</span>
|
||||
<span id="cb7-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb7-4"></a> <span class="st">'like'</span>: [<span class="st">'chocolate'</span>]</span>
|
||||
<span id="cb7-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb7-5"></a>}</span></code></pre></div>
|
||||
<p>This model tells us:</p>
|
||||
<ul>
|
||||
<li>The word <code>'I'</code> can be followed by <code>'really'</code>. Its <em>follow list</em> is <code>['really']</code>.</li>
|
||||
<li>The word <code>'really'</code> can be followed by <code>'really'</code> or <code>'like'</code>.</li>
|
||||
<li>The word <code>'like'</code> can be followed by <code>'chocolate'</code>.</li>
|
||||
<li>The word <code>'chocolate'</code> has no words that follow it. So it is not included as a key.</li>
|
||||
</ul>
|
||||
<p>What about punctuation? To simplify our model, we consider punctuation as part of the word. This means that the word <code>'chocolate'</code> is not the same as <code>'chocolate.'</code> nor is it the same as <code>'chocolate!'</code>.</p>
|
||||
<ol start="0" type="1">
|
||||
<li><p>(<em>Not to be handed in, but useful to complete</em>) answer the following questions:</p>
|
||||
<ol type="a">
|
||||
<li><p>Write the one-word context model for the following string:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb8-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb8-1"></a><span class="co">'David is cool and funny and Mario is cool'</span></span></code></pre></div></li>
|
||||
<li><p>Write a string whose one-word context model is the following:</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-1"></a>{</span>
|
||||
<span id="cb9-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-2"></a> <span class="st">'I'</span>: [<span class="st">'love'</span>],</span>
|
||||
<span id="cb9-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-3"></a> <span class="st">'love'</span>: [<span class="st">'cats'</span>],</span>
|
||||
<span id="cb9-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-4"></a> <span class="st">'hate'</span>: [<span class="st">'dogs'</span>],</span>
|
||||
<span id="cb9-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-5"></a> <span class="st">'cats'</span>: [<span class="st">'and'</span>, <span class="st">'hate'</span>],</span>
|
||||
<span id="cb9-6"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-6"></a> <span class="st">'and'</span>: [<span class="st">'cats'</span>]</span>
|
||||
<span id="cb9-7"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb9-7"></a>}</span></code></pre></div></li>
|
||||
</ol></li>
|
||||
<li><p>In <code>a3.tex</code>, write the one-word context model for the following string:</p>
|
||||
<div class="sourceCode" id="cb10"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb10-1"></a><span class="co">'Love is patient. Love is kind. It does not envy. It does not boast. It is not proud.'</span></span></code></pre></div></li>
|
||||
<li><p>In <code>a3_part2.py</code>, implement the functions <code>update_follow_list</code> and <code>create_model_owc</code>.</p>
|
||||
<p>Some details about the model:</p>
|
||||
<ul>
|
||||
<li>The keys in the model are case-sensitive; so <code>'love'</code> and <code>'Love'</code> are treated as different words, and have different follow lists.</li>
|
||||
<li>Every word in the input text, <em>except the last word</em>, is a key in the returned model.</li>
|
||||
<li>Every word in the input text must have a non-empty follow list.</li>
|
||||
</ul></li>
|
||||
</ol>
|
||||
<h3 id="generating-text">Generating text</h3>
|
||||
<p>Now we’re going to use our one-word context model to generate text, by implementing the following function:</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb11-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-1"></a><span class="kw">def</span> generate_text_owc(count: <span class="bu">int</span>, transitions: <span class="bu">dict</span>[<span class="bu">str</span>, <span class="bu">list</span>[<span class="bu">str</span>]]) <span class="op">-></span> <span class="bu">str</span>:</span>
|
||||
<span id="cb11-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-2"></a> <span class="co">"""Return a string containing (count - 1) randomly generated words based on the data in</span></span>
|
||||
<span id="cb11-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-3"></a><span class="co"> transitions, which maps words to a list of words that follow it.</span></span>
|
||||
<span id="cb11-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-4"></a></span>
|
||||
<span id="cb11-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-5"></a><span class="co"> A randomly generated word is selected from the keys of transitions when:</span></span>
|
||||
<span id="cb11-6"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-6"></a><span class="co"> - it is the first word; or</span></span>
|
||||
<span id="cb11-7"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-7"></a><span class="co"> - the last randomly generated word is not a key in transitions.</span></span>
|
||||
<span id="cb11-8"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-8"></a></span>
|
||||
<span id="cb11-9"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-9"></a><span class="co"> A randomly generated word is selected from the follow list of a key in transitions when the</span></span>
|
||||
<span id="cb11-10"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-10"></a><span class="co"> last randomly generated word is a key in transitions. In addition, one occurrence of the word</span></span>
|
||||
<span id="cb11-11"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-11"></a><span class="co"> selected from the follow list is removed from the follow list (i.e., mutation). When there are</span></span>
|
||||
<span id="cb11-12"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-12"></a><span class="co"> no words in the follow list for a key, the key-value pair is also removed from transitions</span></span>
|
||||
<span id="cb11-13"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-13"></a><span class="co"> (i.e., mutation).</span></span>
|
||||
<span id="cb11-14"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-14"></a></span>
|
||||
<span id="cb11-15"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-15"></a><span class="co"> Your implementation MUST use the helper functions: choose_from_keys and choose_from_follow_list.</span></span>
|
||||
<span id="cb11-16"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-16"></a><span class="co"> We recommend completing these functions first, as they simpler and will get you thinking about</span></span>
|
||||
<span id="cb11-17"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-17"></a><span class="co"> how to use it here.</span></span>
|
||||
<span id="cb11-18"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-18"></a></span>
|
||||
<span id="cb11-19"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-19"></a><span class="co"> Preconditions:</span></span>
|
||||
<span id="cb11-20"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-20"></a><span class="co"> - model is in the format described by the assignment handout</span></span>
|
||||
<span id="cb11-21"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-21"></a><span class="co"> """</span></span>
|
||||
<span id="cb11-22"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-22"></a> <span class="co"># ACCUMULATOR: a list of the randomly-generated words so far</span></span>
|
||||
<span id="cb11-23"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-23"></a> words_so_far <span class="op">=</span> []</span>
|
||||
<span id="cb11-24"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-24"></a></span>
|
||||
<span id="cb11-25"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-25"></a> <span class="co"># We've provided this template as a starting point; you may modify it as necessary.</span></span>
|
||||
<span id="cb11-26"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-26"></a> current_word <span class="op">=</span> <span class="st">''</span></span>
|
||||
<span id="cb11-27"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-27"></a> <span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(count <span class="op">-</span> <span class="dv">1</span>):</span>
|
||||
<span id="cb11-28"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-28"></a> ...</span>
|
||||
<span id="cb11-29"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-29"></a></span>
|
||||
<span id="cb11-30"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb11-30"></a> <span class="cf">return</span> <span class="bu">str</span>.join(<span class="st">' '</span>, words_so_far)</span></code></pre></div>
|
||||
<p>This function behaves similarly to <code>generate_text_uniform</code>, except now we aren’t going to make random choices independent of each other— instead, whenever a word <code>w</code> is chosen, the <em>next</em> word to be chosen must come from the follow list of <code>w</code> stored in the <code>transitions</code>. And for each word <code>w</code>, each word in the follow list of <code>w</code> can only be selected once. For example, in this model:</p>
|
||||
<div class="sourceCode" id="cb12"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb12-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb12-1"></a>{</span>
|
||||
<span id="cb12-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb12-2"></a> <span class="st">'I'</span>: [<span class="st">'like'</span>, <span class="st">'really'</span>],</span>
|
||||
<span id="cb12-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb12-3"></a> <span class="st">'like'</span>: [<span class="st">'chocolate.'</span>, <span class="st">'chocolate.'</span>],</span>
|
||||
<span id="cb12-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb12-4"></a> <span class="st">'really'</span>: [<span class="st">'really'</span>, <span class="st">'like'</span>]</span>
|
||||
<span id="cb12-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb12-5"></a>}</span></code></pre></div>
|
||||
<p>The word <code>'like'</code> can only follow the word <code>'I'</code> once in the generated sentence. But the word <code>'chocolate.'</code> can follow <code>'like'</code> twice. What is the longest sentence we can generate from this model?</p>
|
||||
<p>To accomplish the above, we will <strong>mutate</strong> <code>transitions</code> and the <code>list[str]</code> values in <code>transitions</code> as we “randomly choose” words from it. Sometimes we will need to randomly choose a key from <code>transitions</code>, like when we are generating the very first word or the last word is not a key in <code>transitions</code> (see the <code>choose_from_keys</code> helper function). Other times, when the last word (i.e., the context) is in <code>transitions</code>, we will randomly choose a string from a follow list in <code>transitions</code>. <strong>This is when we mutate</strong> (see the <code>choose_from_follow_list</code> helper function). Let’s try an example.</p>
|
||||
<p>Consider our earlier model:</p>
|
||||
<div class="sourceCode" id="cb13"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb13-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb13-1"></a><span class="op">>>></span> my_model <span class="op">=</span> {</span>
|
||||
<span id="cb13-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb13-2"></a>... <span class="st">'I'</span>: [<span class="st">'like'</span>, <span class="st">'really'</span>],</span>
|
||||
<span id="cb13-3"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb13-3"></a>... <span class="st">'like'</span>: [<span class="st">'chocolate.'</span>, <span class="st">'chocolate.'</span>],</span>
|
||||
<span id="cb13-4"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb13-4"></a>... <span class="st">'really'</span>: [<span class="st">'really'</span>, <span class="st">'like'</span>]</span>
|
||||
<span id="cb13-5"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb13-5"></a>... }</span></code></pre></div>
|
||||
<p>At the beginning, we need to select the “first word” for our randomly generated text. The possible first words are the keys of <code>my_model</code>:</p>
|
||||
<div class="sourceCode" id="cb14"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb14-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb14-1"></a><span class="op">>>></span> <span class="bu">set</span>(my_model.keys())</span>
|
||||
<span id="cb14-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb14-2"></a>{<span class="st">'like'</span>, <span class="st">'I'</span>, <span class="st">'really'</span>}</span></code></pre></div>
|
||||
<p>Suppose we randomly selected <code>'like'</code>. This means our second word will come from the follow list that corresponds with the key <code>'like'</code>:</p>
|
||||
<div class="sourceCode" id="cb15"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb15-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb15-1"></a><span class="op">>>></span> my_model[<span class="st">'like'</span>]</span>
|
||||
<span id="cb15-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb15-2"></a>[<span class="st">'chocolate.'</span>, <span class="st">'chocolate.'</span>]</span></code></pre></div>
|
||||
<p>Suppose we randomly select <code>'chocolate.'</code> (though we didn’t have much choice!) and add it to our randomly generated text. We <em>also</em> need to remove one occurence of <code>'chocolate.'</code> from the follow list. So our string becomes: <code>'like chocolate.'</code>. And our model is now:</p>
|
||||
<div class="sourceCode" id="cb16"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb16-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb16-1"></a><span class="op">>>></span> my_model</span>
|
||||
<span id="cb16-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb16-2"></a>{<span class="st">'I'</span>: [<span class="st">'like'</span>, <span class="st">'really'</span>], <span class="st">'like'</span>: [<span class="st">'chocolate.'</span>], <span class="st">'really'</span>: [<span class="st">'really'</span>, <span class="st">'like'</span>]}</span></code></pre></div>
|
||||
<p>The word <code>'chocolate.'</code> is not a key in <code>my_model</code>. So we will need to choose a random word from the keys of <code>my_model</code>, just like we did for our very first word. Suppose we randomly select <code>'like'</code> again. Its follow list is down to just: <code>['chocolate.']</code>. So when this second <code>'chocolate.'</code> word is selected and removed from the follow list, <code>'like'</code> maps to an empty list <code>[]</code>. When this happens, we remove the key-value pair from the model. So our string becomes: <code>'like chocolate. chocolate.'</code>. And our model is now:</p>
|
||||
<div class="sourceCode" id="cb17"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb17-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb17-1"></a><span class="op">>>></span> my_model</span>
|
||||
<span id="cb17-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb17-2"></a>{<span class="st">'I'</span>: [<span class="st">'like'</span>, <span class="st">'really'</span>], <span class="st">'really'</span>: [<span class="st">'really'</span>, <span class="st">'like'</span>]}</span></code></pre></div>
|
||||
<p>These words are rather meaningless. When your done, be sure to try out <code>run_example</code> on one of our sample text files and see what comes out! Here is a small taste:</p>
|
||||
<div class="sourceCode" id="cb18"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb18-1"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb18-1"></a><span class="op">>>></span> run_example(<span class="st">'data/texts/sample_text_raw.txt'</span>)</span>
|
||||
<span id="cb18-2"><a href="https://www.teach.cs.toronto.edu/~csc110y/fall/assignments/a3/handout/#cb18-2"></a><span class="co">'has no control about the Little Blind Text, that where it came from the far away, behind the countries Vokalia and again. And if she reached the headline of the way. When she had a large language ocean. A small river named Duden flows by their place and supplies it with the all powerful Pointing the word mountains, far World of blind texts. Separated they live the subline of the first hills of sentences fly into their agency, where they abused her seven versalia, put her drunk with Longe and the belt and devious Semikoli, but the copy warned the Little Blind Text should turn around and so it didn</span><span class="ch">\'</span><span class="co">t listen. She packed her way. On her and return to leave for their projects again and made herself on the Little Blind Text didn</span><span class="ch">\'</span><span class="co">t take long until a last view back on the necessary regelialia. It is a copy. The Big Oxmox advised her not to do so, because there live in which roasted parts of Alphabet Village and Consonantia, there were thousands of her cheek, then they are still using her. a small line of Grammar. The copy said could convince her initial into the name of bad Commas, wild Question Marks and everything that was left from its origin would have been rewritten, then she continued her into your mouth. Even the Italic Mountains, she met a paradisematic country, in Bookmarksgrove right at the blind texts it is an almost unorthographic life One day however a thousand times and Parole and the blind text by Copy Writers ambushed her, made her own road, the coast of Lorem Ipsum decided to its own, safe country. But nothing the Line Lane. Pityful rethoric question ran over her for the word "and" and dragged her way she hasn</span><span class="ch">\'</span><span class="co">t been rewritten a few insidious would be the skyline of her hometown Bookmarksgrove, the Semantics, a far from it'</span></span></code></pre></div>
|
||||
<ol start="3" type="1">
|
||||
<li><p>In <code>a3_part2.py</code>, complete the functions <code>generate_text_owc</code>, <code>generate_new_word</code>, and <code>generate_next_word</code> (the latter two are helper functions for <code>generate_text_owc</code>).</p>
|
||||
<p>Test your functions carefully in the Python console (you can copy-and-paste examples from this handout, and make up your own). You may also want to check out <code>a3_sample_tests.py</code>, which does not need to be submitted.</p></li>
|
||||
</ol>
|
||||
<h2 id="part-3-loops-and-mutation-debugging-exercise">Part 3: Loops and Mutation Debugging Exercise</h2>
|
||||
<p>A movie review typically includes a critic’s comments and a score, but the score doesn’t portray the sentiment and raw emotion in the critic’s comments. Professor Mario has decided to build his own <em>movie review platform</em> that labels reviews as positive, negative, or neutral based on the intensity of the words used in the review.</p>
|
||||
<p>Professor Mario uses the <a href="https://github.com/cjhutto/vaderSentiment">VADER Lexicon</a>, which we represent as a mapping from words to a positive/negative intensity score. For example, here are two key words and their intensities:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th style="text-align: left;">Word</th>
|
||||
<th style="text-align: center;">Intensity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">awesome</td>
|
||||
<td style="text-align: center;">3.1</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">awful</td>
|
||||
<td style="text-align: center;">-2.0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The <em>polarity</em> of a review is one of <code>{'positive', 'negative', 'neutral'}</code>, and is calculated by finding the average intensity of the lexicon words used in the review. Words that don’t appear in the VADER Lexicon are ignored when calculating the average.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr class="header">
|
||||
<th style="text-align: left;">Polarity</th>
|
||||
<th style="text-align: center;">Average intensity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;"><code>positive</code></td>
|
||||
<td style="text-align: center;"><span class="math inline"><mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="1" style="font-size: 108.9%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mo class="mjx-n"><mjx-c class="mjx-c2265"></mjx-c></mjx-mo><mjx-mn class="mjx-n" space="4"><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c2E"></mjx-c><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c35"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mo>≥</mo><mn>0.05</mn></math></mjx-assistive-mml></mjx-container></span></td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;"><code>neutral</code></td>
|
||||
<td style="text-align: center;"><span class="math inline"><mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="2" style="font-size: 108.9%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mo class="mjx-n"><mjx-c class="mjx-c2212"></mjx-c></mjx-mo><mjx-mn class="mjx-n"><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c2E"></mjx-c><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c35"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mo>−</mo><mn>0.05</mn></math></mjx-assistive-mml></mjx-container></span> to <span class="math inline"><mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="3" style="font-size: 108.9%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mn class="mjx-n"><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c2E"></mjx-c><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c35"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mn>0.05</mn></math></mjx-assistive-mml></mjx-container></span>, exclusive</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;"><code>negative</code></td>
|
||||
<td style="text-align: center;"><span class="math inline"><mjx-container class="MathJax CtxtMenu_Attached_0" jax="CHTML" tabindex="0" ctxtmenu_counter="4" style="font-size: 108.9%; position: relative;"><mjx-math class="MJX-TEX" aria-hidden="true"><mjx-mo class="mjx-n"><mjx-c class="mjx-c2264"></mjx-c></mjx-mo><mjx-mo class="mjx-n" space="4"><mjx-c class="mjx-c2212"></mjx-c></mjx-mo><mjx-mn class="mjx-n"><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c2E"></mjx-c><mjx-c class="mjx-c30"></mjx-c><mjx-c class="mjx-c35"></mjx-c></mjx-mn></mjx-math><mjx-assistive-mml unselectable="on" display="inline"><math xmlns="http://www.w3.org/1998/Math/MathML"><mo>≤</mo><mo>−</mo><mn>0.05</mn></math></mjx-assistive-mml></mjx-container></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>In <code>a3_part3.py</code>, Professor Mario has written a small program to read review data from a csv file, extract the lexicon words from the review, and then compute review’s the average intensity and polarity. Professor Mario has painstakingly gone through three reviews and manually calculated their polarity and average intensity. Unfortunately, when Professor Mario compares his calculated results to the return values from his program, he finds that his program has some errors!</p>
|
||||
<p>Answer the following questions about this program and <code>pytest</code> report. Write your responses in <code>a3.tex</code>, except for 2(b).</p>
|
||||
<ol type="1">
|
||||
<li><p>Run the program to generate a <code>pytest</code> report.</p>
|
||||
<p>Based on the report, state which tests, if any, passed, and which tests failed. You can just state the name of the tests and whether they passed/failed, and do not need to give explanations here.</p></li>
|
||||
<li><p>For <em>each</em> failing test from the <code>pytest</code> report:</p>
|
||||
<ol type="a">
|
||||
<li><p>Explain what error is causing the test to fail.</p>
|
||||
<p><strong>Hint</strong>: each test refers to a data file under <code>data/reviews</code>; the last column of each csv file stores the test of the review.</p></li>
|
||||
<li><p>Edit <code>a3_part3.py</code> by fixing the function code so that all tests pass. Unlike Assignment 1, the tests do <em>not</em> contain errors.</p>
|
||||
<p>The changes should be small and must be to fix errors only; the original purpose of all functions and tests must remain the same. The expected value in the tests is correct, do not change it.</p></li>
|
||||
</ol></li>
|
||||
<li><p>For <em>each</em> test that passed on the original code (before your changes in question 2), explain why that test passed even though there were errors in the Python file.</p></li>
|
||||
</ol>
|
||||
<h2 id="part-4-forest-fires">Part 4: Forest Fires</h2>
|
||||
<p>In Part 4, our problem domain is forest fires. Specifically, we take a close look at the Canadian Forest Fire Weather Index system. The system calculates several fire danger indices based on measurements made by fire weather stations. The measurements and calculations are typically made daily, and the calculations are based on complex models that are well beyond the scope of this course. Our focus in Part 4 is on developing an understanding of the system (rather than its underlying models), using existing code to generate outputs based on measurements in file data, and testing existing code via the “white-box” method.</p>
|
||||
<h3 id="the-fire-weather-index-system">The Fire Weather Index System</h3>
|
||||
<p>The Forest Fire Weather Index (FWI) System takes, as daily inputs, the following weather measurements:</p>
|
||||
<ul>
|
||||
<li>Temperature (Celsius)</li>
|
||||
<li>Relative Humidity (%)</li>
|
||||
<li>Wind Speed (km/h)</li>
|
||||
<li>Precipitation (mm)</li>
|
||||
</ul>
|
||||
<p>The month and day these measurements are taken is also relevant for the models when making calculations for the system’s outputs. As output, the system calculates three moisture codes (sometimes called “subindexes”):</p>
|
||||
<ol type="1">
|
||||
<li>the Fine Fuel Moisture Code (FFMC)</li>
|
||||
<li>the Duff Moisture Code (DMC)</li>
|
||||
<li>the Drought Code (DC)</li>
|
||||
</ol>
|
||||
<p>The higher the values (with type <code>float</code>) of these codes, the drier the conditions of the environment. Based on these codes, three additional outputs of “fire behaviour indexes” can be calculated:</p>
|
||||
<ol start="4" type="1">
|
||||
<li>The Initial Spread Index (ISI)</li>
|
||||
<li>The Buildup Index (BUI)</li>
|
||||
<li>The Fire Weather Index (FWI)</li>
|
||||
</ol>
|
||||
<p>These six components act as a way to monitor the danger of fire in an environment. A summary of the Canadian Forest FWI System can be found <a href="https://cwfis.cfs.nrcan.gc.ca/background/summary/fwi">here</a>. To see some concrete photo examples of how FWI (ranging from values of 9 to 34) correspond to photos of real forest fires, check out <a href="https://cwfis.cfs.nrcan.gc.ca/background/examples/fwi">this link</a>.</p>
|
||||
<p>Included in the starter files is <code>a3_ffwi_system.py</code>, which is based on the publicly available source code found <a href="https://cfs.nrcan.gc.ca/publications?id=36461">here</a>. We have adapted the original code to follow our course conventions and divided parts of the code into smaller functions. Rather than reading the body of the functions in detail, you should instead focus on the data classes, their docstring descriptions, and the docstring descriptions of the functions.</p>
|
||||
<ol type="1">
|
||||
<li><p>Your first task is to complete <code>a3_part4.py</code>. This task involves implementing functions that load data from a csv, calculate all six outputs of the Forest FWI System, and plot the data. In order to calculate the daily outputs of the system, you will need to use the functions in <code>a3_ffwi_system</code> appropriately. Note that, when calculating moisture codes, the previous day’s moisutre code calculation is required. For the very first day, you should use the <code>INITIAL_FFMC</code>, <code>INITIAL_DMC</code>, and <code>INITIAL_DC</code> constants defined in <code>a3_ffwi_system</code>.</p>
|
||||
<p>For data, we have included the csv file <code>data/ffwi/sample_data.csv</code>. We will also be releasing additional data from the government on Quercus under a special license. It will appear under the Assignment 3 module on Quercus a little while after this assignment is available. Please note that if you wish to use this additional data, you must understand and adhere to the license.</p></li>
|
||||
<li><p>Your second task is to complete <code>a3_part4_tests.py</code>. This task let’s you practice with two forms of testing—complete only the test cases in the starter file, you should not add more. First, you do some “white box testing” – we originally discussed this concept in Section 3.4 of the course notes when we introduced conditional execution. The branches you need to test for are described in the docstring description of the unit tests. To verify that your tests are reaching the right branches, consider using the debugger and breakpoints.</p>
|
||||
<p>Second, you will do a new kind of testing that compares the outputs of the Forest FWI system to the “ground truth”. In this case, the ground truth are the values provided in the data; the term ground truth implies that these are the “correct” (or expected) values. Meanwhile, the values obtained via the <code>calculate_</code> functions in <code>a3_ffwi_system</code> are the actual values. Your <code>test_ffmc_against_ground_truth</code> should contain a loop, and the loop body should consist of multiple <code>assert</code> statements (one for each system output you are validating).</p></li>
|
||||
<li><p>Using what you know about the object-based Python memory model, answer the following questions in <code>a3.tex</code>. You may find it helpful to draw some memory model diagrams (in fact, we encourage it), but you should <em>not</em> include any memory model diagrams in your submission. Your answers should be brief—long answers may be penalized.</p>
|
||||
<ol type="a">
|
||||
<li><p>The function <code>calculate_ffmc</code> calls <code>calculate_mr</code>, passing the precipitation from a <code>WeatherMetrics</code> object referred to by <code>wm</code> as the first argument to <code>calculate_mr</code>. Why is it <em>not</em> possible for <code>calculate_mr</code> to mutate the precipitation attribute of the <code>WeatherMetrics</code> object referred to by <code>wm</code> in <code>calculate_ffmc</code>?</p></li>
|
||||
<li><p>In the function <code>calculate_dc</code>, why is the local variable <code>temperature</code> assigned instead of simply re-using/re-assigning <code>wm.temperature</code> when the temperature is below -2.8 degrees Celsius?</p></li>
|
||||
<li><p>In <code>a3_part4</code>, the return type of <code>load_data</code> is <code>tuple[list[WeatherMetrics], list[FfwiOutput]]</code>. We know that a <code>tuple</code> is immutable. Yet the list objects inside the tuple (i.e., <code>list[WeatherMetrics]</code>, <code>list[FfwiOutput]</code>) can be mutated. So what do we mean when we say that this <code>tuple</code> return type is immutable?</p></li>
|
||||
</ol></li>
|
||||
</ol>
|
||||
<h2 id="submission-instructions">Submission instructions</h2>
|
||||
<p>Please <strong>proofread</strong>, <strong>test</strong>, and <strong>fix PythonTA errors</strong> in your work before your final submission!</p>
|
||||
<ol type="1">
|
||||
<li><p>Login to <a href="https://markus.teach.cs.toronto.edu/csc110-2021-09">MarkUs</a>.</p></li>
|
||||
<li><p>Go to Assignment 3, then the “Submissions” tab.</p></li>
|
||||
<li><p>Submit the following files: <code>a3.tex</code>, <code>a3.pdf</code> (which must be generated from your <code>a3.tex</code> file), <code>a3_part1.py</code>, <code>a3_part2.py</code>, <code>a3_part3.py</code>, <code>a3_part4.py</code>, and <code>a3_part4_tests.py</code>. Please note that MarkUs is picky with filenames, and so your filenames must match these exactly, including using lowercase letters.</p>
|
||||
<p><strong>Note</strong>: for your Python code files, please make sure they run (in the Python console) before submitting them! Code submissions that do not run will receive a grade of <em>zero</em> for that part, which we do not want to happen to any of you, so please check your work carefully.</p></li>
|
||||
<li><p>Refresh the page, and then <em>download each file</em> to make sure you submitted the right version.</p></li>
|
||||
</ol>
|
||||
<p>Remember, you can submit your files multiple times before the due date. So you can aim to submit your work early, and if you find an error or a place to improve before the due date, you can still make your changes and resubmit your work.</p>
|
||||
<p>After you’ve submitted your work, please give yourself a well-deserved pat on the back and go take a rest or do something fun or eat some chocolate!</p>
|
||||
<div style="text-align: center">
|
||||
<p><img src="./handout_files/legally_blonde_chocolate.gif" alt="Legally Blonde GIF of Elle Woods eating chocolate"><br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 536 KiB |
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* I add this to html files generated with pandoc.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-size: 100%;
|
||||
overflow-y: scroll;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
color: #444;
|
||||
font-family: Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman', serif;
|
||||
font-size: 12px;
|
||||
line-height: 1.7;
|
||||
padding: 1em;
|
||||
margin: auto;
|
||||
max-width: 50em;
|
||||
background: #fefefe;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0645ad;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #0b0080;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #06e;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #faa700;
|
||||
}
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
*::-moz-selection {
|
||||
background: rgba(255, 255, 0, 0.3);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
*::selection {
|
||||
background: rgba(255, 255, 0, 0.3);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
a::-moz-selection {
|
||||
background: rgba(255, 255, 0, 0.3);
|
||||
color: #0645ad;
|
||||
}
|
||||
|
||||
a::selection {
|
||||
background: rgba(255, 255, 0, 0.3);
|
||||
color: #0645ad;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #111;
|
||||
line-height: 125%;
|
||||
margin-top: 1.4em;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
border-bottom: solid 2px darkslategray;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
color: #666666;
|
||||
margin: 0;
|
||||
padding-left: 3em;
|
||||
border-left: 0.5em #EEE solid;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: block;
|
||||
height: 2px;
|
||||
border: 0;
|
||||
border-top: 1px solid #aaa;
|
||||
border-bottom: 1px solid #eee;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre, code, kbd, samp {
|
||||
color: #000;
|
||||
font-family: monospace, monospace;
|
||||
_font-family: 'courier new', monospace;
|
||||
font-size: 0.98em;
|
||||
}
|
||||
|
||||
a code {
|
||||
color: rgb(6, 69, 173);
|
||||
}
|
||||
|
||||
pre {
|
||||
padding-left: 0.5em;
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
div.sourceCode {
|
||||
border: solid 1px darkslategray;
|
||||
}
|
||||
|
||||
b, strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ins {
|
||||
background: #ff9;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
sub, sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin: 1em 0;
|
||||
padding: 0 0 0 2em;
|
||||
}
|
||||
|
||||
li p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
ul ul, ol ol {
|
||||
margin: .3em 0;
|
||||
}
|
||||
|
||||
li {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
margin-bottom: .8em;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0 0 .8em 2em;
|
||||
}
|
||||
|
||||
dd:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
figure {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
figure img {
|
||||
border: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
margin: 0 0 .8em;
|
||||
}
|
||||
|
||||
table {
|
||||
margin-bottom: 2em;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table th {
|
||||
padding: .2em 1em;
|
||||
background-color: #eee;
|
||||
border-top: 1px solid #ddd;
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
table td {
|
||||
padding: .2em 1em;
|
||||
border-top: 1px solid #ddd;
|
||||
border-left: 1px solid #ddd;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.author {
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 480px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 768px) {
|
||||
body {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
* {
|
||||
filter: none !important;
|
||||
-ms-filter: none !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background: transparent;
|
||||
font-size: 12pt;
|
||||
max-width: 8in;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a, a:visited {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
a[href]:after {
|
||||
content: " (" attr(href) ")";
|
||||
}
|
||||
|
||||
abbr[title]:after {
|
||||
content: " (" attr(title) ")";
|
||||
}
|
||||
|
||||
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
pre, blockquote {
|
||||
padding-right: 1em;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
tr, img {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
@page :left {
|
||||
margin: 15mm 20mm 15mm 10mm;
|
||||
}
|
||||
|
||||
@page :right {
|
||||
margin: 15mm 10mm 15mm 20mm;
|
||||
}
|
||||
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
|
||||
h2, h3 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
.framed {
|
||||
border: solid 1px black;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
|
||||
/* Custom styling for memory model tables */
|
||||
|
||||
.memory-model-values {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
table .memory-model-values {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table .memory-model-values table {
|
||||
min-width: 90%;
|
||||
}
|
||||
|
||||
.memory-model-values th {
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
.memory-model-values td {
|
||||
border-top: 1px solid darkgrey;
|
||||
}
|
||||
|
||||
.memory-model-values table {
|
||||
border: 1px solid black;
|
||||
margin: 0.5rem auto;
|
||||
min-width: 40%;
|
||||
}
|
||||
|
||||
.memory-model-values caption {
|
||||
background-color: lavender;
|
||||
padding-left: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.memory-model-values-inactive table {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.memory-model-values-inactive {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.memory-model-values-inactive caption {
|
||||
background-color: silver;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,198 @@
|
||||
"""CSC110 Fall 2021 Prep 7: 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.
|
||||
|
||||
You do not need to include doctests for this prep, though we strongly encourage you
|
||||
to check your work carefully!
|
||||
|
||||
Note: the last two function's preconditions refer to math.gcd, which isn't actually
|
||||
imported. This means that python_ta.contracts won't actually check those preconditions,
|
||||
so it will be up to you to verify that these preconditions hold when you call the
|
||||
functions in your own testing.
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Caesar cipher with ASCII characters (from Notes 7.1)
|
||||
###############################################################################
|
||||
def encrypt_ascii(k: int, plaintext: str) -> str:
|
||||
"""Return the encrypted message using the Caesar cipher with key k.
|
||||
|
||||
Preconditions:
|
||||
- all({ord(c) < 128 for c in plaintext})
|
||||
- 1 <= k <= 127
|
||||
|
||||
>>> encrypt_ascii(4, 'Good morning!')
|
||||
'Kssh$qsvrmrk%'
|
||||
"""
|
||||
ciphertext = ''
|
||||
|
||||
for letter in plaintext:
|
||||
ciphertext = ciphertext + chr((ord(letter) + k) % 128)
|
||||
|
||||
return ciphertext
|
||||
|
||||
|
||||
def decrypt_ascii(k: int, ciphertext: str) -> str:
|
||||
"""Return the decrypted message using the Caesar cipher with key k.
|
||||
|
||||
Preconditions:
|
||||
- all({ord(c) < 128 for c in ciphertext})
|
||||
- 1 <= k <= 127
|
||||
|
||||
>>> decrypt_ascii(4, 'Kssh$qsvrmrk%')
|
||||
'Good morning!'
|
||||
"""
|
||||
plaintext = ''
|
||||
|
||||
for letter in ciphertext:
|
||||
plaintext += chr((ord(letter) - k) % 128)
|
||||
|
||||
return plaintext
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Decrypting ciphertexts by brute force
|
||||
###############################################################################
|
||||
def brute_force_ascii_caesar(ciphertext: str) -> dict[int, str]:
|
||||
"""Return a mapping of possible secret keys to decrypted plaintext messages.
|
||||
|
||||
The mapping's keys should be the set {1, 2, ..., 127}.
|
||||
The corresponding value of key k is the plaintext message obtained by decrypting
|
||||
the given ciphertext with the secret key k, using ascii_decrypt.
|
||||
|
||||
Preconditions:
|
||||
- ciphertext != ''
|
||||
- all({ord(c) < 128 for c in ciphertext})
|
||||
|
||||
You may use either a dictionary comprehension or a for loop.
|
||||
(For extra practice, try implementing this function both ways!)
|
||||
|
||||
>>> result = brute_force_ascii_caesar('Kssh$qsvrmrk%')
|
||||
>>> len(result)
|
||||
127
|
||||
>>> result[4]
|
||||
'Good morning!'
|
||||
"""
|
||||
return {k: decrypt_ascii(k, ciphertext) for k in range(1, 128)}
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Implementing a new symmetric-key cryptosystem
|
||||
###############################################################################
|
||||
# In this exercise, you'll implement the encryption and decryption functions for a new
|
||||
# symmetric-key cryptosystem described as follows:
|
||||
#
|
||||
# - The plaintexts and ciphertexts are strings.
|
||||
# - The secret key is from the set {2, 3, ...}.
|
||||
# - Encrypt(k, m) works as follows:
|
||||
# PRECONDITION: math.gcd(k, len(m)) = 1.
|
||||
# (It's possible to make the encryption work without this assumption,
|
||||
# but harder to do, so for this prep you can assume this holds.)
|
||||
#
|
||||
# The ciphertext c has the same length as m.
|
||||
# For all i in {0, 1, ..., len(m) - 1), c[(i * k) % len(m)] = m[i].
|
||||
# In other words, c is a permutation (reordering) of the characters of m.
|
||||
#
|
||||
# - Decrypt(k, c) works as follows:
|
||||
# PRECONDITION: math.gcd(k, len(c)) = 1.
|
||||
#
|
||||
# Simply do the encryption in reverse:
|
||||
# For all i in {0, 1, ..., len(c) - 1), m[i] = c[(i * k) % len(m)].
|
||||
#
|
||||
# Example: m = 'David is cool', and k = 2. len(m) = 13 (Follow along on paper!)
|
||||
# m[0] -> c[0]
|
||||
# m[1] -> c[2]
|
||||
# m[2] -> c[4]
|
||||
# m[3] -> c[6]
|
||||
# m[4] -> c[8]
|
||||
# m[5] -> c[10]
|
||||
# m[6] -> c[12]
|
||||
# m[7] -> c[1] <-- Since we're taking remainders modulo 13, and (2 * 7) % 13 = 1.
|
||||
# m[8] -> c[3]
|
||||
# m[9] -> c[5]
|
||||
# m[10] -> c[7]
|
||||
# m[11] -> c[9]
|
||||
# m[12] -> c[11]
|
||||
#
|
||||
# So the encrypted string is 'Dsa vciodo li'
|
||||
|
||||
|
||||
def encrypt_symmetric_modulo(k: int, plaintext: str) -> str:
|
||||
"""Return the encrypted message of plaintext with the above cryptosystem using the key k.
|
||||
|
||||
Preconditions:
|
||||
- math.gcd(k, len(plaintext)) == 1
|
||||
|
||||
>>> encrypt_symmetric_modulo(2, 'David is cool')
|
||||
'Dsa vciodo li'
|
||||
|
||||
Hint: this is tricky, and easiest done using an index-based for loop and list mutation.
|
||||
We've set up an accumulator for you to use: a list of characters of length m that you
|
||||
should fill in. Inside your loop use list index assignment to set a particular index
|
||||
in the accumulator, and then at the end of the function join the characters into a
|
||||
single string using str.join('', the_accumulator_list).
|
||||
"""
|
||||
n = len(plaintext)
|
||||
|
||||
# Accumulator
|
||||
c = [''] * n
|
||||
|
||||
for i in range(n):
|
||||
c[(i * k) % n] = plaintext[i]
|
||||
|
||||
return str.join('', c)
|
||||
|
||||
|
||||
def decrypt_symmetric_modulo(k: int, ciphertext: str) -> str:
|
||||
"""Return the decrypted message of ciphertext using the key k.
|
||||
|
||||
Preconditions:
|
||||
- math.gcd(k, len(ciphertext)) == 1
|
||||
|
||||
>>> decrypt_symmetric_modulo(2, 'Dsa vciodo li')
|
||||
'David is cool'
|
||||
|
||||
Hint: this one is easier to implement than encrypt_symmetric_modulo.
|
||||
You can use the same approach you used for that function, or a different approach.
|
||||
"""
|
||||
n = len(ciphertext)
|
||||
|
||||
# Accumulator
|
||||
m = [''] * n
|
||||
|
||||
for i in range(n):
|
||||
m[i] = ciphertext[(i * k) % len(m)]
|
||||
|
||||
return str.join('', m)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import python_ta
|
||||
|
||||
python_ta.check_all(config={
|
||||
'max-line-length': 100,
|
||||
'extra-imports': ['math', 'python_ta.contracts'],
|
||||
'disable': ['R1705']
|
||||
})
|
||||
|
||||
import python_ta.contracts
|
||||
|
||||
python_ta.contracts.DEBUG_CONTRACTS = False
|
||||
python_ta.contracts.check_all_contracts()
|
||||
Reference in New Issue
Block a user