Create a Command Line Tool with Python

A Python Script to Display Weather Predictions (Part 2)

Sandesh Chapagain
Python in Plain English

--

Photo by Lukas from Pexels

In the first part of this article, we wrote a python script that helps us check today’s weather. However, we had slightly bigger plans and we left some things unfinished. Today we are going to tweak our program so that it is more flexible in the day of the week we care about, and in the units in which we want to display our temperatures. We’ll also write a simple bash script that will allow us to execute our program with a much simpler command than with just using a python script. Let’s jump right into it!

Selecting the right day of the week

What you might not have noticed in the last article is that we already had information for all eight days (the whole next week including today), and chose to display data for only one of them. Remember the variable day_number we had in the main function?

def main():
"""
Setup our main program
"""
units = "metric"
day_number = 0 #Represents today

I didn’t really explain why a day number of zero represented the current day. Where did we even use that variable? In the get_weather_data() function we had a line that selects, from an array of dictionaries, just the one with an index of day_number.

def get_weather_data(units,day_number):
"""
Connect to the API using the requests library
and return the predictions for the given day number
"""
......
# Extract relevant data from the API response
data = response_dict['daily'][day_number]
......

The API we used to get our weather data returns information for all eight days as an array. If today is Sunday, the response_dict[‘daily’] array is structured so that the first element contains information for today’s weather, the second one for tomorrow, … , and the last one for next Sunday. Now that we know how that works, we can easily change our day number to display data on whatever day we care about.

If I wanted weather for the day after tomorrow, I would just alter my day number to be 2 and I’d be all set.

day_number = 2 #Represents the day after tomorrow

Parsing command line arguments

We now know how to select any given day, but every time we want to do that we need to modify our python file, which is definitely not something we want to do. So let’s see how we can take the name of the day as an input instead.

The ArgumentParser object

To get started with this we need to use the argparse module. Don’t worry about installing it if you’re using Python3.2+ — it’s part of the Python language. However do remember to import it at the top of your script. Now, add the following lines of code (surrounded by #s), in your main function.

What we’ve done is created a parser object that takes in an optional positional argument and stores it under args.day. So now either args.day is None, or it stores whatever the user wrote after the name of our script in the command line. For instance, a command of:

python main.py monday

would make args.day == ‘monday’.

It also takes in an optional flag of -u and allows us to input our units of choice. This information is going to be stored under args.units. I’ve made the default units to be metric if the flag is not used, but feel free to change that to ‘imperial’ if that’s the one your most often use. Some example usages would be:

python main.py -u imperial
python main.py tuesday -u imperial
python main.py -u metric tomorrow

Calculating the day number

Allowing users to type in the actual name of the day is exactly what we want, however, remember we still need to convert this name to a day number in order to use it as explained earlier. Also before we can find the day number, we need to know what day of the week today is. In order to do that, we will seek help from the datetime module. Import it in your script, and let’s now see how we can get our much desired day_number.

First we got today’s index into the weekday (0 for monday and 6 for sunday), and then, depending on the name given as an input, we calculated the day number for the given day. Let’s break down what’s going on in the last five lines of code up there.

We first find the index of the given day, where a 0 would mean the given day was a Monday, and a 6 would mean it was a Sunday. Then, we compare it to the current day. If the given day is before next Monday and after the current day, we can simply subtract those two indices to find the number of days between today and the given day (day_number we talked about before). However, if the given day is after the coming Sunday, we need to add the number of days until Sunday, and the number of days from next Monday to the given day to find the day_number.

Great, now we have a dynamic day_number that we’re passing on to the get_weather_data() function, which will automatically grab only the data pertaining to the given day.

Writing the shell script

Here I am going to use Bash but if you use zsh or any other shell, the script would be very similar to this — although might require a little digging on the internet for the right syntax. Create a new file called weather (with no extension), and add the following lines to it:

#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
python $DIR/main.py "$@"

All these lines of code do is run our main.py file and pass along all the arguments we give to our command line to the python script. It also requires the python script to be in the same directory as this bash script.

Type in the following command in the terminal window:

sudo chmod +x weather

This makes our script executable so that we can run it from the terminal. Now we can type:

weather tomorrow## output:
Description: light snow
Temperature: -10.61°C (-16.42°C to -9.98°C)
Feels like: -17.66°C

Adding out script to $PATH

Our little program works great, however, if we had to go into a specific folder and type in the command for the program to work, it would not be too much fun. It would be nice if we could see the weather from any terminal window no matter what our current working directory is. To do this we need to add the directory in which the script exists to the $PATH.

$PATH is just a location where the shell searches for whatever program is trying to be run in the terminal. If we add the script’s directory to $PATH, no matter what our current working directory is, the shell can locate the script, and then we’ll get our predictions.

To add a location to $PATH, we need to edit the shell configuration file. This is located in the home directory with the name of .bashrc (.zshrc for zsh). Open up the file with your favorite text-editor and add the following lines:

export PATH="$HOME/Desktop/weather:$PATH"

This is assuming both your weather script and main.py is located in your desktop inside a folder named weather. Now you can restart the terminal and then run our program from anywhere within the console.

Conclusion

Thank you for following along, and building this with me. Our program’s output is not the prettiest, but I wanted to let you improve the aesthetics as a fun exercise. My ways of doing things might not have been the best ones, especially the shell scripting part, so if any of you guys are more familiar with those, please do comment on what I could have done better.

Keep hacking!

--

--