diff --git a/projects/fdic/app.py b/projects/fdic/app.py new file mode 100644 index 0000000..65a51f9 --- /dev/null +++ b/projects/fdic/app.py @@ -0,0 +1,55 @@ +# Flask is what makes everything work. Import it. +from flask import Flask, render_template + +# Import our bank model. +from models import Bank + +# Flask needs to run! This gives it legs. +app = Flask(__name__) + + +# Routes! +@app.route('/', methods=['GET']) +def failed_banks_list(): + """ + This route is for a list of ALL banks. + """ + + # The context for this pages is just "banks", a list of all banks. + context = { + 'banks': Bank.select() + } + + # Render the template to list.html and with the context from above. + return render_template('list.html', **context) + + +@app.route('/bank//', methods=['GET']) +def failed_bank_detail(cert_num): + """ + This route is for a single bank. + We're going to do TWO things. + a.) We're going to get the one bank. + b.) We're going to get all banks EXCEPT this bank in the same state. + """ + # a.) Get this bank. + this_bank = Bank.select()\ + .where(Bank.cert_num == int(cert_num)).get() + + # b.) Get the other banks in this state. + same_state_banks = Bank.select()\ + .where(Bank.state == this_bank.state)\ + .where(Bank.cert_num != int(cert_num)) + + # Set up the context; include both this bank and other banks from this state. + context = { + 'bank': this_bank, + 'same_state_banks': same_state_banks + } + + # Render the template to detail.html and with that context. + return render_template('detail.html', **context) + +# Last bit! Just need to get flask to run when we run it. +if __name__ == "__main__": + app.run(host='0.0.0.0', debug=True) diff --git a/projects/fdic/models.py b/projects/fdic/models.py new file mode 100644 index 0000000..5a5de33 --- /dev/null +++ b/projects/fdic/models.py @@ -0,0 +1,30 @@ +# Import our library. +from peewee import * + +# Connect to the DB. +db = SqliteDatabase('fdic.sqlite') + + +# Set up a bank. +class Bank(Model): + """ + This defines a bank and all of the fields a bank has. + """ + bank = CharField() + city = CharField() + state = CharField() + cert_num = PrimaryKeyField() + acq_inst = CharField() + closed = DateField() + updated = DateField() + + # What is this thing? + class Meta: + """ + It's a class INSIDE a class. + Don't let that bother you. + We need to attach this model to a database. + Also, we need to point to Schnaars's table. + """ + database = db + db_table = 'failed_banks' diff --git a/projects/fdic/requirements.txt b/projects/fdic/requirements.txt index d0e040a..aaba7ef 100644 --- a/projects/fdic/requirements.txt +++ b/projects/fdic/requirements.txt @@ -1,2 +1,4 @@ beautifulsoup4 python-dateutil<=1.5 +peewee +flask diff --git a/projects/fdic/templates/base.html b/projects/fdic/templates/base.html new file mode 100644 index 0000000..02178ec --- /dev/null +++ b/projects/fdic/templates/base.html @@ -0,0 +1,13 @@ + + + + + + +
+
+
{% block content %}{% endblock %}
+
+
+ + \ No newline at end of file diff --git a/projects/fdic/templates/detail.html b/projects/fdic/templates/detail.html new file mode 100644 index 0000000..f5cd5f4 --- /dev/null +++ b/projects/fdic/templates/detail.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} + +{% block content %} +

{{ bank.bank }}

+

{{ bank.city}}, {{ bank.state }}

+

Closed {{ bank.closed }}

+
{{ bank.bank }} has the certification number {{ bank.cert_num }} and was closed on {{ bank.closed }}. +
It was acquired by {{ bank.acq_inst }}.
+ {% if same_state_banks.count() > 0 %} +

{{ same_state_banks.count() }} more banks in {{ bank.state }}

+ +
+ {% endif %}
+ +{% endblock %} \ No newline at end of file diff --git a/projects/fdic/templates/list.html b/projects/fdic/templates/list.html new file mode 100644 index 0000000..0deed53 --- /dev/null +++ b/projects/fdic/templates/list.html @@ -0,0 +1,9 @@ +{% extends 'base.html' %} + +{% block content %} +

Failed banks

+ +{% endblock %} \ No newline at end of file diff --git a/tutorials/webscraping101/fec_efiles_scrape.py b/tutorials/webscraping101/fec_efiles_scrape.py index b2c3c8b..5cd68de 100644 --- a/tutorials/webscraping101/fec_efiles_scrape.py +++ b/tutorials/webscraping101/fec_efiles_scrape.py @@ -94,6 +94,7 @@ # To get at the raw data for each filing, we'll combine the above BASE_URL with # unique FEC report numbers (found in the download_links that we extracted above). + for link in download_links: # Below, we use a single line of code to extract the unique FEC report number: @@ -124,7 +125,33 @@ # The first row in the FEC data contains useful info about the format of # the remaining rows in the file. - version = data[0][2] # e.g., 8.0 + # However, after the initial creation of this scraper, there is at least one bad + # link that we have to handle. + + # First we try to extract the version. If it is successful, then continue. + # If not, we moves to the exception handling section. + try: + version = data[0][2] # e.g., 8.0 + # This exception handling section looks for our bad link which causes the program + # to throw an IndexError. We going to define a special url for this case. + + except IndexError: + # If you look at the code below, you will notice that it repeats what we had above. + # However, the csv_download link is redefined. + # For the best practice, we would pull out this pattern into a function. + # Then we would call the function above then again if the error occurs. + # We encourage you to try to turn this piece of code into a function that is + # called twice. + ALT_BASE_URL = 'http://query.nictusa.com/showcsv/nicweb26502/%s.fec' + csv_download_link = ALT_BASE_URL % fec_num + response = requests.get(csv_download_link) + data_rows = response.text.split('\n') + data = list(csv.reader(data_rows)) + version = data[0][2] # e.g., 8.0 + # If the program has another index error at this point, this means that our + # catch/fix didn't work. More troubleshooting and exception handling might + # be needed. + print "Downloaded Electronic filing with File Format Version %s" % version ### WHAT'S NEXT? ###