<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Uncategorized &#8211; Learn | Think | Code</title>
	<atom:link href="https://johnyzaguirre.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>https://johnyzaguirre.com</link>
	<description>Projects i&#039;ve worked on, articles i&#039;ve written, and tutorials i&#039;ve recorded</description>
	<lastBuildDate>Mon, 27 Apr 2020 12:33:14 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.6.8</generator>

<image>
	<url>https://johnyzaguirre.com/wp-content/uploads/2020/04/cropped-kisspng-incandescent-light-bulb-emoji-led-lamp-symbol-5aff6eb3f3aaf8.7281496115266894599981-32x32.png</url>
	<title>Uncategorized &#8211; Learn | Think | Code</title>
	<link>https://johnyzaguirre.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Problem Set 7: CS50 Finance</title>
		<link>https://johnyzaguirre.com/2020/01/02/problem-set-7-cs50-finance/</link>
					<comments>https://johnyzaguirre.com/2020/01/02/problem-set-7-cs50-finance/#comments</comments>
		
		<dc:creator><![CDATA[Johnny]]></dc:creator>
		<pubDate>Thu, 02 Jan 2020 12:55:42 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CS50]]></category>
		<guid isPermaLink="false">https://johnyzaguirre.com/?p=1523</guid>

					<description><![CDATA[Building an app is a process that needs structure I made an initial attempt that went very poorly. I read the CS50 assignment points and went through building the app page for page. Make all the code to register, then make all the code to get a quote, then buy, then sell. I started getting &#8230; <p class="link-more"><a href="https://johnyzaguirre.com/2020/01/02/problem-set-7-cs50-finance/" class="more-link">Continue reading<span class="screen-reader-text"> "Problem Set 7: CS50 Finance"</span></a></p>]]></description>
										<content:encoded><![CDATA[
<h2>Building an app is a process that needs structure</h2>



<p>I made an initial attempt that went very poorly. I read the CS50 assignment points and went through building the app page for page. Make all the code to register, then make all the code to get a quote, then buy, then sell. I started getting very picky about how the user got feedback when something was posted. I wanted nice banners to show things were successful or unsuccessful. I wanted javascript on the front end to update values. Everything became a big mess.</p>



<p>So i deleted it all. And pulled out some post-it notes, and a pencil.</p>



<p>I made 3 stacks:</p>



<ul><li>Frontend</li><li>Database</li><li>Logic</li></ul>



<p>Then I started writing down all the tasks as I read them on the CS50 assignment page. Each post was very simple and specific. On the top left corner of each post-it I put the first letter of what stack it would go on. On the top right I put the first letter for the webpage (register, buy, sell, quote etc).</p>



<p>A post-it might be &#8220;create view template register.html,&#8221; which would be a F on the top left.</p>



<p>another might be &#8220;create model for users,&#8221; which would be a D.</p>



<p>&#8220;create get_balance method for users,&#8221; another D.</p>



<p>What I found was the Frontend stack could be done very quickly because I noticed there were similar tasks. They weren&#8217;t directly connected the way a user thinks when reading about the app. They were literally the same task just for a different page of the app.</p>



<p>So my advice would be to write out as many tasks as possible, sort them in this way, and try to develop frontend -&gt; database -&gt; logic.</p>



<p>For the database I highly recommend creating a new file called models.py and creating a class for each part of your app. I created <strong>users, transactions and portfolio</strong>. Here is what that looks like:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/3307cdb7bad663740e3204d2ac7f1f4a">Gist</a>.
</div></figure>



<p>During the database phase I recommend using the python terminal REPL. If you go into the directory that holds application.py for the flask app, you can actually test out any function, class or method right in the terminal. Here is an example of me using the terminal to test some of the user database methods:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1707" height="1087" src="https://johnyzaguirre.com/wp-content/uploads/2019/12/Screen-Shot-2019-12-28-at-7.28.53-PM.png" alt="" class="wp-image-1547" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/12/Screen-Shot-2019-12-28-at-7.28.53-PM.png 1707w, https://johnyzaguirre.com/wp-content/uploads/2019/12/Screen-Shot-2019-12-28-at-7.28.53-PM-300x191.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/12/Screen-Shot-2019-12-28-at-7.28.53-PM-768x489.png 768w, https://johnyzaguirre.com/wp-content/uploads/2019/12/Screen-Shot-2019-12-28-at-7.28.53-PM-1536x978.png 1536w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>type <strong>python -i application.py</strong><em>.</em> This is interactive mode and makes testing models easier so you don&#8217;t have to submit forms.</p>



<p>When you finish the database make sure to add some fake data to save time during the logic portion.</p>



<p>Logic is something like &#8220;if the user does not have enough cash to by stocks return apology.&#8221;</p>



<h2>API changes</h2>



<p>In the helpers file on line 42 I changed the url because the one given doesn&#8217;t work. Here is the actual api now <a href="https://iexcloud.io/docs/api/#quote">https://iexcloud.io/docs/api/#quote</a></p>



<p>change to this on line 42:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">        response = requests.get(f&quot;https://cloud.iexapis.com/stable/stock/{urllib.parse.quote_plus(symbol)}/quote?token=YOUR_FREE_APITOKEN&quot;)
</pre></div>



<p>change your_free_api_token with your own token when you sign up.</p>



<h2>Other quick notes</h2>



<p>datetime: <a href="https://www.techonthenet.com/sqlite/functions/datetime.php">https://www.techonthenet.com/sqlite/functions/datetime.php</a></p>



<p>foreign keys: <a href="https://sqlite.org/foreignkeys.html">https://sqlite.org/foreignkeys.html</a></p>



<p>inner joins: <a href="https://www.sqlitetutorial.net/sqlite-inner-join/">https://www.sqlitetutorial.net/sqlite-inner-join/</a></p>



<h2>Using the with keyword for opening and closing sqlite3</h2>



<p>In python there is a way to open a sql connection and automatically close it using <strong>with</strong>.</p>



<p>Here would be the standard way of connecting to a database and closing it at the end.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import sqlite3
conn = sqlite3.connect('example.db')
c = conn.cursor()

c.execute('''CREATE TABLE stocks
             (date text, trans text, symbol text, qty real, price real)''')
c.execute(&quot;INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)&quot;)

# Save (commit) the changes
conn.commit()

# close the connection if we are done with it.
conn.close()</pre></div>



<p>Now using <strong>with</strong>:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import sqlite3
  with sqlite3.connect('example.db') as conn:
    c = conn.cursor()

    c.execute('''CREATE TABLE stocks
                 (date text, trans text, symbol text, qty real, price real)''')
    c.execute(&quot;INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)&quot;)

    # Save (commit) the changes
    conn.commit()

    # connection automatically closed once we leave this indented section of code</pre></div>



<h2>Questions?</h2>



<p>This was a much bigger project, so if you have any questions please let me know and i&#8217;ll do my best to answer. My code will be up on github:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/46a9143472ef0c8eb906da159837b47b">Gist</a>.
</div></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://johnyzaguirre.com/2020/01/02/problem-set-7-cs50-finance/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>CS50 Week 8: Notes</title>
		<link>https://johnyzaguirre.com/2019/11/30/cs50-week-8-notes/</link>
					<comments>https://johnyzaguirre.com/2019/11/30/cs50-week-8-notes/#respond</comments>
		
		<dc:creator><![CDATA[Johnny]]></dc:creator>
		<pubDate>Sat, 30 Nov 2019 01:32:32 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CS50]]></category>
		<guid isPermaLink="false">https://johnyzaguirre.com/?p=1499</guid>

					<description><![CDATA[CS50 store demo Cookies and sessions start off this weeks lecture notes. The important thing to remember is http protocol is a stateless protocol. This means traditionally you request a webpage, the server gives you the page data and nothing else happens. Similar to going to a store, buying an item and leaving. The cashier &#8230; <p class="link-more"><a href="https://johnyzaguirre.com/2019/11/30/cs50-week-8-notes/" class="more-link">Continue reading<span class="screen-reader-text"> "CS50 Week 8: Notes"</span></a></p>]]></description>
										<content:encoded><![CDATA[
<h2>CS50 store demo</h2>



<p>Cookies and sessions start off this weeks lecture notes. The important thing to remember is http protocol is a <strong><em>stateless</em></strong> protocol. This means traditionally you request a webpage, the server gives you the page data and nothing else happens. Similar to going to a store, buying an item and leaving. The cashier doesn&#8217;t remember you next time. That is what stateless means. </p>



<p>Cookies and sessions allow the experience to be more <strong><em>stateful</em></strong>, meaning when you request a webpage, a cookie is inside that request header giving the server some <em>unique info about you</em>. This returns a webpage made only for you. Back to the store analogy, if every Monday you bought eggs, and the store had a way of knowing it was you right when you walked in, someone would just bring you eggs or even have them ready for you in advance at the register.</p>



<p>Here is the store demo code for application.py</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/b79424192a4acbcd21114ae1559c9e4f">Gist</a>.
</div></figure>



<p>On line 8 setting the SESSION_PERMANENT value to False means we do not store the session after the browser has been closed. If you quit the browser program and re-open it, the cart values will not be saved. However if the browser is still open and you close just the window, or tab, the cart values will persist. The SESSION_TYPE we are using is filesystem, which means our session values are stored on the server (in a folder called flask_session).</p>



<h2>MVC &#8211; Model View Controller</h2>



<p>MVC is a way of organizing pieces of a web application. The model is where all the database calls are made (variables being used in SQL statements most of the time). The View is for templating, like jinja2, the look of your pages. The controller is usually a main routes page like application.py, where decisions are made based on what the user is doing.</p>



<h2>A Simple Example</h2>



<p>I downloaded the lecture.db file from the notes and put it in the same directory as this script:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from cs50 import SQL

db = SQL(&quot;sqlite:///lecture.db&quot;)

# Query database for all albums
rows = db.execute(&quot;SELECT * FROM Album&quot;)

# For each album in database
for row in rows:
	# Print title of album
	print(row[&quot;Title&quot;])</pre></div>



<p>In my terminal I got this result:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="890" height="1304" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.05.25-PM.png" alt="" class="wp-image-1513" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.05.25-PM.png 890w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.05.25-PM-205x300.png 205w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.05.25-PM-768x1125.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure>



<p>Using sys.argv[1] we can pass variables into the command line which get substituted.</p>



<p>like this:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">rows = db.execute(&quot;SELECT * FROM Album WHERE Title = :t&quot;, t=sys.argv[1])</pre></div>



<p>Its important to remember we don&#8217;t use the normal formatting syntax f&#8221;my string {variable}&#8221; in this case. Because the variables are <strong>sanitized</strong>, meaning the removal of potentially harmful characters. SQL injection is a thing attacks can use to get into our databases, so it&#8217;s important to just know we need this sanitization before running our sql statements.</p>



<h2>Adding Flask to the mix</h2>



<p>So with a flask application we will use the lecture.db file to show album titles on a webpage:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from flask import Flask, render_template, request

from cs50 import SQL

app = Flask(__name__)

db = SQL(&quot;sqlite:///lecture.db&quot;)

@app.route(&quot;/&quot;)
def index():
    rows = db.execute(&quot;SELECT * FROM Album&quot;)
    return render_template(&quot;index.html&quot;, albums=rows)</pre></div>



<p>running this (I had to remove eprint) will show a block of text on the browser, which is all the album titles. But the cool thing is we&#8217;re using a database. So we have state, which means we can save things for later =).</p>



<h2>Query arguments</h2>



<p>We can also pass query arguments from the URL using a GET request type:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">@app.route(&quot;/&quot;)
def index():
    query = request.args.get(&quot;q&quot;)
    rows = db.execute(&quot;SELECT * FROM Album WHERE Title LIKE :q&quot;, q=query+&quot;%&quot;)
    return render_template(&quot;index.html&quot;, albums=rows)</pre></div>



<p>Above is a modified version of the example code. Using LIKE and a % symbol which is a wildcard, you can just use a single letter and it will return whatever starts with it.</p>



<p>So this URL: <a href="http://127.0.0.1:5000/?q=f">http://127.0.0.1:5000/?q=f</a></p>



<p>returns this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1264" height="1449" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.30.27-PM.png" alt="" class="wp-image-1517" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.30.27-PM.png 1264w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.30.27-PM-262x300.png 262w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.30.27-PM-768x880.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure>



<p>So this is apparently enough for us poor online learning only souls to <strong>create an app for buying and selling stocks!</strong></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="398" height="222" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.32.05-PM.png" alt="" class="wp-image-1519" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.32.05-PM.png 398w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-29-at-8.32.05-PM-300x167.png 300w" sizes="(max-width: 398px) 100vw, 398px" /></figure></div>



<p>See you in the next one.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://johnyzaguirre.com/2019/11/30/cs50-week-8-notes/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CS50 Week 7: Walkthroughs</title>
		<link>https://johnyzaguirre.com/2019/11/23/cs50-week-7-walkthroughs/</link>
					<comments>https://johnyzaguirre.com/2019/11/23/cs50-week-7-walkthroughs/#respond</comments>
		
		<dc:creator><![CDATA[Johnny]]></dc:creator>
		<pubDate>Sat, 23 Nov 2019 21:54:38 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CS50]]></category>
		<guid isPermaLink="false">https://johnyzaguirre.com/?p=1425</guid>

					<description><![CDATA[Hello name in python to start it off: Let&#8217;s quickly run through the &#8220;tougher&#8221; Déjà vu walkthroughs ( and then go deeper into the final similarities web app. Let&#8217;s start with the Mario challenge: mario.py So let&#8217;s build a pyramid shape in the terminal: 4 lines. Google range() and it&#8217;s arguments, then google rjust() and &#8230; <p class="link-more"><a href="https://johnyzaguirre.com/2019/11/23/cs50-week-7-walkthroughs/" class="more-link">Continue reading<span class="screen-reader-text"> "CS50 Week 7: Walkthroughs"</span></a></p>]]></description>
										<content:encoded><![CDATA[
<p>Hello name in python to start it off:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">print(f&quot;Hello {input('name: ')}&quot;)</pre></div>



<p>Let&#8217;s quickly run through the &#8220;tougher&#8221; Déjà vu walkthroughs ( and then go deeper into the final <em>similarities </em>web app. Let&#8217;s start with the <strong><em>Mario</em></strong> challenge:</p>



<h2>mario.py</h2>



<p>So let&#8217;s build a pyramid shape in the terminal:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">height = int(input(&quot;enter a number for your mario pyramid: &quot;))
for i in range(2, height+2):
    print(('#'*i).rjust(height+1), end=&quot; &quot;)
    print('#' * i)</pre></div>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="357" height="200" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/source.gif" alt="" class="wp-image-1428"/></figure></div>



<p>4 lines.</p>



<p>Google range() and it&#8217;s arguments, then google rjust() and it&#8217;s arguments. Use print statements to figure out what I did. If you have any questions try to say what this is doing out loud with a small number (like 2 for the user input). Comment below if you have any questions.</p>



<h2>cash.py</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">cash = float(input(&quot;please enter cash amount to break down into coins (example 1.25): &quot;))
coins = {&quot;quarters&quot;: .25,&quot;dimes&quot;:.10,&quot;nickels&quot;:.05,&quot;pennies&quot;:.01}
for key, coin in coins.items():
	(coins[key], cash) = (divmod(cash,coin)[0], round(divmod(cash,coin)[1],2))
print(coins)</pre></div>



<p>Short but not impossible to read. Pull apart the packed variables and google divmod(), which is a very handy function in this case. <a href="https://johnyzaguirre.com/2018/11/13/cs50-week-6/">Go back to my python article that goes through packing and unpacking if you need a refresher.</a></p>



<h2>Caesar.py</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import sys

if len(sys.argv) != 2: 
  print(&quot;Usage: python3 caesar.py key&quot;)
  sys.exit(0)
key = int(sys.argv[1])

message = input(&quot;enter a secret message: &quot;)

def cipher(letter, key):
	if not letter.isalpha():
		return letter
	offset = 65 if letter.isupper() else 97
	return chr(((ord(letter) - offset) + key) % 26 + offset)

print(f&quot;userinput: {message}&quot;)
print(&quot;decoded_text: &quot; + ''.join([cipher(letter, key * -1) for letter in message]))
print(&quot;coded_text: &quot; + ''.join([cipher(letter, key) for letter in message]))</pre></div>



<h2>Similarities (from scratch)</h2>



<p>I&#8217;m going to do one from scratch then i&#8217;ll make it again using the CS50 instructions.</p>



<p>Here is the example image from the CS50 website:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><a href="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-16-at-7.04.16-AM.png"><img loading="lazy" width="1133" height="761" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-16-at-7.04.16-AM.png" alt="" class="wp-image-1447" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-16-at-7.04.16-AM.png 1133w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-16-at-7.04.16-AM-300x202.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-16-at-7.04.16-AM-768x516.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></a></figure></div>



<p>Here was my result. <a href="https://github.com/sojohnnysaid/cs50-similarities" target="_blank" rel="noreferrer noopener" aria-label="You can check out the github repo as well (opens in a new tab)">You can check out the github repo as well</a>. I styled the pages differently and added a number input for the substring page:</p>



<figure class="wp-block-gallery columns-3 is-cropped"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><a href="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM.png"><img loading="lazy" width="1290" height="1449" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM.png" alt="" data-id="1453" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM.png" data-link="https://johnyzaguirre.com/?attachment_id=1453" class="wp-image-1453" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM.png 1290w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM-267x300.png 267w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.08.57-PM-768x863.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></a></figure></li><li class="blocks-gallery-item"><figure><a href="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM.png"><img loading="lazy" width="1290" height="1449" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM.png" alt="" data-id="1452" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM.png" data-link="https://johnyzaguirre.com/?attachment_id=1452" class="wp-image-1452" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM.png 1290w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM-267x300.png 267w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.09.55-PM-768x863.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></a></figure></li><li class="blocks-gallery-item"><figure><a href="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM.png"><img loading="lazy" width="1290" height="1449" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM.png" alt="" data-id="1451" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM.png" data-link="https://johnyzaguirre.com/?attachment_id=1451" class="wp-image-1451" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM.png 1290w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM-267x300.png 267w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-17-at-2.10.52-PM-768x863.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></a></figure></li></ul></figure>



<p>application.py:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from flask import Flask, render_template, redirect, request
from compare import compare_lines, compare_sentences, compare_substrings

app = Flask(__name__)

@app.route(&quot;/&quot;, methods=[&quot;GET&quot;,&quot;POST&quot;])
def index():
    if request.method == &quot;POST&quot;:
        file_one = request.files[&quot;file_one&quot;]
        file_two = request.files[&quot;file_two&quot;]
        return render_template(&quot;index.html&quot;, results=compare_lines(file_one,file_two))
    return render_template(&quot;index.html&quot;, results=None)



@app.route(&quot;/sentences&quot;, methods=[&quot;GET&quot;,&quot;POST&quot;])
def sentences():
    if request.method == &quot;POST&quot;:
        file_one = request.files[&quot;file_one&quot;]
        file_two = request.files[&quot;file_two&quot;]
        return render_template(&quot;sentences.html&quot;, results=compare_sentences(file_one,file_two))
    return render_template(&quot;sentences.html&quot;, results=None)



@app.route(&quot;/substrings&quot;, methods=[&quot;GET&quot;,&quot;POST&quot;])
def substrings():
    if request.method == &quot;POST&quot;:
        file_one = request.files[&quot;file_one&quot;]
        file_two = request.files[&quot;file_two&quot;]
        return render_template(&quot;substrings.html&quot;, results=compare_substrings(file_one,file_two, int(request.form.get('length'))))
    return render_template(&quot;substrings.html&quot;, results=None)


if __name__ == '__main__':
    app.run</pre></div>



<p>The index route goes straight to the matching lines page. All forms send a POST request to the same URL, so i&#8217;m checking for the request type using the IF statement. At the top i&#8217;ve imported my own file <strong>compare</strong>, which has the functions I need to process the files that are being uploaded. Also notice to get the files I use <strong>request.files</strong> and then pass in the form&#8217;s <strong>name</strong> value. This will return what flask calls a <strong><em>filestorage</em></strong><em> </em>object. This thin wrapper allows us to call <strong>read()</strong> which is still in a format that is not decoded because it doesn&#8217;t assume the file is text. </p>



<p>Here is the compare.py file so you can see the function I use to get the text from each file:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from nltk.tokenize import sent_tokenize, word_tokenize

def get_file_data(file_one, file_two):
    #takes filestorage type of bytes and turns file data it into a string
    data = [file_one.read().decode('utf-8'), file_two.read().decode('utf-8')]
    data = [file.replace('&lt;', '&amp;lt;').replace('&gt;', '&amp;gt;') for file in data]
    return data


def get_similarities(file_one, file_two):
    return set(file_one).intersection(file_two)


def format_html(file_one, file_two, similarities):
    #adds span tags and \n re-added if identical lines otherwise just the line with \n re-added
    similarities = list(similarities)
    files = []
    for item in similarities:
        file_one = file_one.replace(item, f&quot;&lt;span&gt;{item}&lt;/span&gt;&quot;, 1)
        file_two = file_two.replace(item, f&quot;&lt;span&gt;{item}&lt;/span&gt;&quot;, 1)
    files.append(file_one)
    files.append(file_two)
    return files

def set_files_as_list_of_strings(formatted_files):
    return [''.join(formatted_files[0]), ''.join(formatted_files[1])]


def compare_lines(file_one, file_two):
    data = get_file_data(file_one, file_two)

    #split string into list of strings wherever a linebreak is found
    file_one = data[0].split('\n')
    file_two = data[1].split('\n')

    #set intersection returns a set of all identical lines between the lists
    similarities = get_similarities(file_one, file_two)

    #adds span tags and \n re-added if identical lines otherwise just the line with \n re-added
    formatted_files = format_html(data[0], data[1], similarities)

    #return as a list of 2 strings
    return set_files_as_list_of_strings(formatted_files)




def compare_sentences(file_one, file_two):
    data = get_file_data(file_one, file_two)

    #TO DO splits data up into sentences
    file_one = sent_tokenize(data[0])
    file_two = sent_tokenize(data[1])

    #set intersection returns a set of all identical sentences between the lists
    similarities = get_similarities(file_one, file_two)

    #adds span tags and \n re-added if identical sentence otherwise just the sentence with \n re-added
    formatted_files = format_html(data[0], data[1], similarities)

    #return as a list of 2 strings
    return set_files_as_list_of_strings(formatted_files)




def compare_substrings(file_one, file_two, length):
    data = get_file_data(file_one, file_two)

    #split string into list of substrings based on user input
    file_one = [char for item in word_tokenize(data[0]) for char in item]
    file_two = [char for item in word_tokenize(data[1]) for char in item]

    slices_one = []
    for i in range(0,len(file_one), length):
        if len(file_one[i:i+length]) == length and ''.join(file_one[i:i+length]).isalpha():
            slices_one.append(''.join(file_one[i:i+length]))

    slices_two = []
    for i in range(0,len(file_two), length):
        if len(file_two[i:i+length]) == length and ''.join(file_one[i:i+length]).isalpha():
            slices_two.append(''.join(file_two[i:i+length]))


    #set intersection returns a set of all identical substrings between the lists
    similarities = get_similarities(slices_one, slices_two)

    print(similarities)

    list_of_substrings = ['\n'.join(similarities), '\n'.join(similarities)]

    #return as a list of 2 strings
    return set_files_as_list_of_strings(list_of_substrings)</pre></div>



<p>On line 5 you can see where I call <strong>read()</strong> then <strong>decode(&#8216;utf-8&#8217;)</strong> to get the files actual text.</p>



<p>When the user posts the data we&#8217;re not able to immediately get to the text inside the submitted files. My goal is for our <strong>data</strong> variable to just hold the file text as a string.</p>



<p>Using <strong>read()</strong> with no argument, I save all the form data to memory until <strong>EOF</strong>. This goes back to the days we were messing with file handlers in C. That returns a <strong>byte </strong>object. In python a byte object represents sequences of integers which are usually ascii characters. We can use the decode method to get back a string. I&#8217;ve passed &#8216;utf-8&#8217; as an argument, <a rel="noreferrer noopener" aria-label="however it actually decodes to this by default too, so decode() would work just as well (opens in a new tab)" href="https://docs.python.org/3/library/stdtypes.html#bytes" target="_blank">however it actually decodes to this by default too, so <strong>decode()</strong> would work just as well</a>.</p>



<p>Once I get the files as strings I can start working on formatting the data. If you look at where it ends up in html you can see i&#8217;ve wrapped the text in <strong>&lt;pre&gt;&lt;/pre&gt;</strong> tags. Let&#8217;s look at <strong><em>templates/base.html</em></strong><em> on line 110:</em></p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;HTML&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    {% block head %}
	&lt;title&gt;Similarities{% block title %}{% endblock %}&lt;/title&gt;
	&lt;style&gt;
	    {% block background %}
	    body{
            background: #606c88;  /* fallback for old browsers */
            background: -webkit-linear-gradient(to right, #3f4c6b, #606c88);  /* Chrome 10-25, Safari 5.1-6 */
            background: linear-gradient(to right, #3f4c6b, #606c88); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
        }
        {% endblock %}
        h1{
            line-height: 43px;
        }
        table, form{
            border-radius: 7px;
            box-shadow: 0px 12px 20px 1px;
            background: white;
            border-collapse: collapse;
            margin-left: auto;
            margin-right: auto;
            margin-top: 47px;
            font-size: 19px;
            line-height: 27px;
            width: 89%;
        }

        form{
            padding: 2px 0px 21px 39px;
        }

        input{
            font-size: 16px;
            margin: -14px;
        }


        table, th, td {
            border: 1px solid #191e2a;
        }

        th, td {
            padding: 15px;
            text-align: left;
        }

        span{
            background-color: yellow;
        }

        li a{
            text-decoration: none;
            padding: 16px;
            color: white;
            font-size: 27px;
        }

        li{
            flex: 3;
            text-align: center;
        }

        ul{
            display: flex;
            list-style-type: none;
            margin-top: 30px;
        }

        menu{
            padding-left: 0px;
        }

        pre{
            white-space: pre-wrap;
        }
        td{
            min-width: 45vw;
        }
	&lt;/style&gt;
    {% endblock %}
&lt;/head&gt;
&lt;body&gt;
    &lt;menu&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href=&quot;/&quot;&gt;Similar Lines&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;/sentences&quot;&gt;Similar Sentences&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;/substrings&quot;&gt;Similar Substrings&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
&lt;/menu&gt;
    {% block content %}
    &lt;form action={{ request.path }} method=&quot;post&quot; enctype = &quot;multipart/form-data&quot;&gt;
      &lt;h1&gt;Upload two files to highlight similarities{% block h1 %}{% endblock %}&lt;/h1&gt;
      &lt;input type=&quot;file&quot; name=&quot;file_one&quot; id=&quot;file_one&quot;&gt;&lt;br&gt;
      &lt;input type=&quot;file&quot; name=&quot;file_two&quot; id=&quot;file_two&quot;&gt;&lt;br&gt;
      {% block numberInput %}{% endblock %}
      &lt;input type=&quot;submit&quot; value=&quot;Submit&quot;&gt;
    &lt;/form&gt;
    &lt;table&gt;
        &lt;tr&gt;
            &lt;th&gt;
                Code Group One
            &lt;/th&gt;
            &lt;th&gt;
                Code Group Two
            &lt;/th&gt;
        &lt;tr&gt;
            &lt;td id=&quot;groupone&quot;&gt;
&lt;pre&gt;
{% block results_one %}{% endblock %}
&lt;/pre&gt;
            &lt;/td&gt;
            &lt;td id=&quot;grouptwo&quot;&gt;
&lt;pre&gt;
{% block results_two %}{% endblock %}
&lt;/pre&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
{% endblock %}
&lt;/body&gt;
&lt;/html&gt;</pre></div>



<p>Using jinja2 templating I can create a block that holds <strong>results_one</strong> and on line 116 I have another &lt;pre&gt; &lt;/pre&gt; with <strong>results_two</strong> inside. Now let&#8217;s look at <strong>index.html</strong> which is the first page of the website, where I compare lines:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-objectivec&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Objective-C&quot;,&quot;modeName&quot;:&quot;objectivec&quot;}">{% extends &quot;base.html&quot; %}

    {% block title %} - Lines{% endblock %}
    {% block background %}
        body{
            background-image: linear-gradient(to right, #ab7272 0%, GRAY 280%);
        }
    {% endblock %}
{% block head %}
    {{ super() }}
{% endblock %}

    {% block h1 %} - matching lines{% endblock %}
    {% block results_one %}{{results[0]|safe}}{% endblock %}
    {% block results_two %}{{results[1]|safe}}{% endblock %}
{% block content %}
    {{ super() }}
{% endblock %}</pre></div>



<p>This is why jinja2 is so powerful.  My base.html is 123 lines of code. My index.html, sentences.html and substrings.html pages are less than 20! If I have to make a change on all the webpages, base.html will be the one place to make it.</p>



<p>Using  <strong>{% extends &#8220;base.html&#8221; %}</strong> allows me to reuse all the code and slip in custom variables by defining their values on each individual page. Look at line 14:</p>



<p><strong>{% block results_two %}{{results[1]|safe}}{% endblock %}</strong></p>



<p>I pass in the results from my compare function in application.py. Let me make a diagram so it&#8217;s easier to understand the flow:</p>



<figure class="wp-block-image size-large"><a href="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-2.jpg"><img loading="lazy" width="978" height="727" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-2.jpg" alt="" class="wp-image-1487" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-2.jpg 978w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-2-300x223.jpg 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-2-768x571.jpg 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></a></figure>



<p>This is generally what is happening. Things are being passed to do some processing work, but always end up back in application.py so the flask framework can do the rest for us.</p>



<p>I&#8217;m still learning as I go, and the tough part of this is all the different languages working together&#8230;the html, css, server calls, url requests and python code. Each is a journey on it&#8217;s own and don&#8217;t be discouraged if this made little sense. CS50 doesn&#8217;t cover html, or css very much so if you&#8217;re up to it check out teamtreehouse for video courses you can take on those topics.</p>



<h2>Finishing the actual challenges</h2>



<p>Back to similaries less, which is a much simpler challenge. We don&#8217;t have to make the flask app from scratch. Just update the helpers.py and index.html files with functions and a form. Here is what I ended up doing:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/602bbdf69d97f155ea0e293f2a3f3fc1">Gist</a>.
</div></figure>



<p>My drop down has a nifty javascript function inside it that will hide or show the numbers field if substring is selected. Also when the user hits the back button it resets the form using the script at the bottom.</p>



<p>So remember, a lot of these features i&#8217;ve added is not because i&#8217;m some all powerful genius. I am just not afraid to ask myself &#8220;what do I want this to do?&#8221; followed by googling it and not being too proud to use code from online. In these cases, if it works, great! The script at the bottom is straight from a stack overflow answer. I also forgot how to inline javascript in html so a quick google and you can see <strong>onchange</strong> on line 14 that goes into my javascript for changing the style of an element (which I also googled because I forgot for the 100th time, which is OK)</p>



<p>There is too much to remember, and too much changing in the world of programming, be a hunter of code examples and understand fundamentals to get things done and not get stuck with half finished projects.</p>



<p></p>



<p>Moving on to week 8!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://johnyzaguirre.com/2019/11/23/cs50-week-7-walkthroughs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CS50 Week 7</title>
		<link>https://johnyzaguirre.com/2019/11/13/cs50-week-7/</link>
					<comments>https://johnyzaguirre.com/2019/11/13/cs50-week-7/#respond</comments>
		
		<dc:creator><![CDATA[Johnny]]></dc:creator>
		<pubDate>Wed, 13 Nov 2019 13:02:34 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[CS50]]></category>
		<guid isPermaLink="false">https://johnyzaguirre.com/?p=1278</guid>

					<description><![CDATA[Web Programming So with a brief overview of html, css and python it is time to put everything together. If you&#8217;ve never programmed something for the web just remember: THE INTERNET IS JUST A BUNCH OF COMPUTERS ALL TALKING TO EACH OTHER There is no special &#8220;cloud&#8221; machine or &#8220;server.&#8221; These are all just words &#8230; <p class="link-more"><a href="https://johnyzaguirre.com/2019/11/13/cs50-week-7/" class="more-link">Continue reading<span class="screen-reader-text"> "CS50 Week 7"</span></a></p>]]></description>
										<content:encoded><![CDATA[
<h2>Web Programming</h2>



<p>So with a brief overview of html, css and python it is time to put everything together.</p>



<p>If you&#8217;ve never programmed something for the web just remember:</p>



<p><strong>THE INTERNET IS JUST A BUNCH OF COMPUTERS ALL TALKING TO EACH OTHER</strong></p>



<p>There is no special &#8220;cloud&#8221; machine or &#8220;server.&#8221; These are all just words that describe <strong>COMPUTERS</strong>. It&#8217;s not much different from sending a hand written letter from one house to another house. The mailman is just your internet cable and some electricity.</p>



<p>We have to command our computer to send information (think hand written letter) using a request called <strong>GET</strong>. So if you go inside your browser like safari, edge, chrome, firefox, whatever, that bar at the top for web addresses is where you send <strong>GET</strong> requests. You are saying &#8220;go GET me the information from google.com.&#8221; When you google cats the bar changes to some funky address that is saying &#8220;GET me cats.&#8221; (https://www.google.com/search?q=cats&amp;oq=cats&amp;aqs=chrome.0.69i59j0l4j69i61.3015j0j8&amp;sourceid=chrome&amp;ie=UTF-8)</p>



<p>On our computer we might have a word document locally. If we open it we get the information on the screen so we can read it. It is easy in our case to write more stuff onto the document and save it. How do we do this on the web?</p>



<p>There are a few different commands besides <strong>GET</strong> but the next one you should know is called <strong>POST</strong>. If I have data somewhere on the internet, meaning not on my computer but on the web, I can add data to it by using a <strong>POST</strong> type request. It is still a web address but it has some data tied to it that will be saved on the other end. You can also get a response from a <strong>POST </strong>request. Usually it will be a message that your data was either saved, or something went wrong.</p>



<p>Web requests have headers. I&#8217;m on Firefox so if I make a GET request, I can inspect by right clicking and choosing <strong>inspect</strong>. This is similar on a lot of browsers. Here is how I found the headers:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="547" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-04-at-7.44.06-AM-1024x547.png" alt="" class="wp-image-1279" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-04-at-7.44.06-AM-1024x547.png 1024w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-04-at-7.44.06-AM-300x160.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-04-at-7.44.06-AM-768x411.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /><figcaption><center>This took a while to find</center></figcaption></figure></div>



<p>So we can see in my case we&#8217;re using HTTP/2.0 the response code was 200 which means all is good and our content type is text/html; charset=UTF-8.</p>



<p>UTF stands for <strong>Unicode Transformation Format</strong> and after spending the past hour looking this up I think I get how it works. I&#8217;m probably not 100% but this is the gist. Please leave a comment if you have any additional info on the topic that would help others. Here is an image I put together to help visualize what is happening:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="768" height="1024" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/melinda-gimpel-0lrWg2ALPVw-unsplash-768x1024.jpg" alt="" class="wp-image-1281" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/melinda-gimpel-0lrWg2ALPVw-unsplash-768x1024.jpg 768w, https://johnyzaguirre.com/wp-content/uploads/2019/11/melinda-gimpel-0lrWg2ALPVw-unsplash-225x300.jpg 225w, https://johnyzaguirre.com/wp-content/uploads/2019/11/melinda-gimpel-0lrWg2ALPVw-unsplash.jpg 900w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /><figcaption>Photo by&nbsp;<a href="https://unsplash.com/@melindagimpel?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Melinda Gimpel</a>&nbsp;on&nbsp;<a href="https://unsplash.com/s/photos/keyboard?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div>



<p><strong>utf-8</strong> is the encoding lookup table that turns a character code into binary for a computer to read or pass back out to Unicode. <strong>Unicode</strong> (a character set) takes the character code and maps it to a lookup table that has the actual character we display on the page using a typeface or font.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="348" height="72" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-7.41.52-AM.png" alt="" class="wp-image-1291" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-7.41.52-AM.png 348w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-7.41.52-AM-300x62.png 300w" sizes="(max-width: 348px) 100vw, 348px" /></figure></div>



<p>I hope that made sense. If it doesn&#8217;t please let me know in the comments.</p>



<h2>HTML</h2>



<p>HTML holds 2 types of info. Info we see and info we don&#8217;t see. Here is a sample from the CS50 lecture notes:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html>

&lt;html>
    &lt;head>
        &lt;title>hello, title&lt;/title>
    &lt;/head>
    &lt;body>
        hello, body
    &lt;/body>
&lt;/html></code></pre>



<p>The browser program is going to interpret this starting at the top. The first line lets the browser know we are dealing with HTML5, the current standard. Next we have <strong>&lt;html&gt;</strong> which starts and ends all the info we&#8217;re going to have on our page.</p>



<p><strong>&lt;head&gt;</strong> is where the browser gets info regarding the title of our page, scripts we want to run, and <strong>CSS</strong>.</p>



<p><strong>&lt;body&gt;</strong> is where we hold the material that can be viewed on the screen by our user. Inside the body we can have website titles, images, text, links and anything else you&#8217;ve ever seen on a webpage.</p>



<p>Notice how everything has a closing tag and has a nested structure.</p>



<h2>CSS</h2>



<p>CSS to style our page.  We can change the character font, color, add borders, background images and even animations. When you hover your mouse over a button, and the button on the page looks slightly different when you hover over it, that is CSS. Here is some example code:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/cc919a82e1297ca915b41069a3eb2449">Gist</a>.
</div></figure>



<p>You can put css in the &lt;head&gt; section of your html file, or reference a separate .css file.  The example file above can be opened using your browser without any other files. Try hovering over the button and last list item.</p>



<p>In CSS the first letter stands for cascading. It&#8217;s important you know that in css the rule closest to the bottom will always been the final say.</p>



<p>Notice on line 21 of my example I set the font to 1000000000px! Then on the following lines I change the font. So if a css rule is targeting the <strong>exact </strong>same element in the html, the last rule will win. Remember I wrote <strong>exact</strong>. If one rule is <strong>li</strong> and the next rule is <strong>li:first-child</strong> THEY ARE NOT EXACTLY THE SAME. So the cascading rule of last is not true. </p>



<p><a href="https://www.w3schools.com/css/" target="_blank" rel="noreferrer noopener" aria-label="To learn more I recommend W3Schools CSS tutorials, they are excellent. (opens in a new tab)">To learn more I recommend W3Schools CSS tutorials, they are excellent.</a></p>



<h2>Dynamic content with python</h2>



<p>This look complicated but lets try to break this down. I was stumped at first but after posting some questions on reddit I figured it out:</p>



<pre class="wp-block-code"><code># Implements a web server

from http.server import BaseHTTPRequestHandler, HTTPServer


# HTTPRequestHandler class
class HTTPServer_RequestHandler(BaseHTTPRequestHandler):

    # GET
    def do_GET(self):

        # send response status code
        self.send_response(200)

        # send headers
        self.send_header("Content-type", "text/html")
        self.end_headers()

        # write message
        self.wfile.write(bytes("hello, world", "utf8"))


# configure server
port = 8080
server_address = ("0.0.0.0", port)
httpd = HTTPServer(server_address, HTTPServer_RequestHandler)

# run server
httpd.serve_forever()</code></pre>



<p>Ok after going through the notes I understand what is happening. Seeing a class with a do_GET method and not finding it being called in the program was really confusing at first. </p>



<p><strong>do_GET</strong> gets called when the user goes to the browser and loads that webpage (makes a <strong>GET </strong>request).</p>



<p>wfile was confusing at first too, but it&#8217;s a file handler used by the HTTPServer class. It requires a <strong>bytes</strong> object so python has a helpful function that takes in a string and an <strong>encoding</strong> (utf-8). So we have above the example of &#8216;hello world&#8217; but we can also create our own file handler, insert it into the bytes function with the <strong>read()</strong> method and serve up our text file to the webpage.</p>



<p>Here is that version:</p>



<pre class="wp-block-code"><code># Implements a web server

from http.server import BaseHTTPRequestHandler, HTTPServer


# HTTPRequestHandler class
class HTTPServer_RequestHandler(BaseHTTPRequestHandler):

    # GET
    def do_GET(self):

        # send response status code
        self.send_response(200)

        # send headers
        self.send_header("Content-type", "text/html")
        self.end_headers()

        # write message
        # file handler gives us a stream. bytes turns it into a bytes object
        # we can pass the file handler, a string of text
        # just remember to pass the encoding type utf8!
        f = open("test.txt")
        self.wfile.write(bytes(f.read(), 'utf8'))
        f.close()


# configure server
port = 8080
server_address = ("0.0.0.0", port)
httpd = HTTPServer(server_address, HTTPServer_RequestHandler)

# run server
httpd.serve_forever()</code></pre>



<p>I created a file called test.txt in the same directory for this test. Next I&#8217;ll try an html file:</p>



<pre class="wp-block-code"><code># Implements a web server

from http.server import BaseHTTPRequestHandler, HTTPServer


# HTTPRequestHandler class
class HTTPServer_RequestHandler(BaseHTTPRequestHandler):

    # GET
    def do_GET(self):

        # send response status code
        self.send_response(200)

        # send headers
        self.send_header("Content-type", "text/html")
        self.end_headers()

        # write message
        # file handler gives us a stream. bytes turns it into a bytes object
        # we can pass the file handler, a string of text
        # just remember to pass the encoding type utf8!
        f = open("test.html")
        self.wfile.write(bytes(f.read(), 'utf8'))
        f.close()


# configure server
port = 8080
server_address = ("0.0.0.0", port)
httpd = HTTPServer(server_address, HTTPServer_RequestHandler)

# run server
httpd.serve_forever()</code></pre>



<p>Here is my html file:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;HTML&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;Wow CATS&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1&gt;CATS ARE AWESOME!!!&lt;/h1&gt;
	&lt;p&gt;Hello world this is my cats page please subscribe for lots of cats&lt;/p&gt;
	&lt;br&gt;
	&lt;img src=&quot;https://inteng-storage.s3.amazonaws.com/img/iea/4N610VqxGJ/sizes/cat-cloning_resize_md.jpg&quot;&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div>



<p>The result:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="571" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-05-at-9.06.28-AM-1024x571.png" alt="" class="wp-image-1287" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-05-at-9.06.28-AM-1024x571.png 1024w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-05-at-9.06.28-AM-300x167.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-05-at-9.06.28-AM-768x428.png 768w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-05-at-9.06.28-AM.png 1173w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>So far we&#8217;ve created a static page but now we have to go even deeper and build <strong>dynamic pages</strong>. This is a pretty dense topic and we&#8217;ll soon see the differences. <a href="https://www.keycdn.com/support/difference-between-static-and-dynamic">Here is a quick read that explains the differences well</a>.</p>



<h2>Flask &#8211; a python web framework</h2>



<p>Make sure to type <strong>pip install flask</strong> in the terminal before getting started.</p>



<p>Let&#8217;s start with a simple example, straight from the Flask website, <a href="https://flask.palletsprojects.com/en/1.1.x/quickstart/">which you can find here</a>.</p>



<p>I&#8217;ve made a folder called flask_example, and inside a file called mysite.py. Inside that file are a few lines of code:</p>



<pre class="wp-block-code"><code>from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
	return 'Hello, CS50!'
</code></pre>



<p>If I tried to run this in the terminal by typing <strong>flask run</strong>, I will most likely get this message:</p>



<pre class="wp-block-code"><code> * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
Usage: flask run [OPTIONS]

Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py" module was not found in the current directory.</code></pre>



<p>It wants us to create an environment variable, which is a variable our operating system holds (not our program). Flask reaches to the OS for this variable to reference our file.</p>



<p>We can create environment variables by using the <strong>export</strong> command in the terminal.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="360" height="140" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.13.49-AM.png" alt="" class="wp-image-1296" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.13.49-AM.png 360w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.13.49-AM-300x117.png 300w" sizes="(max-width: 360px) 100vw, 360px" /></figure></div>



<p>So lets create the <strong>FLASK_APP</strong> environment variable that is the name of our program. In this example the file i&#8217;m working in is called <strong>mysite.py</strong></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="431" height="134" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.15.52-AM.png" alt="" class="wp-image-1297" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.15.52-AM.png 431w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.15.52-AM-300x93.png 300w" sizes="(max-width: 431px) 100vw, 431px" /></figure></div>



<p>Now when I run the command <strong>flask run</strong> I get this:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="799" height="124" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.16.33-AM.png" alt="" class="wp-image-1298" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.16.33-AM.png 799w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.16.33-AM-300x47.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.16.33-AM-768x119.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>If I hover of the website address and click open I get this:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="503" height="333" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.17.42-AM.png" alt="" class="wp-image-1300" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.17.42-AM.png 503w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.17.42-AM-300x199.png 300w" sizes="(max-width: 503px) 100vw, 503px" /></figure></div>



<p>Now that we&#8217;ve created this simple example lets follow the lecture notes.</p>



<h2>Flask continued (lecture notes)</h2>



<p>I&#8217;m going to rename mysite.py to <strong>application.py</strong> so it matches up with the notes. Then i&#8217;m going to create a folder called <strong>templates</strong>. The notes are a little confusing here but to clear it up here is the directory structure:</p>



<ul><li>flask_example<ul><li>application.py</li><li>templates</li></ul></li></ul>



<p>So flask_example is the main folder, which has application.py and the templates folder inside of it.</p>



<p><strong>first we have to make sure to reset our environment variable!!!!</strong></p>



<p>In the terminal type <strong>export FLASK_APP=application.py</strong></p>



<p>Next, inside the templates folder i&#8217;ll create a new file called index.html that has this html:</p>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html>

&lt;html>
    &lt;head>
        &lt;title>hello, title&lt;/title>
    &lt;/head>
    &lt;body>
        hello, body
    &lt;/body>
&lt;/html></code></pre>



<p>I&#8217;m going to replace the code in application.py with this:</p>



<pre class="wp-block-code"><code>from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/zuck")
def zuck():
    return render_template("zuck.html")

@app.route("/login")
def login():
    return render_template("login.html")</code></pre>



<p>Next i&#8217;ll run the <strong>flask run </strong>command in the terminal:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="808" height="156" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.06-AM.png" alt="" class="wp-image-1304" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.06-AM.png 808w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.06-AM-300x58.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.06-AM-768x148.png 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="349" height="216" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.29-AM.png" alt="" class="wp-image-1305" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.29-AM.png 349w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-9.30.29-AM-300x186.png 300w" sizes="(max-width: 349px) 100vw, 349px" /></figure></div>



<p>Now inside of templates create a zuck.html file with this html:</p>



<pre class="wp-block-code"><code></code></pre>



<pre class="wp-block-code"><code>&lt;!DOCTYPE html>

&lt;html>
    &lt;head>
        &lt;title>hello, title&lt;/title>
    &lt;/head>
    &lt;body>
        hello, this is the zuck page!
    &lt;/body>
&lt;/html></code></pre>



<p>Enter <strong>flask run</strong> in the terminal again and open the website URL. Then add &#8220;/zuck&#8221; to the end of the url and you will get this result:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="379" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-6.18.03-PM-1024x379.png" alt="" class="wp-image-1308" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-6.18.03-PM-1024x379.png 1024w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-6.18.03-PM-300x111.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-6.18.03-PM-768x284.png 768w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-06-at-6.18.03-PM.png 1248w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<h2>Error handling and tracebacks with flask</h2>



<p>You can skip this and just run these commands:</p>



<pre class="wp-block-code"><code>touch ~/.bash_profile &amp;&amp; echo export FLASK_DEBUG=1 > .bash_profile</code></pre>



<p>Then restart the terminal for it to work. <a href="#frosh">Click here for the next section of text.</a></p>



<p>This was a huge pain to get working with CS50 IDE. I spent about an hour on this because I really wanted that nice traceback feature right in the browser. Turns out there is another environment variable that needs to be set similar to <strong>FLASK_APP.</strong> <a href="https://flask.palletsprojects.com/en/1.1.x/quickstart" target="_blank" rel="noreferrer noopener" aria-label="I found this in the flask documentation (opens in a new tab)">I found this in the flask documentation</a>:</p>



<p>To enable all development features (including debug mode) you can export the&nbsp;<code>FLASK_ENV</code>&nbsp;environment variable and set it to&nbsp;<code>development</code>&nbsp;before running the server:</p>



<pre class="wp-block-preformatted">$ export FLASK_ENV=development
$ flask run
</pre>



<p>(On Windows you need to use&nbsp;<code>set</code>&nbsp;instead of&nbsp;<code>export</code>.)</p>



<p>This does the following things:</p>



<ol><li>it activates the debugger</li><li>it activates the automatic reloader</li><li>it enables the debug mode on the Flask application.</li></ol>



<p>You can also control debug mode separately from the environment by exporting&nbsp;<code>FLASK_DEBUG=1</code>.</p>



<p>It turns out <strong>FLASK_ENV</strong> wasn&#8217;t the answer, I just needed that last little part <strong>FLASK_DEBUG=1</strong>. Or to be exact <strong>export FLASK_DEBUG=1</strong></p>



<p>To make it more frustrating I had to do this every time I opened a new terminal. To fix this I wrote this in the terminal:</p>



<pre class="wp-block-code"><code>touch ~/.bash_profile &amp;&amp; echo export FLASK_DEBUG=1 > .bash_profile</code></pre>



<p>I&#8217;ve run into .bash_profile in the past and I recommend doing a quick google how it works when you get a chance.</p>



<p>Now open a fresh new terminal, close the old one, and try to go to the login.html (make sure in the templates folder you delete login.html so it is not there since we&#8217;re trying to mock an error situation). You should get that awesome jinja2 traceback!</p>



<p><a id="frosh"></a></p>



<h2>Frosh IMs &#8211; what it means</h2>



<p>I have no idea what Frosh is let me look that up&#8230;</p>



<p>Ok google tells me it is a slang word for a first year student (like a freshman). </p>



<p>Ok&#8230; fine.</p>



<p>IM&#8217;s stands for intramurals which are sports organized within an institution. Fun fact, the word is derived from the Latin <em>intra muros</em> which means &#8220;within walls.&#8221; Now that i&#8217;ve unpacked the heading of this section let&#8217;s get down to the programming part:</p>



<p>File structure is similar to the previous example:</p>



<ul><li>froshims0/<ul><li>application.py</li><li>templates/<ul><li>failure.html</li><li>index.html</li><li>layout.html</li><li>success.html</li></ul></li></ul></li></ul>



<p>If we go through each file <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="http://cdn.cs50.net/2017/fall/lectures/9/src9/froshims0/" target="_blank">in the link provided here</a>, we can go into each file, copy the code and run it to get the form:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.53.20-AM.png" alt="" class="wp-image-1325" width="272" height="177" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.53.20-AM.png 437w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.53.20-AM-300x195.png 300w" sizes="(max-width: 272px) 100vw, 272px" /></figure></div>



<p>Next I would like you to open the inspector in your browser by right clicking and choosing inspect. This is a little different for each browser. I&#8217;m using chrome in this case:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="1024" height="447" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.55.35-AM-1024x447.png" alt="" class="wp-image-1326" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.55.35-AM-1024x447.png 1024w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.55.35-AM-300x131.png 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.55.35-AM-768x335.png 768w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-08-at-7.55.35-AM.png 1170w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>Next I want you to click on the &#8220;Network&#8221; tab:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="1666" height="1335" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/2019-11-08-08.17.55.gif" alt="" class="wp-image-1335"/></figure>



<p>A <strong>post request</strong> means the form values are sent in the HTTP body data. What does that mean? Even if we can&#8217;t see the body data doesn&#8217;t mean the other end doesn&#8217;t receive and read it. Lets think of it this way:</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><img loading="lazy" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/sue-hughes-toQNPpuDuwI-unsplash-1-3000x2000.jpg" alt="" class="wp-image-1341" width="737" height="493"/><figcaption>Photo by&nbsp;<a href="https://unsplash.com/@suehughes?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">sue hughes</a>&nbsp;on&nbsp;<a href="https://unsplash.com/s/photos/writing-envelope?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure></div>



<p>When I open my browser it&#8217;s like walking into a post office, where I get my mail. When I go to the counter, the clerk asks for information necessary to retrieve my mail. On my computer, when I type <strong>google.com</strong> it&#8217;s like asking the post office worker &#8220;please get me google.com.&#8221; Once that post office worker brings me an envelope let&#8217;s imagine it like this for google.com:</p>



<p></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="960" height="720" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing.jpg" alt="" class="wp-image-1346" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing.jpg 960w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-300x225.jpg 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-768x576.jpg 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>Now if I take this same idea and fill out a form on a webpage. I can use a GET request or a POST request. Using GET I pass in the form values right into the URL address. When filling out the frosh form using the method <strong>GET</strong>, and hitting submit the url will change to this:</p>



<pre class="wp-block-code"><code>https://792cdab9-edb1-4a25-a6df-87b8146cafcf-ide.cs50.xyz:8080/register?name=john+smith&amp;dorm=Canaday</code></pre>



<p>Notice the last part: <strong>?name=john+smith&amp;dorm=Apley+Court</strong></p>



<p>So if we look back at the envelope image it might look like this:</p>



<p></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="960" height="720" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1.jpg" alt="" class="wp-image-1350" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1.jpg 960w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-300x225.jpg 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-768x576.jpg 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<p>This is usually ok for quick and dirty apps that don&#8217;t need to be secure with data. A form about if you like cats or not might be ok for the <strong>GET </strong>method.</p>



<p>Otherwise we have to use <strong>POST</strong>. So if i change my code back so I use the <strong>POST</strong> method, which is how it was written by default, my url looks like this after submitting:</p>



<pre class="wp-block-code"><code>https://792cdab9-edb1-4a25-a6df-87b8146cafcf-ide.cs50.xyz:8080/register</code></pre>



<p>So where did my form values end up?</p>



<p><strong>THE SAME PLACE WHERE YOUR BROWSER STORES PAGE DATA.</strong> Like <strong>LITERALLY THE SAME PLACE.</strong> I had no idea for the longest time, because you can&#8217;t see what the computer (server) sees on the other side. It uses that space because you can store tons more data. Think about how many images, videos, text <strong>you view</strong> <strong>on the webpage body</strong>. That allows forms to take advantage of all that space to then store things to the computer on the other end of the form submission.</p>



<p>So here is what a post request looks like:</p>



<p></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="960" height="720" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-1.jpg" alt="" class="wp-image-1351" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-1.jpg 960w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-1-300x225.jpg 300w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Untitled-drawing-1-1-768x576.jpg 768w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" /></figure></div>



<h2>Flask routes and more</h2>



<p>Let&#8217;s look at the application.py file in our lecture notes:</p>



<pre class="wp-block-code"><code>from flask import Flask, render_template, request

app = Flask(__name__)

@app.route("/")
def index():
	return render_template("index.html")

@app.route("/register", methods=["POST"])
def register():
	if not request.form.get("name") or not request.form.get("dorm"):
		return render_template("failure.html")
	return render_template("success.html")</code></pre>



<p>When we use <strong>from flask</strong> we&#8217;re saying <em>from the flask file, give me access to the Flask class. Python classes by convention </em>start with a capital letter. We are also importing the <strong>render_template</strong> function, and the <strong>request </strong>object, which has methods we can use to <strong>GET </strong>and <strong>POST</strong> things.</p>



<p>Next we have this funky <strong>@app.route(&#8220;/&#8221;)</strong>, followed by a function def. </p>



<pre class="wp-block-code"><code>@app.route("/")
def index():
	return render_template("index.html")</code></pre>



<p>This is called a <strong>decorator</strong>. Let&#8217;s break down what that means.</p>



<h3>A quick peak at decorators, factories and wrapping functions.</h3>



<p>Let&#8217;s jump right into this <em>magic</em>™</p>



<pre class="wp-block-code"><code>def returnPositiveNumber(number):
	if number > 0:
		return number
	else:
		return 1</code></pre>



<p>Here we have a simple function. It will always return a positive number. If it&#8217;s zero or a negative number it will return 1. Easy. <strong>Our function takes in one arguement <em>num</em> as it&#8217;s only argument.</strong></p>



<p>Python treats functions as first-class-objects, which means you can put them just about anywhere, <strong>including as arguments to other functions</strong>.</p>



<p>Check this next piece out:</p>



<pre class="wp-block-code"><code>def plusNineThousandDecorator(function):
	def wrapper(number):
		return function(number) + 9000
	return wrapper</code></pre>



<p>PlusNineThousand <strong>takes a function as its argument</strong>. So we&#8217;re going to pass our <strong>returnPositiveNumber</strong> function into it. How does this look if we try to print something out?</p>



<p><strong>SUPER IMPORTANT!</strong> When we use a function as an argument we are <strong>NOT</strong> calling the function, we reference it as an object which is super strange at first sight. <strong>NO () are used!</strong> </p>



<pre class="wp-block-code"><code>test = plusNineThousand(returnPositiveNumber)</code></pre>



<p>Look back to our plusNineThousand definition and check out the last line. <strong>It returns decorator</strong>. So what is decorator? It&#8217;s a function. <strong>So test is a function</strong>. What does it do? How does it work? <strong>Take a look at it&#8217;s definition:</strong></p>



<pre class="wp-block-code"><code>return function(number) + 9000</code></pre>



<p>It takes <strong>the same argument as our original function</strong>. So we need to run it as <strong>test(num)</strong>. But now <strong><em>it adds 9000 to the returned result.</em></strong></p>



<p>Let&#8217;s try it out:</p>



<pre class="wp-block-code"><code>print(test(42))
#result is 9042

print(test(-1))
#result is 9001</code></pre>



<p><strong>test</strong> is now a function that takes our original function which returned <strong>num</strong> and added a piece of new functionality, which is adding 9000 to it and returning it back.</p>



<p>When using decorators it is common to modify the original function like this:</p>



<pre class="wp-block-code"><code>returnPositiveNumber = plusNineThousandDecorator(returnPositiveNumber)</code></pre>



<p>Now our original function <strong>is what it used to be plus it adds 9000 to everything</strong>.</p>



<pre class="wp-block-code"><code>print(returnPositiveNumber(42))
#result is 9042</code></pre>



<p>We can use some syntax sugar to make our ugly: </p>



<pre class="wp-block-code"><code>returnPositiveNumber = plusNineThousandDecorator(returnPositiveNumber)</code></pre>



<p>Into this:</p>



<pre class="wp-block-code"><code>@plusNineThousandDecorator
def returnPositiveNumber(number):
	if number > 0:
		return number
	else:
		return 1</code></pre>



<p>Make sure the decorator function is before the function you modify. Also the decorator @ has to be placed on the line before the function like shown above.</p>



<p>Here is the entire program:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler"><div class="wp-block-embed__wrapper">
View the code on <a href="https://gist.github.com/sojohnnysaid/6a70fe00b03c6ff34a0c0db328262341">Gist</a>.
</div></figure>



<p>Going deeper, we can assign arguments to our @plusNineThousandDecorator. We can only modify before and after our modified function so let&#8217;s try to add some html tags to the front and back of our number.</p>



<p>So we can not pass arbitrary arguments to our decorator. <strong>The decorator returns our original function wrapped in some other stuff</strong>.</p>



<p><strong>Now we need a &#8220;factory&#8221; that returns a decorator while passing some arguments in the process</strong>.</p>



<p>So let&#8217;s <strong>&#8220;wrap&#8221;</strong> our decorator function in a decorator factory:</p>



<pre class="wp-block-code"><code>def decoratorFactory(htmlTag):
	def plusNineThousandDecorator(function):
		def wrapper(number):
			return f"&lt;{htmlTag}>{function(number) + 9000}&lt;/{htmlTag}>"
		return wrapper
	return plusNineThousandDecorator


@decoratorFactory("h1")
def returnPositiveNumber(number):
	if number > 0:
		return number
	else:
		return 1


print(returnPositiveNumber(42))


# results
# &lt;h1>9042&lt;/h1></code></pre>



<p>Now we can modify our factory argument, get back a decorator, which then wraps our function, and finally modifies it&#8217;s behavior.</p>



<p>This keeps our program<em> dry</em>, or without repetitive code that is difficult to keep track of. If one thing changes in our program we only want to go fix it in <strong>one and only one</strong> place. <a href="https://blog.codinghorror.com/curlys-law-do-one-thing/">Here is a great article on this topic</a>. Decorators help us achieve this goal when creating software.</p>



<h2>Back to our flask app</h2>



<p>So now that we know a little bit about decorators let&#8217;s look again at a basic flask application:</p>



<pre class="wp-block-preformatted">app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"</pre>



<p><a href="https://ains.co/blog/things-which-arent-magic-flask-part-1.html">The example above is from ains.co, and I highly recommend coding through both part 1 and 2 articles here.</a></p>



<p>What is happening behind the scenes is this (basically):</p>



<pre class="wp-block-code"><code>#credit goes to ains.co 
#please read the article on his site it's fantastic
#https://ains.co/blog/things-which-arent-magic-flask-part-1.html

class Flask():
    def __init__(self):
        self.routes = {}

    def route(self, route_str):
        def decorator(f):
            self.routes[route_str] = f
            return f

        return decorator

    def serve(self, path):
        view_function = self.routes.get(path)
        if view_function:
            return view_function()
        else:
            raise ValueError('Route "{}"" has not been registered'.format(path))


app = Flask()

@app.route("/")
def hello():
    return "Hello World!"</code></pre>



<p>We haven&#8217;t used decorators in classes, but it&#8217;s basically the same except here we call a method inside of the Flask class.</p>



<p>The cool part is the <strong>self.routes{}</strong>. </p>



<p>Flask is storing each path (<strong>&#8220;/&#8221;)</strong> as a <strong>key</strong>, while the value is the decorator function itself.</p>



<p>It doesn&#8217;t go that final level deep to <strong>wrapper</strong>. In our example we used our modified function right away, but flask is saving this function to be used later in the <strong>serve</strong> method.</p>



<p>Once we make a request in our browser to the main domain (&#8220;/&#8221;), flask is going to check if that is in it&#8217;s <strong>self.routes</strong> dictionary. If it is it will return the function that is stored, which is <strong>hello()</strong>.</p>



<p>If this is confusing <strong>do not worry</strong>. It is ok to just understand the results of the code and get a <em>feel </em>for how flask operates. This is just a look under the hood of the flask <em>engine</em>. <a href="https://ains.co/blog/things-which-arent-magic-flask-part-1.html">Again here is the link if you want to learn (most of) the inner workings.</a></p>



<h2>Getting form values from flask</h2>



<p>Since our <em>form action</em> in the <strong>index.html</strong> &lt;form&gt; is <strong>&lt;form action=&#8221;/register&#8221;&#8230;</strong> we have to let flask know about this url, otherwise known to flask as a <em>route</em>, and what we should do when the user submits our form to it. So we are sending our form message to that url using the POST method as shown below:</p>



<pre class="wp-block-code"><code>@app.route("/register", methods=["POST"])
def register():
    if not request.form.get("name") or not request.form.get("dorm"):
        return render_template("failure.html")
    return render_template("success.html")</code></pre>



<p>Our function has some logic that guards against the user not submitting the correct values, and finally if the guard is passed we just return the success.html page found in our <strong>templates folder</strong>.</p>



<p>Some cool is the request object we have access to. This allows us to work with the form values that are specified in the index.html &lt;form&gt; element. These are </p>



<p><strong>&lt;input type=&#8221;text&#8221; name=&#8221;name&#8221;</strong>&#8230;</p>



<p>and</p>



<p><strong>&lt;select name=&#8221;dorm&#8221;&gt;</strong></p>



<p>using the <strong>name</strong> attribute we can use <strong>request.form.get(</strong><em>nameAttribute)</em> which gives us the value we specify.</p>



<p>Now let&#8217;s take a look at the failure.html file to pull apart what is happening.</p>



<h2>Flask templating</h2>



<p>Take a look at the templates/failure.html file in the froshim0 flask application:</p>



<pre class="wp-block-code"><code>{% extends "layout.html" %}
{% block body %} 
You must provide your name and dorm!
{% endblock %}</code></pre>



<p>The curly brace percent symbol syntax is <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://jinja.palletsprojects.com/en/2.10.x/" target="_blank">a templating language called jinja2</a>. This means we can write regular html, and when we need an expression like a variable we use the following syntax: <strong>{{ myVariable }}</strong>. When adding logic (for loops, conditionals etc), we wrap them in the curly brace percent symbol like this: <strong>{% <em>logic here %}</em></strong>.</p>



<p>Here is what the failure.html page looks like:</p>



<pre class="wp-block-code"><code>{% extends "layout.html" %}
{% block body %} 
You must provide your name and dorm!
{% endblock %}</code></pre>



<p>If we look into layout.html we only see this:</p>



<pre class="wp-block-code"><code>{% block body %}{% endblock %}</code></pre>



<p>Because there is nothing between block body and endblock, layout.html is not actually adding anything to our failure.html file.</p>



<p>If we erase the jinja2 lines and leave only the plain text:</p>



<pre class="wp-block-code"><code>You must provide your name and dorm!</code></pre>



<p>our webpage result is the same. Run the flask app in the terminal by typing <strong>flask run</strong>. Go to the webpage that has the form and leave it blank. Then click submit. We should get this.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" width="300" height="153" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.00.19-AM.png" alt="" class="wp-image-1377"/></figure></div>



<p>Now let&#8217;s put the jinja2 lines back into failure.html.</p>



<p>Next go back to layout.html and add something like this:</p>



<pre class="wp-block-code"><code>{% block body %}
HELLO LAYOUT!
{% endblock %}</code></pre>



<p>Now when we test the webpage again we get this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="300" height="153" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.00.19-AM-1.png" alt="" class="wp-image-1378"/></figure>



<p>So we don&#8217;t see HELLO LAYOUT!</p>



<p>This is because <strong>{% block body %}{% endblock%}</strong> is a placeholder for <strong>any file that extends layout.html</strong>. So if failure starts with the <strong>{% extends</strong> &#8230; <strong>%}</strong> expression that means anything within the <strong>{% block body %}{% endblock%}</strong> <strong>in the failure.html file will appear in the {% block body %}{% endblock%}</strong> <strong>inside the layout.html file</strong>.</p>



<p>Now let&#8217;s try adding some html to the outside of the expression in the layout.html file. Try this, save and re-run the flask app by canceling it in the terminal with ctrl-c, then re-running flask run.</p>



<p>Here is layout.html now:</p>



<pre class="wp-block-code"><code>HELLO START OF LAYOUT&lt;br>
---------------------&lt;br>
&lt;br>
&lt;br>
{% block body %} THIS WILL NOT RENDER {% endblock %}&lt;br>
&lt;br>
&lt;br>
-------------------&lt;br>
HELLO END OF LAYOUT</code></pre>



<p>Now things are getting interesting. Every page in our app now has this text we&#8217;ve added:</p>



<figure class="wp-block-gallery columns-3 is-cropped"><ul class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img loading="lazy" width="336" height="350" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.12.35-AM-1.png" alt="" data-id="1382" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.12.35-AM-1.png" data-link="https://johnyzaguirre.com/?attachment_id=1382" class="wp-image-1382" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.12.35-AM-1.png 336w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.12.35-AM-1-288x300.png 288w" sizes="(max-width: 336px) 100vw, 336px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" width="303" height="237" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.31-AM.png" alt="" data-id="1381" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.31-AM.png" data-link="https://johnyzaguirre.com/?attachment_id=1381" class="wp-image-1381" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.31-AM.png 303w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.31-AM-300x235.png 300w" sizes="(max-width: 303px) 100vw, 303px" /></figure></li><li class="blocks-gallery-item"><figure><img loading="lazy" width="309" height="248" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.40-AM.png" alt="" data-id="1380" data-full-url="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.40-AM.png" data-link="https://johnyzaguirre.com/?attachment_id=1380" class="wp-image-1380" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.40-AM.png 309w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-11-at-9.13.40-AM-300x241.png 300w" sizes="(max-width: 309px) 100vw, 309px" /></figure></li></ul></figure>



<p>Now we can put pieces of our webpage that repeat on many pages in one place, and extend them using the <strong>{% extends &#8230;%}</strong> method in jinja2.</p>



<h2>Storing form data with flask</h2>



<p>Flask allows us to access form fields when submitted by a user. Looking at application.py on line 1, we import <strong>request</strong>. Here is an updated version of our code:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from flask import Flask, render_template, request, redirect

app = Flask(__name__)

# Registrants
students = []

@app.route(&quot;/&quot;)
def index():
	return render_template(&quot;index.html&quot;)


@app.route(&quot;/registrants&quot;)
def registrants():
	return render_template(&quot;registrants.html&quot;, students=students)



@app.route(&quot;/register&quot;, methods=[&quot;POST&quot;])
def register():
	name = request.form.get(&quot;name&quot;)
	dorm = request.form.get(&quot;dorm&quot;)
	
	if not name or not dorm:
		return render_template(&quot;failure.html&quot;)
	
	students.append(f&quot;{name} from {dorm}&quot;)
	return redirect(&quot;/registrants&quot;)</pre></div>



<p>Flask is instantiating the request object when the user goes to a webpage. So If I go to &#8220;/&#8221; or &#8220;/registrants&#8221; a new request object is made. This is because of <strong>threads </strong>and<strong> context</strong>.  Threading means the program is doing several things at once, a good example is one user going to our &#8220;/&#8221; webpage and another user at a different computer going to &#8220;/register.&#8221; Each thread has <strong>different stuff going on. The context of the request is not the same</strong>. So flask hands us back a unique object with values that are relevant to the user&#8217;s request.</p>



<p>on line 6 we create a list of<strong> </strong>&#8220;students.&#8221; because this lives outside of all our routes and functions it will be saved for as long as we run our flask app. It&#8217;s stored in memory.</p>



<p>on lines 21 and 22  we create variables &#8220;name&#8221; and &#8220;dorm&#8221; which store the user input from our form. Our request object has a form object inside of it with a get method. This is kind of confusing because it&#8217;s not like <strong>get and post</strong> kind of get, it&#8217;s just the &#8220;get me the value&#8221; kind of get. To clarify:</p>



<ul><li>get <strong>POST request values</strong><ul><li>use <em>request.</em>form.get(field name=&#8221;thisvalue&#8221;)</li></ul></li><li>get <strong>GET request values</strong><ul><li>use request.args.get(field name=&#8221;thisvalue&#8221;)</li></ul></li></ul>



<p>Finally on lines 24 through 28 we guard against the user not inputing values in our form by checking if either name or dorm return false. If one or both return false in our if statement, we return our failure.html page using the render_template function.</p>



<p>If the user submitted all the form values we use our &#8220;students&#8221; list and use the append method to add the formatted string to our list. Finally we redirect the user to the &#8220;/registrants&#8221; page. This confused me because I didn&#8217;t realize the app route is going to &#8220;/<strong>register</strong>&#8221; and the redirect is to &#8220;/regis<strong>trants</strong>.&#8221;</p>



<p>So normally we could pass a template using render_template. But I think it makes sense to use redirect to minimize code repetition. If the registrants template file ever had to change you would only have to change it in one place. The template should stay with the route!</p>



<p>Notice line 15 how we have students=students as an argument in the render_template fuction:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">@app.route(&quot;/registrants&quot;)
def registrants():
	return render_template(&quot;registrants.html&quot;, students=students)</pre></div>



<p>We&#8217;re creating a new variable for our render_template so it can access our <strong>students</strong> list. So the students on the right side is the one that has our name and dorms, while the one on the left is passed to our template. This is where <strong>jinja2</strong> comes into play.</p>



<p>Go to templates/registrants.html</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;HTML&quot;,&quot;modeName&quot;:&quot;html&quot;}">{% extends &quot;layout.html&quot; %}

{% block body %}

&lt;ul&gt;
    {% for student in students %}
    &lt;li&gt;{{ student }}&lt;/li&gt;
    {% endfor %}
&lt;/ul&gt;

{% endblock %}</pre></div>



<p>On line 6 we are using a <strong>for student in students</strong> <strong><em>loop</em></strong>. The <strong>students</strong> is the list of student data we passed from our application.py!</p>



<p>Just like any python loop we express a single item in our list but creating a temporary variable, in this case we call it <strong>student</strong> (singular). Now within the loop we add it to our html list with double curly braces <strong>{{ student }}</strong>.</p>



<p>We have to end our for loop when using html and jinja2 so on line 8 we use the <strong>{% endfor %}</strong>  statement.</p>



<p>Here is what happens after submitting the form two times:</p>



<figure class="wp-block-image size-large"><img loading="lazy" width="680" height="154" src="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-12-at-8.47.05-AM.png" alt="" class="wp-image-1410" srcset="https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-12-at-8.47.05-AM.png 680w, https://johnyzaguirre.com/wp-content/uploads/2019/11/Screen-Shot-2019-11-12-at-8.47.05-AM-300x68.png 300w" sizes="(max-width: 680px) 100vw, 680px" /></figure>



<p>Don&#8217;t forget using <strong>app.route</strong> doesn&#8217;t have to return a webpage! Notice how we don&#8217;t have a <strong>register.html</strong> file in our templates. This is because that route is only being used to process some values. Once we have them we can redirect them to an actual webpage. Each time the user goes to a different address it&#8217;s just running a function for us. That <em>might </em>be a webpage, other times it might just be doing some work behind the scenes.</p>



<h2>Adding more features to the froshim form</h2>



<p>Next up we add an email letting the user know they registered. Of course new features mean new import statements so let&#8217;s bring them in:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import os
import smtplib
from flask import Flask, render_template, request</pre></div>



<p>We aren&#8217;t using the redirect method so we&#8217;ll leave it out this time.</p>



<p>Next we create our app object and the usual route to our root web address &#8220;/&#8221;:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import os
import smtplib
from flask import Flask, render_template, request

# Configure app
app = Flask(__name__)

@app.route(&quot;/&quot;)
def index():
    return render_template(&quot;index.html&quot;)</pre></div>



<p>Then we configure the &#8220;/register&#8221; route to send a confirmation email to the user:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">import os
import smtplib
from flask import Flask, render_template, request

# Configure app
app = Flask(__name__)

@app.route(&quot;/&quot;)
def index():
    return render_template(&quot;index.html&quot;)


@app.route(&quot;/register&quot;, methods=[&quot;POST&quot;])
def register():
    name = request.form.get(&quot;name&quot;)
    email = request.form.get(&quot;email&quot;)
    dorm = request.form.get(&quot;dorm&quot;)
    if not name or not email or not dorm:
        return render_template(&quot;failure.html&quot;)
    message = &quot;You are registered!&quot;
    server = smtplib.SMTP(&quot;smtp.gmail.com&quot;, 587)
    server.starttls()
    server.login(&quot;jharvard@cs50.net&quot;, os.getenv(&quot;PASSWORD&quot;))
    server.sendmail(&quot;jharvard@cs50.net&quot;, email, message)
    return render_template(&quot;success.html&quot;)</pre></div>



<p>Using the smtblib (SMTP library &#8211; simple mail transfer protocol) we can log into an email account, and send emails to users through it. Just like you would from your own email account.</p>



<p>Using the os library allows us to use operating system variables and methods from within our program. We don&#8217;t want a plain text password in our program, so we can have the os library call it from an environment variable we set outside of the program. I&#8217;m using a mac, so in the terminal I would type <strong>export PASSWORD=<em>mypassword</em></strong>.</p>



<p>This script doesn&#8217;t work without a few changes. Can you try to use your email to send a success message back to the same email?</p>



<p>I had to add the email input in the index.html file, create an environment variable with my email password then update the script with my email address.</p>



<p>Finally google doesn&#8217;t allow apps like this to work by default. So do a quick search for <em>allowing less secure apps</em> <em>in gmail</em> to briefly allow the app to send the email to see it working.</p>



<h3>Using the csv library</h3>



<p>Here is another example where we save the registrants to a csv table file:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}">from flask import Flask, render_template, request
import csv

app = Flask(__name__)

@app.route(&quot;/&quot;)
def index():
    return render_template(&quot;index.html&quot;)

@app.route(&quot;/register&quot;, methods=[&quot;POST&quot;])
def register():
    if not request.form.get(&quot;name&quot;) or not request.form.get(&quot;dorm&quot;):
        return render_template(&quot;failure.html&quot;)
    file = open(&quot;registrants.csv&quot;, &quot;a&quot;)
    writer = csv.writer(file)
    writer.writerow((request.form.get(&quot;name&quot;), request.form.get(&quot;dorm&quot;)))
    file.close()
    return render_template(&quot;success.html&quot;)</pre></div>



<p>Getting csv (comma separated values) data can be really handy to users who have to filter data later in a spreadsheet. Python3 comes with a great library for this called <strong>csv</strong>. </p>



<p>On line 14 we use the <strong>open</strong> function to create our csv file, and the <strong>&#8220;a&#8221;</strong> means we&#8217;re going to be writing to the file in <em>append</em> mode, since we are going to add info to the file over and over every time a user fills out the form. We don&#8217;t want to overwrite the previous data, which is what would happen if we used <strong>&#8220;w&#8221;</strong> or write mode.</p>



<p>The csv class has a writer class that takes in a file handler, and gives us back an object with methods for adding data to the csv. We name the object <strong>writer</strong> and use the writerow method, passing in the data the way we want it entered into the row. Imagine this is our csv spreadsheet:</p>



<figure class="wp-block-table"><table class=""><tbody><tr><td>John Smith</td><td>Apley Court</td></tr><tr><td>Jane Smith</td><td>Matthews</td></tr></tbody></table></figure>



<p>Our csv files can be open in a text editor and look like this:</p>



<p>John Smith, Apley Court<br>Jane Smith, Matthews</p>



<p>Each column is separated with a comma<br>and each row is separated with a line break.</p>



<p>Back to our program we see on line 18 this is exactly what the <strong>writer.writerow</strong> function is doing. Pushing in a row of data from the form.</p>



<p>Finally with use the <strong>file.close()</strong> method, and return our success.html page.</p>



<p>Our .csv file can be opened in Excel. Create a few entries and try it out!</p>



<p>That is it for week 7 lecture notes!!!</p>



<h2>Preview into problem set 6</h2>



<p>Coming up we&#8217;re going to use flask to create a web app that compares strings char by char, or the less comfortable version is uploading two text files and comparing them in different ways. See you in the next one!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://johnyzaguirre.com/2019/11/13/cs50-week-7/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
