Full Stack Development in 1 Twitter Thread
By: Sean Mcclure
Tags: Front End Development, Hacking, Prototyping, JavaScript, Development

Full Stack Development in 1 Twitter Thread

End-to-End Steps for Turning Your Idea into Something Real

When Form Follows Function

People have ideas. Lots of ideas. But how often do they turn those ideas into something real? There is a distinct difference between what’s in our heads and what can be created.

Most people don’t build software. This includes many people on actual software teams. If you’re not coding now you see the creation of working software as someone else’s job. Perhaps you’ve wanted to start learning (or relearning) yourself but assume it takes too long, is too technically challenging or just not something that interests you.

Ideas typically live as drawings, post-its, mockups and “clickable apps”, all of which might capture ideas but are hardly validation of something workable. There is a transition point between one’s ideas and what nature allows to happen, and through that transition is where innovation actually happens. There is a beautiful correspondence between form and function that only a true piece of working software can expose.

There are no excuses left for someone not making software. No matter your interest, if you want to see your ideas come to life then you need to build software. Given today’s level of abstraction in tooling, full pieces of software can be created rapidly.

Software development isn’t about “programming” computers it’s about crafting something real, that interacts with people, and becomes part of the working economy.

I originally wrote this on Twitter in a single thread, to show how just how accessible it is for anyone to create end-to-end software applications.

There are many false gatekeepers to opportunity. The assumption that you need formal education, online courses or years of deep experience is patently false. Everyone has the ability to piece together their idea into something that actually works.

Let’s get started.

The Pieces

You only need a browser, a notepad, and your computer’s terminal (command prompt on PC). There are a few high-level pieces that go into building all applications:

a page

styles

layouts

interactive elements

events

server

fetching/storing data

People rarely write programs from the ground up anymore. That’s too slow. Today we use libraries. We will use JavaScript and Python libraries. I will use Azle for front-end stuff ( DISCLAIMER : I created Azle, but you can use any JS library), and Flask for back-end stuff.

Let’s start with our page.

Pages always have an index.html file. Go to the Azle homepage and click on the STARTER HTML icon in the top left. Copy and paste this into notepad or whatever editor you want (I’ll use TextWrangler), then save the file as index.html (on your Desktop).

Grabbing the STARTER HTML file from Azle.

Every web application has an index.html file. It’s the page your browser points to when you load a website or web application. Let’s place the file in a folder called my_app , and drag your index.html file into this folder:

If you right-click the index.html file and choose your browser you can view the page. Doing that will pop open your browser and show a blank page.

Let’s style the page. Go grab the style_body code from Azle and paste it into your index.html file (inside the create_azle function):

Don’t be like Reddit and think you’re cool cuz yer ugly. Go grab some minimalist hex codes and style your page like its 2020. Nothing says I’m modern like Russian pastel:

flatuicolors.com/palette/ru

Choose your favorite color by clicking on it. Replace the “background” color in the style_body function with your new color. I’ll choose Biscay. We also don’t want to use standard browser fonts because the only thing worse than looking like Reddit is looking like Craigslist.

Google fonts to the rescue. I’ll choose Ubuntu. Nice and modern looking.

Of course, we need to make our Google font available. Let’s load that prior to calling our style_body function. Search for “font” in the docs to find the load_font function):

az.load_font("Ubuntu")

I also set the min-width property in the style_body function to 1150px so the page doesn’t squish when I resize the browser. Since we’re only prototyping an application we don’t care about responsivity.

Our code should now look like this:

Since this all sits in our index.html file we can refresh the browser and see the result:

Here’s the CodePen if want to play with the code. Try changing the color of the background. Of course, changing the font won’t make a difference yet since we are not showing any text.

Whenever you see CodePen in this article, click on it to open a tab showing a live interactive version of our current code. Play with the values to suit your preferences.

We are making progress…

Of course, nothing is on our page. Let’s change that. We will add a section to hold our content. Add 1 section using the add_sections function:

…and refresh your browser:

Azle’s default color for sections is a blue color, but of course, we can change that as needed.

CodePen

Try changing the number of sections.

Let’s head back to Russia and see if we can’t find a better color than blue for our section. Use the style_sections function (placed directly below our add_sections function) to style our new section. To style an element we must target it using its class name and instance number. We know the class name of our section is called “my_sections”, and since we only made 1 section it must be the first instance. Our style_sections function looks like this:

I will choose Apple Valley as my section background color. I also added a border-radius of 6px to round the corners. I set the height to auto , which allows HTML elements to grow and shrink based on the contents inside the element.

