0

I'd appreciate some help generating the required table for index.html. My code for the index() route within application.py is below:

# call this part A - accessing the data in the "transactions" table

shares_owned = db.execute("SELECT symbol, name, SUM (num_shares_buy), SUM (cost) FROM transactions WHERE id = :id GROUP BY symbol", id = session["user_id"])
num_shares_owned = len(shares_owned)
for n in range(num_shares_owned): # n is the index of the item in the list
    share = shares_owned[n] # access the dict at position [n] on the list and call this "share"...
    share["num_shares_owned"] = share["SUM (num_shares_buy)"]
    share["total_cost"] = share["SUM (cost)"]
    # lookup symbol using lookup() method. Returns a dict object with three key-value pairs:
    # ...name, price, & symbol
    x = lookup(share["symbol"])
    share["current_price"] = x["price"]
    share["total_asset_value"] = share["current_price"] * share["SUM (num_shares_buy)"]
    share["gain_loss"] = share["total_asset_value"] - share["SUM (cost)"]

    # call this part B - debug tests - will appear in terminal
    print(share["name"])
    print(share["symbol"])
    print("You own {} shares of {}".format(share["SUM (num_shares_buy)"], share["name"]))
    print("You paid a total of {}".format(share["SUM (cost)"]))
    print("The current price of {} is {}".format(share["name"], share["current_price"]))
    print("Your shares of {} are currently worth {}".format (share["name"], share["total_asset_value"]))
    print("You made a gain(loss) of {}".format(share["gain_loss"]))

return render_template("index.html", placeholder = share, shares_owned = shares_owned)

I'm able to iterate through the various shares my user owns, sum them, and create the data required for my html table. For example, the print() statements I'm using to debug give the following output in the terminal, matching the data in finance.db:

Apple Inc.

AAPL

You own 1 shares of Apple Inc.

You paid a total of 155.45

The current price of Apple Inc. is 153.93

Your shares of Apple Inc. are currently worth 153.93

You made a gain(loss) of -1.5199999999999818

Alphabet Inc.

GOOG

You own 3 shares of Alphabet Inc.

You paid a total of 2926.8

The current price of Alphabet Inc. is 983.68

Your shares of Alphabet Inc. are currently worth 2951.04

You made a gain(loss) of 24.23999999999978

Snap Inc.

SNAP

You own 5 shares of Snap Inc.

You paid a total of 105.45

The current price of Snap Inc. is 20.21

Your shares of Snap Inc. are currently worth 101.05000000000001

You made a gain(loss) of -4.3999999999999915

Tesla, Inc.

TSLA

You own 5 shares of Tesla, Inc.

You paid a total of 1699.25

The current price of Tesla, Inc. is 347.32

Your shares of Tesla, Inc. are currently worth 1736.6

You made a gain(loss) of 37.34999999999991

However, when I try to pass this into index.html, using the for-loop in Jinja combined with the render.template() command above, I get the following output:index.html

My code for index.html is below:

{% extends "layout.html" %}

{% block title %}
    Portfolio
{% endblock %}

{% block main %}
    <table>    
        <tr>
            <th>Symbol</th>
            <th>Name</th>
            <th>Number of Shares Owned</th>
            <th>Total Cost Paid ($US)</th>
            <th>Current Value of Your Shares ($US)</th>
            <th>Gain/(Loss) ($US)</th>
        </tr>

        {% for share in shares_owned %}
        <tr>
            <td>{{placeholder.symbol}}</td>
            <td>{{placeholder.name}}</td>
            <td>{{placeholder.num_shares_owned}}</td>
            <td>{{placeholder.total_cost}}</td>
            <td>{{placeholder.total_asset_value}}</td>
            <td>{{placeholder.gain_loss}}</td>
        </tr>
        {% endfor %}
    </table>

{% endblock %}

I understand why this is happening! The "for n in range(num_shares_owned):" statement iterates through all of the shares owned, and variable share gets set to represent the dict of the final iteration (in this case, Tesla and all its data). So the Jinja code just iterates four times, but each time is only looking at this one dict.

What I don't know how to do is to iterate over each dict in the list "shares_owned" in turn, and pass their data individually to index.html

I'd really appreciate any hints you have!

Finally - I see I have some work to do getting data into nice clean formats (e.g. $US to say two decimal places). That can wait!

Many thanks in advance for your help.

4
  • I should have said "I think I understand why this is happening" ;) Jun 5, 2017 at 21:46
  • Why do you need placeholder and shares_owned in index.html? Isn't everything you want/need in shares_owned? To be less cryptic, don't you want share.symbol instead of placeholder.symbol? Jun 5, 2017 at 22:02
  • As DinoCoderSaurus said in the comment above, I think everything you want/need is in shares_owned. I would ditch the placeholder variable in render_template at the bottom of your code. I did this pset in php a while back so...that said--it looks to me as if what is happening is you're setting placeholder to the last value of share after exiting the for loop (therefore it will be that last value, e.g. TSLA every time) when you call render_template.
    – johnnyd3
    Jun 5, 2017 at 23:33
  • Thanks both - really helped solve the problem! Jun 14, 2017 at 14:38

1 Answer 1

1

I was tripped out by a similar problem for quite some time before I actually figured out something that worked for me.

In my case, what I did is I declared an empty list of rows and initialized an index variable to 0. Then I assigned my SELECT statement to another variable (ex.: data). Then in the for loop in application.py I constructed each row by creating a row variable and assigning it a dict which contained all the values I wanted to have in each row. The index allows to iterate through each entry retrieved by the SELECT call. Once my row was constructed with the relevant values I appended that row to my list of rows. That list is what I looped over in Jinja.

Here is a small example in a nutshell:

index = 0
rows = []

data = db.execute("SELECT symbol, name FROM transactions WHERE id = :id 
GROUP BY symbol", id = session["user_id"])

for entry in data:
    row = dict(symbol=data[index]["symbol"],
    name=data[index]["name"])
    rows.append(row)
    index += 1

 return render_template("index.html",rows=rows)

Then in Jinja:

{% for row in rows %}
    <tr>
        <td> {{ row.symbol }} </td>
        <td> {{ row.name }}</td>
    </tr>
{% endfor %}

In some cases, depending of the operations I needed to do on the data, I had better results declaring the variables outside of the dictionary like so:

for entry in data:
    symbol = data[index]["symbol"]
    name = data[index]["name"]
    row = dict(symbol=symbol,
    name=name)
    rows.append(row)
    index += 1 

Hope that helps...

1
  • Thanks Mynah - interesting approach and different from what I had thought of - great to learn something new! Jun 14, 2017 at 14:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .