This commit is contained in:
Hykilpikonna
2021-10-25 19:28:38 -04:00
26 changed files with 10675 additions and 0 deletions
+128
View File
@@ -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}
+291
View File
@@ -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
+94
View File
@@ -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']
})
+161
View File
@@ -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']
})
+189
View File
@@ -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'])
+153
View File
@@ -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'],
})
+105
View File
@@ -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'],
# })
+129
View File
@@ -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'])
+50
View File
@@ -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
1 Month Day Temp Humidity Wind Rain FFMC DMC DC ISI BUI FWI
2 4 13 17.0 42.0 25.0 0.0 87.7 8.5 19.0 10.9 8.5 10.1
3 4 14 20.0 21.0 25.0 2.4 86.2 10.4 23.6 8.8 10.4 9.3
4 4 15 8.5 40.0 17.0 0.0 87.0 11.8 26.1 6.5 11.7 7.6
5 4 16 6.5 25.0 6.0 0.0 88.8 13.2 28.2 4.9 13.1 6.2
6 4 17 13.0 34.0 24.0 0.0 89.1 15.4 31.5 12.6 15.3 14.8
7 4 18 6.0 40.0 22.0 0.4 88.7 16.5 33.5 10.7 16.4 13.5
8 4 19 5.5 52.0 6.0 0.0 87.4 17.2 35.4 4.0 17.1 5.9
9 4 20 8.5 46.0 16.0 0.0 87.4 18.5 37.9 6.6 18.4 9.7
10 4 21 9.5 54.0 20.0 0.0 86.8 19.7 40.6 7.4 19.6 11.0
11 4 22 7.0 93.0 14.0 9.0 29.9 10.1 29.5 0.0 10.9 0.0
12 4 23 6.5 71.0 17.0 1.0 49.4 10.7 31.6 0.4 11.6 0.2
13 4 24 6.0 59.0 17.0 0.0 67.3 11.4 33.7 1.3 12.3 0.9
14 4 25 13.0 52.0 4.0 0.0 77.8 13.0 37.0 1.1 13.9 0.8
15 4 26 15.5 40.0 11.0 0.0 85.5 15.4 40.7 3.9 15.9 5.5
16 4 27 23.0 25.0 9.0 0.0 91.5 19.8 45.8 8.4 19.8 12.2
17 4 28 19.0 46.0 16.0 0.0 89.9 22.5 50.2 9.5 22.4 14.3
18 4 29 18.0 41.0 20.0 0.0 90.0 25.2 54.4 11.7 25.1 17.7
19 4 30 14.5 51.0 16.0 0.0 88.4 27.0 57.9 7.7 27.0 13.3
20 5 1 14.5 69.0 11.0 0.0 85.7 28.3 63.0 4.0 28.2 8.0
21 5 2 15.5 42.0 8.0 0.0 87.4 30.8 68.2 4.4 30.8 9.1
22 5 3 21.0 37.0 8.0 0.0 89.4 34.5 74.3 5.9 34.4 12.3
23 5 4 23.0 32.0 16.0 0.0 91.0 38.8 80.9 11.1 38.7 21.0
24 5 5 23.0 32.0 14.0 0.0 91.2 43.1 87.4 10.3 43.0 21.1
25 5 6 27.0 33.0 12.0 0.0 91.7 48.1 94.7 9.9 47.9 21.7
26 5 7 28.0 17.0 27.0 0.0 95.2 54.5 102.1 34.5 54.3 52.6
27 5 8 23.5 54.0 20.0 0.0 89.7 57.4 108.8 11.3 57.2 25.9
28 5 9 16.0 50.0 22.0 12.2 62.2 29.9 91.8 1.4 33.0 3.0
29 5 10 11.5 58.0 20.0 0.0 76.7 31.3 96.3 2.3 34.5 5.4
30 5 11 16.0 54.0 16.0 0.0 83.5 33.4 101.6 3.8 36.7 8.9
31 5 12 21.5 37.0 9.0 0.0 88.7 37.1 107.8 5.6 39.9 12.8
32 5 13 14.0 61.0 22.0 0.2 86.7 38.7 112.8 8.1 41.6 17.3
33 5 14 15.0 30.0 27.0 0.0 89.6 41.7 117.9 15.9 44.2 28.8
34 5 15 20.0 23.0 11.0 0.0 92.1 45.9 123.9 10.1 47.7 21.9
35 5 16 14.0 95.0 3.0 16.4 21.3 20.1 97.0 0.0 26.5 0.0
36 5 17 20.0 53.0 4.0 2.8 51.0 18.3 103.0 0.2 25.3 0.2
37 5 18 19.5 30.0 16.0 0.0 82.3 22.1 108.9 3.3 29.3 6.8
38 5 19 25.5 51.0 20.0 6.0 75.4 16.4 106.4 2.1 23.7 3.8
39 5 20 10.0 38.0 24.0 0.0 84.3 18.2 110.6 6.4 25.8 11.3
40 5 21 19.0 27.0 16.0 0.0 90.3 22.1 116.4 10.0 29.9 17.2
41 5 22 26.0 46.0 11.0 4.2 77.6 18.7 117.7 1.6 26.8 2.9
42 5 23 30.0 38.0 22.0 0.0 90.2 23.8 125.5 13.4 32.3 22.0
43 5 24 25.5 67.0 19.0 12.6 65.3 13.1 108.5 1.4 20.2 1.9
44 5 25 12.0 53.0 28.0 11.8 55.4 7.7 91.6 1.2 12.8 0.8
45 5 26 21.0 38.0 8.0 0.0 80.8 11.3 97.8 1.9 17.6 2.6
46 5 27 13.0 70.0 20.0 3.8 61.7 8.4 97.9 1.2 13.8 0.9
47 5 28 9.0 78.0 24.0 1.4 64.5 9.0 101.9 1.7 14.7 2.0
48 5 29 11.0 54.0 16.0 0.0 77.6 10.5 106.3 2.0 16.8 2.8
49 5 30 15.5 39.0 9.0 0.0 85.4 13.1 111.5 3.5 20.3 5.8
50 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."
1 critic_name media movie_title review_date individual_meta_score text
2 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."
1 critic_name media movie_title review_date individual_meta_score text
2 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."
1 critic_name media movie_title review_date individual_meta_score text
2 Tasha Robinson The A.V. Club Transformers 42 Turns the franchise into a terrible, terrible '80s comedy.
+542
View File
@@ -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
+340
View File
@@ -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
+447
View File
@@ -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
+218
View File
@@ -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!
+2
View File
@@ -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.
+964
View File
@@ -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, youll 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 -&gt; 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 weve 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 weve 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">-&gt;</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 &gt;= 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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">-&gt;</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 &gt;= 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 wouldnt 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">&gt;&gt;&gt; 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">&gt;&gt;&gt; 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) doesnt 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> doesnt 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, well 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 keys 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 were 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">-&gt;</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 arent 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). Lets 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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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 didnt 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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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 critics comments and a score, but the score doesnt portray the sentiment and raw emotion in the critics 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 dont 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 reviews 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 systems 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 days 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 lets 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 youve 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
+198
View File
@@ -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()