Since we want to arrange things on the page we will use layouts. These are just grids; boxes placed on the page, which we fill with text, buttons, sliders, inputs, etc. I’ll add a layout with 2 rows and 1 column using the add_layout function:

It looks like this:

I want the top row to hold my title. I’ll change the top row’s height to 60px by targeting the first row of my layout using another style_layout function, directly below our previous one:

Note how I targeted the class name of the row “my_layout_rows” and the first instance (row 1). Refresh the browser to see the difference:

Everything we’ve been adding inside the curly braces of our style functions is standard CSS styling. As you try to figure out how to achieve the styles you want just search online for the right CSS. With time you will learn many styling tricks.

Let’s go ahead and show off the Ubuntu font we loaded earlier by adding a title to our application. We target the first cell of our layout and add text using the add_text function:

Let’s increase the font size of our title, and center its alignment:

Pretty good so far. Now things get more interesting, as our next step is adding interactive elements to our application.

Let’s add another layout inside our 2nd cell to hold our interactive elements. Copy the same layout code we used before, pasting it at the bottom. Target the 2nd cell of our original layout, use 1 row, 2 columns, and color the background creamy peach (or whatever you like). We add the add_layout and style_layout as functions directly below our previous code, as follows:

Notice I also used the column_widths property of the style_layout function to give a 20/80 split between column widths.

The app looks too “liney.” Let’s remove the bordering from our most recent layout by setting its border to 0 :

That’s cleaner. However, I still want some kind of separation between the 2 cells of our inner layout. Let’s color the 2nd cell “Squeaky” from our Russian palette:

Notice our app no longer requires any bordering, since the coloring alone demarcates our layout cells. Let’s make it minimal and smooth by removing the outer layout’s (the first one we added) border.

Here’s the CodePen at this point.

Now we’re ready to add our interactive elements. We didn’t start with any mockups of what we wanted to create, which is fine. But now might be a good time to think about what we want this to be.

Most of today’s interesting applications are data-driven. What kind of interesting data could we fetch, and what kind of model might we use? While I write this, covid-19 is on everyone’s mind. Let’s fetch covid-19 data and use a model to predict cases.

****Usual Disclaimer***** Don’t be an idiot and use this model to make real-life decisions regarding a pandemic. This is just for demonstration purposes.

We want publicly-available data, ideally delivered as a “RESTful service” (“REST API”). REST APIs deliver data and functionality “over the wire” into our browser, making it easier to create interesting applications without having to write a ton of code.

If someone offers covid-19 data as a REST API it means we don’t have to store/manage the data ourselves; we can just use it

I found one here: https://about-corona.net It’s free and requires no authentication.

REST APIs have “endpoints”, which are what we point to with our browser to fetch actual data. After reviewing the documentation I found the endpoint we will use:

https://corona-api.com/timeline

This gives global counts for deaths, confirmed and recovered cases.

Anytime you want to see what a REST API’s data looks like just open your browser to the endpoint:

To use the data in our application we don’t access it as above, rather we ingest the data using JavaScript, and parse the results into some useful form. But first, let’s get back to our mockup. Now that we’ve seen the data, we can think about how our app might look and act.

A dirty mockup is all we need to anchor our approach. Here’s what I came up with, using Google Slides to create the sketch:

The user chooses a type (deaths, confirmed, recovered), with results visualized on the right in a graph. The user then chooses a “horizon” (future days) and clicks FORECAST to run a model in the back-end, whose results also get visualized when they are returned.

With data and mockup in hand we can start adding our interactive UI elements. We need a dropdown, a slider, a button, and a line chart. Let’s start with the first 3. I’ll add a new layout inside the first inner layout cell to help position our elements:

Notice I kept the border set to 1 so I can see the new layout:

Now let’s add our UI elements inside these new cells. From Azle’s documentation we can grab the code we need.

Add dropdown, slider and button code to our application:

Boom, now we have UI elements:

Let’s tailor these elements for our app. We know the options we want for our dropdown (deaths, confirmed, recovered). Add those now:

Let’s allow up to 30 days for the prediction. Set the default to 1 week out ( 7 days), with min_value of 1 day and max_value 30 days:

Let’s center the elements and remove the border from our recent layout.

We will use the all_ prefix in front of a new style_layout function to apply center alignment to all 3 cells at once:

I also set the border on the layout to 0 since we no longer need it.

Toggle the border between 1 and 0 while developing.

