Height Data Collector

project / July 20th, 2021

Height Data Collector Home Page

Height Data Collector AppGitHub

Background

This is a web app where users can submit their height (in centimetres) and an email address. Once submitted, this data is added to a database and the app will calculate the average height from all of the heights collected. An email containing the new average height, current sample size, and an assessment of the user's height is then automatically sent to the user's email address from the Collecting Heights email address.

This is a professional portfolio project that was created after completing the 100 Days of Code Python Bootcamp.

Purpose

After completing the 100 Days of Code Python Bootcamp, I wanted to apply my knowledge of Python, Flask, and SQL databases with basic HTML and CSS to create a simple, interactive web app that would collect data from a user, store it in a database, perform an operation on the collected data, and send new information back to the user through a different medium like email or text. I felt this project would be suitable for a portfolio, since it touches on a variety of different tools and concepts I learned throughout the bootcamp and can be explained easily.

Concepts and Tools Used

  • Python

  • Flask

  • Jinja

  • SQLAlchemy

  • DB Browser

  • SMTP library (Simple Mail Transfer Protocol - for sending emails)

  • HTML

  • CSS

  • Heroku

Process

Define Project Requirements

My goals for this project were simple. The app will have a simple front-end built with HTML that contains a home page with a title, subtext, and required inputs that allow the user to submit their email address and height in centimetres. Once the data is submitted, the user is taken to the success page, which contains text informing them that their submission was successful and to check their email.

The back-end will add the new data to a database and calculate the new average height from all of the collected heights. An email that contains the average height, current sample size, and an brief assessment of the height of the newest user is sent to the email address of the newest user.

I decided to build the front-end first before building the basic back-end structure. Once the back-end structure is built, the next step is to ensure that my back-end is receiving the email address and height by printing them in the PyCharm console before creating a database and add more logic to calculate the average height and send an email.

Front-end

To comply with the requirements of the Flask framework, the HTML files for the home and success pages are created in a folder called templates and a CSS stylesheet in a folder called static. The home contains HTML elements for the website title, subtext, and a form with two inputs and a button for submitting the email address and height. Jinja tags are added around the subtext to add logic that will display different messages depending on whether the email address has already been used or not. The success page is simply comprised of text to inform the user that their submission was successful, as well as a button to return to the home page. CSS is added to style the background, fonts, and buttons for both pages. The HTML and CSS files are built and tested locally before incorporating them with the Flask app.

Height Data Collector Success Page

Back-end

The basic structure of a Flask app is built from importing the Flask class from the flask library. A GET route and POST route are then set up to render the HTML files for the home and success pages, respectively. Inside the success route, code is written to verify that the oncoming request is a POST request. If the success route is getting a POST request, the request method is used to access and print the email address and height submitted in the inputs. This verifies that the back-end is receiving the correct data.

The next step is to create an SQLite database and connect it to the back-end. First, an SQLAlchemy object is created for the Flask app and the app is configured to specify a connection to the URI of the new database. Next, a Data class that is inherited from the model class of the SQLAlchemy object is created to act as a database model and has integer, string, and integer columns for the id, email, and height, respectively. When new data is added to the database, it will be added as an instance of the Data class.

After the database is created, the email address and height values that were printed earlier can now be sent to the database by passing them to a newly created object from the Data class and using the add and commit SQLAlchemy object commands. Before executing these commands, a database query is performed to see if that particular email already exists in the database. If so, the home page is rendered with a different subtext (thanks to the logic written with the Jinja tags from earlier) above the form to indicate to the user that the email address has already been used.

Height Data Collector Wrong Email

Otherwise, the add and commit commands are executed and the new email address and height are added to the database.

The final pieces of logic to add to the back-end code are to calculate the average height from the collected database heights and to send an email containing this information. To get the average height, an SQLAlchemy method called avg from the func class is used in a database query on the height field. The rounded average height, current number of users, and the email address and height of the newest added user are then passed to a function called send_email, which is created next.

Another Python script called send_email is created and contains a function of the same name that will handle the email functionality. Inside the send_email function, conditional IF statements are used with the height of the newest user to determine what personalized message their email will have. Using the SMTP library, the function will then create a connection to the Gmail server (where the Collecting Heights email address is provided) and log in into the Collecting Heights email account to compose and send an email to the newest user that includes the personalized message, the average height, and the current sample size. The send_email function is then imported into the main back-end server code to be used after a successful addition to the database.

Height Data Collector Email

Deployment

This app was deployed by committing the project to a GitHub repository and connecting to it with Heroku. A necessary key change is to upgrade the database from an SQLite database to a PostgreSQL database. Although SQLite is great for local development and allows us to view changes to the locally created database using DB Browser, it is not intended to be a production-grade database. This is because SQLite is a file-based database, which can be problematic since file locations on a Heroku server get shifted around daily. The database would be at risk of getting wiped every day. Heroku allows developers to upgrade their database to their production-grade PostgreSQL by adding it on the Heroku dashboard. Because SQLAlchemy was used in the Flask app, the only necessary changes are connecting to the new database URI provided and installing the psycopg2-binary library.

Outcome and Takeaways

Building this app was a valuable experience in creating a full-stack web app that incorporated the variety of different tools I learned about in the 100 Days of Code Python Bootcamp. Being able to incorporate a front-end, back-end, and a database and see them work together seamlessly to produce a tangible result like an email was especially satisfying.

This app can also act as a template for other data collection projects and be easily modified and customized to suit different needs.

Possible Improvements Going Forward

In addition to sending email, it would also be useful to use the Twilio API to send the results as text messages. Another improvement would be to expand the database model and forms to include more pieces of data like weight and use it to calculate a useful metric like BMI for health and fitness purposes.


External Links