You've probably heard of Python, an interactive programming language that makes it easy to work with data. Today it's used for everything from websites and apps to statistics, machine learning, and AI.
With Python, writing code is simple, but it takes some time to create a program that's actually useful. You could also use the open-source app Jupyter Notebooks to work with data, but that won’t get you very far when you want to develop actual software. Today I’ll change the game for you by showing you how you can quickly and easily create a program using Python.
I’m making a horoscope generator. Why? Because I thought it would be fun to build a program that generates random text from pre-made blocks. And what better use of Python, which most people use to make smarter predictions, than pseudo-scientific predictions of your daily fate? The irony made perfect sense to me. So let’s go.
Note: You can use this code to randomly compose any block of text: a political speech, an ad, a formal application letter, you name it. So even if you're not interested in horoscopes, you can still use this program for your own interests.
Here's what we’ll do, and how our software will work:
1. We’ll do some basic housekeeping and set up pre-made blocks of text. Our horoscope generator's job will be to randomly pick from them.
2. We’ll program the horoscope generator to interact, or interface, with the user. At this stage, we'll use the command line, so we'll just assume the user is going to type something on the screen. (Later on, though, we could use some fancy APIs to tie our generator to messaging apps, or even to a voice assistant.)
3. As we mentioned, our program will generate the horoscope by randomly picking blocks of text and putting them together.
Make sure your Python environment is running (i.e., you have Anaconda or pure Python installed). Make a new text file, and save it as horoscope.py to a place that will be easy to reach by typing its location in the command line. For Windows, I’ll just save my text file to D:\projects\horoscope.py for easy access. If you have a Mac, it makes sense to create a folder in your home directory (alongside Desktop and Documents) and keep your Python projects there.
Now, let’s start coding.
This app will need to randomly pick blocks of text. For that, there is a Python library called ‘
random
,’ which I need to import:import random
Next up, let’s set up the library of pre-made blocks of text. For that, we can use Python lists. A list is basically a collection of stuff, and you can address any part of that stuff by knowing its sequential number. Lists in Python are very powerful, but let’s start with something simple:
first = ["Today is perfect for new endeavors. ", “The tensions of this week will feel heavier today than yesterday. ", "Today is the day to cherish and embrace others. ", "Making yourself useful is a main component of a successful day. ", "Today, exercise caution when crossing the street. ",]
second = ["Remember that good things come to those who work hard. ", "Don’t let the circumstances bring you down. ", "Patience is key, but sometimes a little push can get the job done. ", "A smile can get you a long way. "]
third = ["Looking ahead may seem like a waste of time, but it pays off in the end. ", "Luck favors those who mind the risks and take them. ", "Today is the day for that thing you always wanted to do. ", "Luck is on your side today, so seize it! ", "Things are looking up for you! "]
These three collections include lines of generic text that suit almost all situations. Look at how they are structured:
● There are three groups, each containing a bunch of sentences. We’ve given each group its own name.
● Each sentence is enclosed in quotation marks, which in Python, means ‘string’ (or text).
● To put many bits of text inside a collection, we’ve separated them with commas.
So, there you are: three collections of comma-separated strings.
The rules of our horoscope program are simple: you enter your zodiac sign, and in return, you get some recommendations. It doesn’t matter if these recommendations are actually based on your zodiac sign.
The main idea is that you first submit something and then get something in return. (If the horoscope generator just spat out recommendations without your prompt, that would break the rules of horoscopes, and I respect the game.)
So we need an interface to talk with the user.
By default, like most programming languages, Python interfaces with the user through the command line. This is the black screen with the white text you see when you open an app like Terminal which allows you to access your computer's operating system .
When you open Terminal, you can type text into the command line, and Python can respond with text. It’s not very user-friendly, but for now, it will do. In our next lesson, we’ll take our program to the instant messaging and voice app Telegram.
In Python, we use the command ‘
print
’ to write something to the user. Let’s use this code:print("1 — Aries")
print("2 — Taurus")
print("3 — Gemini")
print("4 — Cancer")
print("5 — Leo")
print("6 — Virgo")
print("7 — Libra")
print("8 — Scorpio")
print("9 — Sagittarius")
print("10 — Capricorn")
print("11 — Aquarius")
print("12 — Pisces")
Now, let’s ask for something from the user:
zodiac = int(input("Pick your sign by typing a number and pressing Enter: ")))
This line of code is interesting because it contains two commands, one nested in the other:
1.
zodiac = int(...)
takes what's inside the parentheses, converts it into an integer (that is, a whole number), and stores that number within a variable called ‘zodiac’2.
input("...")
outputs what's inside the quotes and asks the user to input some information. Once the user has input their information and pressed Enter, this command will return that information from the user to wherever it was called.Since these might be new topics, let’s talk briefly about calls and returns.
In programming, many processes involve calls and returns. I often ‘call’ functions and methods to do tasks, they do their tasks, and they ‘
return
’ the results. In this case, I’m calling the method input(“…”)
, and it’s going to return the information that the user enters.Here's the cool thing about calls and returns. You can do A; inside A, you can call B; and inside B, you can call C. So, C returns something to B, B processes that and returns the result to A, and then A does its thing.
For example, imagine you need to calculate a specific user’s income tax. To find out their income, you need to ask a database. To find out which user’s income to request from the database, you need to know their name or tax ID. Say, for this task, you have these functions to work with (assuming someone has already defined and written them):
askUserID()
queryDatabaseByID()
calculateTax()
One way we could accomplish the task is by writing this code:
userID = askUserID()
income = queryDatabaseByID(userID)
tax = calculateTax(income)
print(tax)
In these four lines, we used three blocks of memory to store the user‘s ID, the user’s income, and the resulting tax. This data sits in memory while the program runs.
That approach would make sense if we had to reuse this data for some other processes in our program—for example, to find out something else about this user from the database; or to use the user's income tax in some other calculation.
But if we only needed this data for one-time calculation, storing all this data and naming it would be too much of a hassle. A much simpler approach would be:
print( calculateTax( queryDatabaseByID( askUserID() ) ) )
In this line, all four things above happen one by one, as part of calling and returning. Print calls
calculateTax
, which calls queryDatabaseByID
, which calls UserID
. So, first UserID
returns some ID. Next, queryDatabaseByID
finds the income information for that ID in the database and returns the result to calculateTax
. Then, CalculateTax
receives the income, calculates the tax, and returns the tax to print. Finally, Print receives what it needed to print, and outputs the tax information to wherever it was designed to output.This kind of nesting and calling makes your code a little easier to write, but harder to read. So don’t overuse this approach.
Now back to programming our horoscope generator. At the moment, we have our source text and the astrological sign that the user has input. What more do we need?
To generate the horoscope, we’ve agreed to choose some random bits of text from our library and spit them out. We can do this with a simple line:
print(random.choice(first), random.choice(second), random.choice(second_add), random.choice(third))
Thanks to the beautiful Python library called ‘
random
,’ I can take advantage of a method called ‘choice
,’ which literally chooses a random existing item from a list or any other collection. To appreciate how neat this method is, consider this. In other languages, to make a random choice from an array, you need to:1. Find out whether that array contains items, and find out how many items are in it
2. Using a random number generator, generate a random number
3. Do the math to make sure your random number is within the range of how many items there are in your original array
4. Pick the random item
This could easily take three to seven lines of code, depending on the language. Now, all you have to do is call
random.choice()
and feed it some collection or array. And your code will return that random element.So, are we done? Nope, not yet.
See, earlier we asked the user to input a number for their zodiac sign. While this was a nice touch on our part, we never actually checked whether the user input that number. What if they input 99? What if they input 0? Although we are clearly cheating the user with these random horoscopes, we don’t want the user cheating us, so let’s check their input:
if 0 < zodiac < 13:
print(random.choice(first), random.choice(second), random.choice(second_add), random.choice(third))
else:
print("This does not correspond to a zodiac sign")
These lines simply check whether ‘
zodiac
’ is above zero and below 13, in which case the input is correct, and our program can output the mashup of text based on random.choice()
. If the user’s input is not a number or not between one and 12, then our program will generate an error and end.And now we’re done. The user can input their number and receive some feel-good advice to brighten their day. Here’s the final code, which you can expand as you wish:
first = ["Today is perfect for new endeavors. ", "The tensions of this week will feel heavier today than yesterday. ", "Today is the day to cherish and embrace others. ", "Making yourself useful is a main component of a successful day. ", "Today, exercise caution when crossing the street. ",]
second = ["Remember that good things come to those who work hard. ", "Don’t let the circumstances bring you down. ", "Patience is key, but sometimes a little push can get the job done. ", "A smile can get you a long way. "]
third = ["Looking ahead may seem like a waste of time, but it pays off in the end. ", "Luck favors those who mind the risks and take them. ", "Today is the day for that thing you always wanted to do. ", "Luck is on your side today, so seize it! ", "Things are looking up for you! "]
print("1 — Aries")
print("2 — Taurus")
print("3 — Gemini")
print("4 — Cancer")
print("5 — Leo")
print("6 — Virgo")
print("7 — Libra")
print("8 — Scorpio")
print("9 — Sagittarius")
print("10 — Capricorn")
print("11 — Aquarius")
print("12 — Pisces")
zodiac = int(input("Pick your sign by typing a number and pressing Enter: ")))
if 0 < zodiac < 13:
print(random.choice(first), random.choice(second), random.choice(second_add), random.choice(third))
else:
print("This does not correspond to a zodiac sign")
How could we improve this program? You may notice that most of our code is actually content (in this case, text). So it would be better to design this software with all the content in one file and all the logic in a different file. That way, we'd be able to update the content easily, even as the program is running.
We could also dramatically shorten the part of code where the program outputs the zodiac signs. That section of code could be around five lines instead of 12 if we used a loop, an element of programming languages that allows you to repeat specific actions .
But for such a simple task as generating a few horoscopes, the code we have now works just fine.
Up next: how to turn this horoscope generator into a Telegram service.
For even more lessons from expert developers, explore Practicum by Yandex, and advance your career in tech.