halign with center ensures the contents of all 3 cells align horizontally.

Now let’s add our line chart visual.

Starting to look like a real application now. For the line chart we will use another library called Plotly. Plotly is built on top of D3.js, an industry-standard visualization library written in Javascript.

While you can learn D3.js itself, Plotly offers an abstraction layer that makes development (much) more rapid. Click the line chart option on Plotly’s website:

We will copy the line chart code into our application. First, we need to make this library available. The simplest way to make a JS library available to an app is via CDN (content delivery network). We just add the appropriate URL to the header of our index.html file. We find this URL from Plotly’s Getting Started page:

Now we can use any of Plotly’s visuals in our application. Grab the line chart code from Plotly’s website and place it inside a function called draw_line_chart , like this:

Place this anywhere in the index.html file, outside the main create_azle function (so anywhere at the bottom, but still inside the <script> tags). Look in the next CodePen to see.

If we invoke our draw_line_chart function it will draw our line chart inside the element with the my_div id. Of course we don’t have any element like that now, so let’s create the HTML element that will house our plot.

We will use Azle’s add_html function. I will give the div an id called “hold_chart” :

Let’s go back and change ‘myDiv’ in the previous draw_line_chart function to ‘hold_chart’ so it targets correctly.

We need a way to call our draw_line_chart function. Let’s make it so that clicking on our FORECAST button draws our line chart.

To add events to UI elements in Azle we use the add_event function. Let’s add a click event to our FORECAST button like this:

If we now click the FORECAST button we will see the line chart drawn:

Looks great. Here is this latest CodePen.

Plotly provides a lot of slick stuff out of the box. We get tooltips, zooming, panning, and a host of customizable options. Doing this all yourself in raw D3 isn’t fun.

The data shown in the line chart is just mock data provided by Plotly. Obviously we want to hook up real data. Let’s do that now.

I mentioned earlier that we will ingest the REST data using JavaScript, and parse the results into some useful form. An important fact about building apps that rely on fetched data is the data must be available prior to using it.

While this sounds obvious it’s easy to miss when one is just beginning to learn software development. As an example, when our users first load our app we want to show the line chart. But that line chart depends on data being available.

To make sure data are available to any pieces of our app that require it we use so-called “asynchronous code.” Asynchronous code WAITS until something has happened (e.g. data has been fetched) before calling a function of our choice.

In our case, we want to fetch covid-19 data, WAIT until it’s available in our app, THEN draw our line chart. JavaScript makes all this possible via its “fetch” API. With fetch, we simply point to the URL provided by the REST service and tell it what to do once data are received.

Let’s use fetch to bring our covid-19 data into our application. How do we use it? A simple Google search led me to this, which explains it quite nicely. It tells us to use fetch like this:

Let’s paste it into our code, using the covid-19 URL we found above (right after our Plotly code):

Refresh your browser. The app itself doesn’t look any different. But if we open the “browser console” we can see the covid-19 data we fetched. Open the browser console by right-clicking anywhere on the screen and clicking “inspect”. Then click console.

You will see an “Object” sitting in the console. This is the covid-19 data we fetched (notice the fetch API we pasted above says console.log(data)). Click repeatedly into this object to view its structure:

This looks a lot better than what appeared in the browser when we first pointed to the covid-19 URL. Now we can parse this data object, using its contents to populate our line chart. To do this we’ll need to make a slight change to how our line chart is being drawn.

Inspecting the line chart code we added earlier we can see it uses “traces” to convert raw data into lines. We need to get the data from our fetch results into these x and y properties of the trace object:

Let’s write some JavaScript to parse the results of our fetch. We need to: 1. understand the source structure; 2. understand the destination structure. We can understand the source structure by inspecting the data in the browser console as we did previously.

The destination structure is the trace object required by Plotly. I wrote the following function to take the raw data retrieved from fetch and convert it into the trace structure needed for Plotly:

Functions are how we group code in software. They have a name, accept arguments, and return some result. Functions help keep code modular and maintainable.

What’s important here is to understand this is not the way to parse data. It’s a way. You must experiment with JavaScript and toy around until you find something that works. Search online for how to parse JavaScript objects, loop through them, and return new structures.

My get_dates_and_cases function accepts the fetched data, a choice (e.g. deaths), loops through its contents, extracts the pieces I need for plotting, and returns the object for Plotly. I will write another function to draw the line chart with our prepared data.

We can remove the original Plotly code we added and use this function instead. It uses our first function to prepare the trace data, then plots the line chart as usual.

