This worksheet focuses on Flask web applications, anonymous functions, and decorators.
These things might be helpful while working on the problems. Remember that for worksheets, we don't strictly limit what resources you can consult, so these are only suggestions.
The Flask application written in lecture was called TaskGain or ActiveTask, depending on which section of MCS 275 you are in. The applications are quite similar, and use a SQLite database to manage a collection of tasks that have owners, privacy settings, state (e.g. "in progress"), and a timestamp of creation or update.
To prepare for the next problem, download a copy of the Flask application for your section and get it running on your computer.
The application has a number of files, so you can do it in either of these ways:
taskgain.py
- Main programadd_sample_tasks.py
- Utility to add sample taskstimefmt.py
- Module for time formattingstatic/
- Subdirectory for static filesstatic/taskgain.css
- Main stylesheettemplates/
- Subdirectory for templatestemplates/task_list_view.html
- Template for task listtemplates/add_task_form.html
- Template for new task formtemplates/front.html
- Template for front pageactivetask.py
- Main programadd_sample_tasks.py
- Utility to add sample taskstimefmt.py
- Module for time formattingstatic/
- Subdirectory for static filesstatic/activetask.css
- Main stylesheettemplates/
- Subdirectory for templatestemplates/task_list_view.html
- Template for task listtemplates/add_task.html
- Template for new task formtemplates/front.html
- Template for front pageOpen a terminal and cd
to the location of the main .py
script (taskgain.py
or activetask.py
). Run that script with Python, e.g. using a command
python3 taskgain.py
or similarly with your interpreter name and possibly replacing taskgain
with activetask
.
You should see output similar to this:
* Serving Flask app 'taskgain'
* Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
Notice the port number 5000
on the second-to-last line. It might not be 5000
for you, but you need to know it.
Now, open a browser and visit http://localhost:5000/
, replacing 5000
with the port number as needed.
You should see a fronty page which lets you enter a username (and which directs you to that user's task list.) Try logging in, modifying tasks, and making a new task. (You'll need to manually enter the URL localhost:5000/task/new/
to make a new task.)
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.
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.
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.
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.