CS304: Frequently Asked Questions

Whenever we discover something, solve a knotty bug, or come across anything else that is worth keeping around as a reminder, please let me know so that I can add it to this list.

Click on a question to toggle it

How do I download / copy one of the course directory's download folders to my personal computer?

Each of the directories in the course account, ~cs304/pub/downloads has an associated zip file in a sibling folder. (I used zip because it's pretty common on Windows and MacOS.) You can download and unpack them as follows, executing these commands in the directory you want to download to:

      
curl -O https://cs.wellesley.edu/~cs304/zip/sqlite.zip
unzip sqlite.zip
Notice that there is no pub in the URL: that's because pub is short for public_html and that directory is implicit in URLs.
How do I copy files from my partner's account to my own?

You can't copy them from your partner, but your partner can drop the files to you. See this explanation for more detail, but the quick summary is that your partner should do:

      
tar cf dir.tar dir/
drop youracct dir.tar
and then you can go to your drop folder, untar them, and copy them to where you want them.
How do I install virtualenv?

Conceptually, the steps are these:

  1. get to the correct directory
  2. delete any old venv
  3. create the virtual environment in a folder called venv

Here are the unix commands:

cd ~/cs304/
rm -r venv
virtualenv venv

If you have any trouble, talk to Scott or a tutor.

How do I use virtualenv?

Whenever you login to your Tempest account to work on CS 304, you would do the following:

cd ~/cs304/
source venv/bin/activate

You can then work in any directory using the Python modules in your virtual environment.

If you want to use a different virtual environment, you can do:

deactivate

and then activate the other venv in the same way.

How do I install pymysql/flask/etc?

The pip command installs standard Python libraries from the internet. You will have to activate your virtualenv so that pip will install to your virtualenv.

cd ~/cs304
source venv/bin/activate
pip install pymysql
pip install flask
How do I install the DBI module?

A version of the cs304dbi module was distributed with the pymysql folder. If you don't have that folder, you can copy the folder from the course directory (see above).

To make the DBI module available throughout your course directories, you can copy it to the virtual environment's site-packages directory:

cp ~/cs304/pymysql/cs304dbi.py ~/cs304/venv/lib/python3.6/site-packages

If your virtual environment is activated and isn't in a standard place, say because you are working on your laptop in some personal configuration, the following command uses an environent variable that should install cs304dbi into your virtual environment:

cp ~/cs304/pymysql/cs304dbi.py $VIRTUAL_ENV/lib/python3.6/site-packages

Note that you may have to edit that command if you're using a different minor version of Python (say, 3.5 instead of 3.6).

How do I use the DBI (cs304dbi) module?

Assuming the module is installed, use the pydoc command to read the documentation.

pydoc cs304dbi

To make the DBI module available throughout your course directories, you can copy it to the virtual environment's site-packages directory:

cp ~/cs304/pymysql/cs304dbi.py $VIRTUAL_ENV/lib/python3.6/site-packages
How do run my Flask program?

It can be helpful to have a checklist. This works for me in the demo account, assuming it has the people_app that we discussed in class:

        source ~/cs304/venv/bin/activate
        cd ~/cs304/people_app/
        python app.py
    

Then clicking on the link usually works. VS Code automatically sets up an SSH tunnel.

If you already have activated your venv, you can skip the source command, though it won't hurt.

How do I kill my Flask process?

Assuming that you're at the terminal (shell) that is running Flask, you just type ^C (control-c). But you probably knew that.

So, this question only arises if you aren't at that terminal or have lost it. That means you have to determine the process ID (PID) of your flask process and kill that process. The PID is an arbitrary 4 or 5 digit number, and will be different every time you run flask.

I'll describe two approaches, one that uses a simple script that I have supplied, but which won't work on any other computer system, and a general approach that will expand your knowlege of Unix.

  • The simple way is to use the ~cs304/pub/bin/kill-my-flask-process command. It wants a port number on the command line or the keyword id, in which case it'll use your id. Examples:
    ~cs304/pub/bin/kill-my-flask-process id
    ~cs304/pub/bin/kill-my-flask-process 1943        
    
  • The more general way is to use some Unix commands you probably don't know. Let's assume that the port that your flask process is running on is 2345. You can find open network programs using the netstat command. You can use grep to filter that output to look for your port. That should, hopefully, print just the process PID that you need. Then, you can then kill the process with the kill command, giving the PID you learned from netstat and grep.

    Here's an example. You may have to scroll horizontally to see the PID information printed by netstat.

    $ netstat -ntlp | grep 2345
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    tcp        0      0 0.0.0.0:2345            0.0.0.0:*               LISTEN      56789/python
    $ kill 56789
    $ netstat -ntlp | grep 2345
    (Not all processes could be identified, non-owned process info
     will not be shown, you would have to be root to see it all.)
    

    Note that netstat won't tell you about processes you don't own, so it issues that warning every time. Don't worry about it.

Can I login to my CS account from off-campus?
Yes. The CS server is accessible globally. Just be sure to use the full name: cs.wellesley.edu. For example:
$ ssh cs304guest@cs.wellesley.edu
Can I access my Flask app from off-campus?
Yes, but there's a trick. The campus firewall does not allow access to our "UID" ports from off-campus, but you can get inside the campus firewall in one of two ways:
  • Use the VPN software that LTS supports.
  • Use SSH Port Forwarding/Tunneling. For example, my Tempest UID (and hence my port) is 1492. On-campus, I would use a URL like http://cs.wellesley.edu:1942/. To set up an SSH tunnel, I would do the following.

    In a shell on my off-campus laptop, I would type:

    $ ssh -L 8080:localhost:1942 anderson@cs.wellesley.edu

    Once I login as anderson@cs.wellesley.edu, that sets up port 8080 on my laptop to forward port 1942 from cs.wellesley.edu. Obviously, you would substitute your own account and your own port.

    Then, in my laptop's browser, I go to localhost:8080/

    If you're a Windows user, you should use PuTTY. The following SSH on Windows article explains how to use PuTTY and how to set up an SSH tunnel using PuTTY.

The advantage of SSH tunnels over the VPN is slightly higher performance and, sometimes, easier setup, but the advantage is small, so use whichever you prefer. We must use the VPN when we use CAS.

Checklist for Viewing Flask App from Off-Campus
  • set up the SSH tunnel in an ordinary terminal (or use the VPN)
  • In VS Code:
    1. login
    2. activate your venv
    3. navigate to your app
    4. run app.py (or the equivalent)
  • In a browser, go to localhost:8080
I'm having trouble with SQL queries that involve the `release` column.
As of MySQL 4+, the `release` keyword is a reserved word. We can still use it in queries, but it has to be surrounded by back-quotes. So the following fails:
select tt,title,release from movie;
but the following works:
select tt,title,`release` from movie;
Make sure they are backquotes not apostophes. On most keyboards, the backquote shares the key with the tilde on it, not the key with the double-quote character. Look to the left of the digit `1`.
In the CRUD assignment, movies with multiple words in the title don't work. It only shows the first word.
The full title is probably there in the HTML. Do a "view source" and you will probably see them, but parsed as attributes of the input rather than the value. The template needs to surround a value with quotation marks.
My images or CSS aren't working.

Make sure you use url_for() throughout your code. The images and the CSS files need to be in the static folder, not in the templates folder as you might think.

Also, browsers will cache copies of your images and CSS files. To get the latest updates, be sure to use shift+reload.

How can I copy the WMDB to my own database?

There's a command in the course account bin directory that should do the trick:

~cs304/pub/bin/copy-wmdb

If that fails, it's usually due to a table that can't be dropped due to a foreign key constraint. If you're still puzzled, there's a command in the course account bin directory that might help:

~cs304/pub/bin/copy-wmdb-explain

Of course, if that doesn't help, talk to Scott

How can our team share a database?

Scott should have given you access to your team database from your personal account. If that's not working, talk to him.

multiple search critera

Yes, it's possible to allow the user to search by different criteria. It's tricky; much harder than the stuff we've done so far, but it's been done in past student projects.

The first strategy is simple but suffers from combinatorial explosion, namely to choose the search based on different criteria:


if search by num beds and user:
    select * from listing where city = %s and user = %s and numBeds = %s 
if search by num beds:
   select * from listing where city = %s and numBeds = %s''
elif:
    search by city   select * from listing where city = %s and user = %s"
elif:
    ...

You can see how the first case checks for both criteria and then we check for singletons. So, we get 3 cases with 2 criteria, and 7 cases with 3 criteria and 2n-1 with n criteria, hence the combinatorial explosion.

Of course, if you disallow combinations, it's a bit easier.

The alternative is more sophisticated, where you use criteria that can be made into wildcards. Let's just discuss numBeds. We'll use 0 (zero) to mean any number of beds. (Or you could use -1 as the wildcard value.)


if search by num beds:
    bed_val = request.args.get('desired-beds')
else:
    bed_val = 0
"select * from listing where (%s = 0 or %s = numBeds) and ...", [bed_val, bed_val, ...]

Notice how we use bed_val twice: once to compare to the wildcard value and once to compare to the number of beds in the listing. If bed_val is 2, it has to match the number of beds in the listing, but if it's zero, it'll match the constant zero and the number of beds is irrelevant.