Be sure to keep the “hold_chart” div we added so the plot has somewhere to live.

Recall that our fetch code only fetches data but does nothing with it. Let’s make it do that our fetch function draws our line chart once the data have arrived. Change our original fetch code to look like this:

Finally, remove the call to draw_line_chart that currently sits inside our add_event function. We’ll add it back in a second. Also, don’t worry about the az.hold_value.fetched_data = data line yet. We’ll explain that later.

Your current code should look like this: CodePen.

Notice in the CodePen I wrapped a setTimeout around the fetch function. This just adds a slight delay to ensure the elements are on the screen when it goes to draw the plot. This won’t be an issue once we move the fetch function to inside our add_event in the next step.

Our covid data is now showing in the line chart. Importantly, the line chart will only be drawn when the data have been fully fetched from the REST API. To recap, we used asynchronous code in JavaScript to fetch data from an API, THEN created a visual once the data were ready.

We also wrote 2 functions to prepare the raw data and plot the results. We are getting close:

…although we haven’t discussed the data storing yet.

Our next step is to allow the user to select a choice (deaths, confirmed, recovered) to redraw the line chart accordingly. Let’s store the returned data so we can use it as needed, without having to refetch the data each time.

I will keep the returned data in a JavaScript object. I will just use Azle’s namespace like this:

Type az.hold_value.fetched_data into the browser console and hit enter. You can see that we can access our covid-19 data anytime by simply working with this object.

First, we want to redraw the line chart when the user makes a choice from the dropdown. Let’s use Azle’s “ change ” event to make this happen.

To add an event to our element we use Azle’s add_event function as we did before for the button, targeting the element of choice, just as we did with styling:

If you refresh your browser and make a selection from the dropdown you should see the choice alerted.

Now we just need to redraw the line chart instead of calling alert. Our draw_line_chart function we wrote earlier is ready to go. It already takes the data and choice as arguments and redraws the plot accordingly. So all we need to do is add draw_line_chart to our add_event function for the dropdown:

Notice we are using the data stored inside az.hold_value.fetched_data . We are also using a new Azle function called grab_value ; this allows us to grab whatever value the user chose on an element (targeted as usual, with class name and class instance ).

Let’s see if it works:

Beautiful.

Here’s the current CodePen.

Adding events to our other elements works the same way. But those elements relate to calling some back-end model to make predictions using our covid-19 data. So before adding the other events let’s start working on the back-end model.

For the “back-end” we need a server that supports the heavy lifting required to compute our predictions. We could use a cloud provider such as Digital Ocean or Amazon Web Services, but since we’re just prototyping ideas we’ll use our own local computer.

Getting a front-end communicating with a back-end requires a web service. A web service will allow us to send requests to the server and receive something in return. This is what we need, since we want to give a back-end model data from our front-end and return a prediction.

We will use a lightweight web framework called Flask to build our web service in Python. Let’s do that now. At the beginning, we created our index.html file. Let’s add another file to the same folder, calling it predict.py :

I just copied the index.html file and removed the contents to make an empty predict.py file.

Now we will add some basic Flask code to our currently blank predict.py file. Flask’s documentation has a Quickstart guide where they show us the minimal code needed to set things up:

We will need a few more pieces, like extra libraries, to get our web service suitable for our purpose. Here is what our predict.py file will look like:

Whereas in JavaScript we used “CDNs” to add extra libraries to our application, in Python we use import statements. Above we are importing Flask, as well as the “request” and “jsonify” libraries, which will enable us to receive and send data from-and-to our front-end.

We also set a “route” which is an “endpoint” for our service. Recall our discussion on endpoints when we looked at fetching covid-19 data from a REST API. If you’re thinking we are making our own REST API right now then you are correct :)

Much of today’s back-end machinery in enterprise software is made available as services, consumed as REST APIs. This makes it easier to patch together various functionality and maintain and scale the application.

Beneath the “route” in our predict.py file we create a function. Python functions look different than Javascript functions, but the idea is the same; a modular piece of code that can accept arguments and return a value. I called our function forecaster.

Finally, we specify the “port” at the end of the file. A port is a programmatic docking point that grants access from the outside world to our local system. I chose port 5000. You can choose a different number if you want (if it’s already being used your computer will tell you)

Let’s fire up our web service to see if it works. If it all goes well we’ll add our prediction model and start serving real forecasts for our application to consume and visualize.

So far we’ve just been using a browser and notepad to create our application. But now we need to speak directly with our operating system, and for that we must use terminal (command prompt on PC).

