This worksheet focuses on Flask web applications, anonymous functions, and decorators.
(Setup description omitted; problem heading preserved to make it clear problem 2 refers to this application.)
Modify the sample application to add these new features. Test them to make sure they work.
Make a new route /task/<taskid>/
that does the following:
taskid
task_view.html
that you create in the templates/
subdirectory which displays a page listing all the information about that task in a nice format (e.g. with labels for the different fields and proper formatting for the dates/times)Then, modify the /task/new/submit
route so that when a new task is created, the redirect goes to the single task view page for the newly-created task. To do this, you'll need to know this neat trick: The query
SELECT last_insert_rowid();
will return the primary key of the most recently inserted row. So calling this immediately after an SQL INSERT
is the proper way to find the unique identifier of the added row.
Here's a function that can take a day described by its year, month, and day numbers and return two time stamps ts0,ts1
so that a timestamp x
lies within that day if and only if ts0 <= x < ts1
.
import datetime
def timestamp_range_for_day(year,month,day):
"""
Return the timestamps when a calendar day
begins and ends.
"""
ts0 = datetime.datetime(year,month,day).timestamp()
ts1 = (datetime.datetime(year,month,day)+datetime.timedelta(days=1)).timestamp()
return ts0,ts1
Use this to add the following feature to the task list management application: Visiting a URL of the form /reports/day/2024/04/09/
will show a page with two sections:
Each section should contain a list of tasks with the described property.
As with the previous feature, this one should use a new template. It is recommended to base your work on the task list view template, since that one also involves a task list.
It would be quite difficult to place all of the solutions in cells in this notebook. Instead, the following links can be used to download full versions of the apps that include all of the changes we need to make:
The changes are as follows:
single_task_view.html
was addedon_this_day.html
was addedtimestamp_range_for_day()
was added to the main python scriptsingle_task_view
that handles /task/<int:taskid>/
was added to the main python scripton_this_day
that handles /reports/day/<int:year>/<int:month>/<int:day>/
was added to the main python scriptadd_task
was modified to get the created taskid and redirect to the single task view pageAlso, the version of the app provided here had one additional convenience feature:
Use anonymous functions (lambda
) with Python's sorted()
, max()
, or min()
functions to answer these questions.
Generate the first 20 powers of 7 (meaning $7^1$ to $7^{20}$) and sort them according to how many different decimal digits they use. That is, 343 would appear near the start of the list since it uses only two distinct digits, while 1628413597910449 would appear near the end, as it uses all 10 digits.
sorted([7**x for x in range(1,21)], key = lambda x: len(set(str(x))))
Here's a text file with 10000 English words, one per line:
Let's say the endscore of a word is the number of times its last letter appears in the word. For example, "plasma" has an endscore of 2 because the last letter, a, appears twice. And "associates" has an endscope of 3 because it contains 3 copies of the last letter, s.
Using custom sorting and lambda
, find 20 words with the highest endscores in this list.
We can use the following cell to open the list of words:
words = [x.strip() for x in open("wordlist.10000.txt","rt").readlines()]
Then the following lambda function counts the number of occurrences of the final letter:
lambda w: w.count(w[-1]))
.
This results in the following answer:
sorted(words, key = lambda w: w.count(w[-1]))[-20:]
Use the same word list as the last problem. Suppose we say the variety of a word is the ratio of the number of distinct letters to the length of the word. For example, "cameras" has 6 distinct letters and has a length of 7, so its variety is $\frac67 \approx 0.85714$.
Among words with at least four letters, find one that has the lowest variety.
To find the variety of a word w
, we can use len(set(w))/len(w)
. So the answer is as follows:
sorted([ w for w in words if len(w)>=4], key = lambda w: len(set(w))/len(w))[:10]
To verify that this formula works, let's find the position of the word "cameras"
in the list:
idx = words.index("cameras")
print(idx)
Then the cell below shows us that the variety is approximately 0.85714, as expected
print("The word {} has variety {}".format(words[idx], len(set(words[idx]))/len(words[idx])))