Welcome to Part 5 of my tutorial into the completion of CS50’s Finance problem set. This week I will discuss the implementation of Sell. With Sell, we want our user to be able to sell stocks from their portfolio. To do this, we must first give the user a way to choose an available stock from their portfolio. As in the previous weeks, we will start by showing the html file and then move onto the Python code that will execute in the backend.

So, let’s look at the sell.html file shown below. By now in the problem set you should feel pretty comfortable with reading and understanding what is going on in this file. Please be sure to try and write this out yourself and only refer here if you run into a road block. As before, we nest everything into a form that we will submit that will execute our Python code. One thing that is different here is that we are using a new html element of <select>. This element gives the user a drop down menu from which to choose an <option>. For more information on the select and option tags, refer to the W3Schools website. Now, there are other ways that you can choose to show the options to your user. Go ahead and try messing around with some other html tags as this will be good practice. I have chose to use the drop down as I feel that this is the most intuitive. Notice that our option tag is nested in a Jinja for loop. This technique is how we will limit the stock the user can sell to only stocks in which they own. The key for the value attribute of the option tag and the value between the opening and closing tags is set to {{ stock.symbol }}. So, the symbol for the stock is shown to the user as an option to select (inside the tags) and the value that will return when the user hits the submit button (key for the value attribute). The next elements allows the user to select the number of shares to sell and a button to submit the form, both which you have seen before.

Now, on to the back end Python code. The firs part of the sell function is identical to the buy function that we covered two weeks ago. So, I will start here at the declaration of the available_shares variable. By now, the SQL statements should be very readable to you. Here, we are summing the the total shares of a particular stock that is in a user’s portfolio and calling that return value total_shares. We are passing in the selected stock symbol that the user picked from the drop down menu. Now, you may be asking: How did we set what available stocks for the user to choose from? Right now we are working on the POST method, which executes when the form is submitted. Prior to that the user landed at the page via the GET method (through the URL by clicking a link). So, we will cover that portion when we get to the else portion of the if statement, which will cover the GET method.

Now, we want to make sure that the user is unable to sell more shares than they own. Makes sense. So, if our available_stock table returns 0 for the total_shares (i.e. the user has sold all of the shares that they owned), or the user tries to select an amount to sell that is greater than total_shares we will return the error message “not enough shares.” the price and total_price variables should look familiar. We need to know the total price for which our user will sell their stocks so that we can update the cash on their account. In the next db.execute statement we use SQL to update the users cash to equal their current cash plus the amount for which they sold the stock (total_price). We also enter another transaction into the transactions table that will show the transaction of the sale. Finally, we redirect the user to their home page, which will now show an updated portfolio after the sale.

Now, we get to how the user can select their available_stocks from the drop down menu. When the page is reached via GET (when the user clicks the sell link) we will execute the statements under the else. Here we are using the SQL statement to set available_stocks equal to the the stock symbols that the user has associated with them in the transactions table. It is important to note, that we must GROUP BY symbol to ensure we don’t get any duplicates in the drop down menu. You will notice that we also used this technique when getting the available_shares as well. Finally, we pass the available_stocks table to the rendering of the sell.html file that will allow our Jinja code from before to execute. And now, we can limit the stocks that the user can sell to stocks that appear in their portfolio.

And that is all for the implementation of sell from the Finance problem set. If you found this tutorial helpful, please remember to share on your favorite social media site by clicking the buttons below. Comment below with any questions and I will help the best I can. As always…Happy Programming!!


  1. Good evening, I have received error messages, in helpers.py, any tips ???
    I just changed this:

    @wraps (f)
         def decorated_function (wallet, rows):
             if session.get (“user_id”) is None:
                 return redirect (“/ login”)
             return f (wallet, rows)
         return decorated_function



  2. Hi, thank you very much for the tutorial. I have a bug. From the message below I understand that the table “transactions” doesn’t exist. Do I have to create it with phpliteadmin?


    DEBUG:cs50:SELECT symbol, SUM(shares) as total_shares FROM transactions WHERE user_id = 4 GROUP BY symbol HAVING total_shares > 0
    ERROR:flask.app:Exception on / [GET]
    Traceback (most recent call last):
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py”, line 2292, in wsgi_app
    response = self.full_dispatch_request()
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py”, line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py”, line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/_compat.py”, line 35, in reraise
    raise value
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py”, line 1813, in full_dispatch_request
    rv = self.dispatch_request()
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/flask/app.py”, line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
    File “/home/ubuntu/workspace/pset7/finance2/helpers.py”, line 33, in decorated_function
    return f(*args, **kwargs)
    File “/home/ubuntu/workspace/pset7/finance2/application.py”, line 45, in index
    “SELECT symbol, SUM(shares) as total_shares FROM transactions WHERE user_id = :user_id GROUP BY symbol HAVING total_shares > 0”, user_id=session[“user_id”])
    File “/opt/pyenv/versions/3.6.0/lib/python3.6/site-packages/cs50/sql.py”, line 224, in execute
    raise e
    RuntimeError: no such table: transactions [SQL: ‘SELECT symbol, SUM(shares) as total_shares FROM transactions WHERE user_id = 4 GROUP BY symbol HAVING total_shares > 0’] (Background on this error at: http://sqlalche.me/e/e3q8)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s