I am using a Mac, so everything you see here will be in macOS. But the same general steps apply to PC. Open terminal. Quickest way in Mac is to use Spotlight Search by typing “command + spacebar” and typing in “terminal”:

With terminal open, change into our my_app directory by running the following:

cd Desktop/my_app/

…and hit enter. Now type:

ls

… and hit enter again.

You should see both the index.html and predict.py files. Hard to believe our entire application is only 2 files.

Thanks to the level of abstraction available in today’s tools we only require minimal code to create a full blown app.

Now, start our web service by running the following:

python predict.py

…and hitting enter.

You are now running a web service, exposing your Python code to any application capable of communicating with it. This is pretty cool, considering so many high-powered libraries are available today in Python. Just think what you could create!

Our back-end is being served on “localhost”, port 5000, with an endpoint called “predict_covid”, accepting parameters called “x” and “y”. To pass all this information “over the wire” we can construct the following URL:

http://localhost:5000/predict_covid/?x=100&y=400

This is the standard way to communicate with a REST API when using URLs in the browser. The ? mark precedes the first parameter name, and the & precedes the second. Open a new tab in your browser, add the above URL to the top, and hit enter. You should see the following:

Our web service simply returns the values we passed for “x” and “y”. Not too exciting, but it does prove our web service works.

Let’s hook it all up, end-to-end, so that our front-end application written in JavaScript (Azle) is passing data to, and receiving data from, our web service (rather than the browser). If we succeed, the only thing left to do will be building a good forecasting model in Python.

We need to pass the following data to our back-end:

dropdown choice

slider value

dates and # of cases

Note: We could fetch the covid data in the back-end rather than passing it over-the-wire, but then we would be fetching data twice. Since we are only forecasting a few dates and values it makes more sense to use the data already fetched from the front-end.

We already know how to “grab” the values from UI elements, using Azle’s grab_value function. We also have our fetched data structured nicely in our az.hold_value.fetched_data object.

To send this to our web service we could use JavaScript’s fetch API again. Instead, let’s use Azle’s call_api function, inside our button’s event listener:

Here is a breakdown of what is happening:

We added an “event listener” to our button, just like we did to our dropdown earlier. We also added Azle’s call_api inside the event’s function property, specifying the URL to our Flask service, the “x” and “y” parameters, and an alert when data are returned.

Refresh your browser and click on the FORECAST button:

Our application is officially interacting with our back-end service, passing data to, and receiving a response from, our Python code. Let’s replace the “x” and “y” parameters with the actual data we need to send, and also add the forecast horizon from the slider value.

Here I am grabbing the slider value, and the “x” and “y” data from our existing get_dates_and_cases function.

We now have our events hooked-up:

Finally, let’s build a forecasting model to make predictions based on the user’s choice of type (deaths, confirmed, recovered) and horizon. After some searching around I found a library called Prophet, which was open-sourced by Facebook.

Facebook recently released their neural prophet version as well.

Prophet is a forecasting library for time series, and has a Quickstart guide for Python that should get us up and running.

Our final predict.py file receives data from the front-end (which we already know how to do), prepares the data as needed by the Prophet library (as specified in their docs), trains a forecast model, makes a prediction, and returns the results.

All this in about 10 lines of code. Not bad! (There’s that abstraction working for us again).

In our index.html file I added 2 new functions for prepping data for the 2nd trace (to show the forecast). You’ll see it’s very similar to the ones we wrote for trace 1. I also added the new draw_forecast function to the done property of our call_api function.

Have a look over the final index.html to see the changes. You should recognize the final changes as familiar code. If anything looks unfamiliar search online to learn why it might have been added.

Let’s refresh our browser one last time to see the full application in action.

We achieved everything on our original list:

Before singing off, I want to add a spinner when the user clicks FORECAST so they know to wait for the result. I also want the Plotly chart to be transparent so we can see that nice blue background we had. Finally, I’m going to change the title of our app now that it’s something real.

You can find the final code here:

And here is the final CodePen. Note that since CodePen isn’t running our back-end web service you won’t see the predictions. But everything should be working on your local machine.

These are the major parts that go into building any application. With these skills you can grow into the world of software development (or just use it as a hobby to build stuff).

That’s it. Might seem like a long article but considering you just crafted an entire application with all major pieces, not too bad. If you’re stuck, reach out to me on Twitter. We’ll work through the code together. And don’t stop here. Try other libraries. Other use cases. Other anything. Just build.

Again, the only gatekeeper to opportunity is you.