OceanofPDF - Com 12 Twisted Python Projects For Young Coders - Daniel Aldred
OceanofPDF - Com 12 Twisted Python Projects For Young Coders - Daniel Aldred
1. welcome
2. 1_Hello_GUI
3. 2_Are_you_funnier_than_a_hyena?
4. 3_Making_a_F.A.R.T._box,_a_disgusting_soundboard
5. 4_Photo_book:_Show_off_your_pics
6. 5_It’s_just_a_prank,_bro!
7. 6_Are_you_a_mind_reader?
8. 7_Is_your_password_secure?
9. Appendix_A._Installing_Python_on_Microsoft_Windows
10. Appendix_B._Installing_Python_on_other_operating_systems
11. Appendix_C._Installing_guizero_on_other_operating_systems_and_features_of_guiz
12. Appendix_D._Downloading_code_and_resources_from_GitHub
welcome
Thank you for your purchase of the MEAP for Twisted Python Projects! For
people who are new to Python, it's important to have fun while learning. I
understand that, and that’s why I’ve combined Python with guizero, a simple
program for creating apps, to bring you 12 twisted and entertaining projects.
From a joke machine to a fart soundboard, a number guessing game, a prank
quiz, a pixel painter, and more, each chapter covers everything you need to
know to build these fun and unusual apps. And don’t worry, there’s even a
sensible chapter where you’ll learn to build an app to check the security of
passwords.
Throughout the book, I guide you through each stage of the code, explaining
what it does and why we use it. Through a combination of diagrams, callouts,
graphics, and code listings, you’ll learn essential Python and guizero
programming skills. Plus, at the end of each chapter, you’ll find extra
challenges to make your app even more twisted, with all the code included
for you to experiment with.
With the skills you’ll learn, you’ll be able to create your own fun apps
beyond the ones presented in the book. Thank you again for your interest and
support. I’m excited to hear your feedback on the platform and look forward
to helping you become a twisted Python programmer!
In this book
welcome 1 Hello GUI 2 Are you funnier than a hyena? 3 Making a F.A.R.T.
box, a disgusting soundboard 4 Photo book: Show off your pics 5 It’s just a
prank, bro! 6 Are you a mind reader? 7 Is your password secure?
Appendix A. Installing Python on Microsoft Windows Appendix B. Installing
Python on other operating systems Appendix C. Installing guizero on other
operating systems and features of guizero Appendix D. Downloading code
and resources from GitHub
1 Hello GUI
Each chapter covers building a new GUI app with different features. When
you’re done with each project you can combine your new programming skills
and techniques from each chapter to create your own or new versions of the
GUIs.
Most of this book’s projects use the Microsoft Windows platform; however,
Python and guizero are compatible with Linux and Apple computers .
Appendix A covers installing Python on a Windows computer. Appendix B
covers how to install the required software on a Linux or Apple computer.
Python was created by Guido van Rossum as a side project and first appeared
in February 1991, which is a long time ago! When asked why his project was
called Python, Guido said that at the time he was reading scripts from a 1970s
BBC TV comedy program called Monty Python's Flying Circus. He needed a
short and memorable name for his new programming language and chose to
call it Python. Although Python has a funny name, it is used professionally
and used as a main language to teach coding in many schools and colleges
across the world.
In Python it is simply
print ("Hello World")
The advantage of Python code being so simple to write is that you are less
likely to make errors. Some programming languages require special
punctuation and spacing. Python still does, but it is less complex. However,
do not assume Python is a basic language. You can still create really
interesting and engaging GUIs as you will see throughout the chapters; it is
just that the Python code is easier to write than other programming languages.
If you already have Python installed, then you can move on to section 1.2.
Remember to check out appendix E, which covers commonly used Python
features and techniques. If you need to first install Python, then go to
Appendix A before reading 1. 2.
Once Python is installed, you can test that Python is working correctly by,
3. Press the Enter key on the keyboard and the program will print out the
message, I made a program.
An easier way to interact with your computer or device is to use graphics and
images; in short, a GUI. (figure 1.2). The Home Screen on your smartphone
is GUI, if you want to make a new folder using a GUI, you press the folder
icon. If you want to take a photo, you press the camera icon. This is a simpler
method of interaction and easier to remember rather than having to write the
code to create the folder or to take a picture. Icons are easier to remember and
use, and this is why GUIs are found everywhere, from Web Browsers,
ATMs, self-service checkout tills, GPS satnav, and so on.
There are other versions of GUI programs that work with Python, and you
can read more about these in the appendix D.
What is a function?
A function is a reusable block of code that can be called and used anywhere
within a program. Functions save time and make the program more efficient.
This means that you do not have to write the code from scratch; libraries save
you a lot of time and reduce your effort in writing programs, For example, a
library function can play a sound or display an image. At the time of writing
this book there are over 137,000 Python libraries. Let’s get started and install
guizero.
Installing guizero
There are several methods to install guizero and it has even been designed so
that you can download the files and make GUIs without installation. This is
useful if you are not permitted to download and install the software on the
computer. It means that you can just get started with the projects with no
need to install anything. Check out Appendix C which covers the guizero
easy install method. This section of the chapter covers how to install guizero
on a Windows computer. It assumes that you have already installed Python, if
you have not, then check out appendix A and follow the steps, then come
back here. If you are using an Apple, Linux or other computer, then head
over to Appendix B and follow the steps to install guizero on your computer.
To install guizero, we are going to use the command prompt and write a short
instruction to pull down the required program files. Before you start the
installation, ensure that you are connected to the Internet as you are going to
download the installation files.
Command Prompt
The command prompt app will load, and you will be presented with the
following window.
Now that you have the command window open, let’s install guizero. Type in
the following command, (a command can be thought of as an instruction, you
are writing an instruction for your computer to perform)
pip3 install guizero
This instruction tells your computer to use a program called pip3 to install the
guizero program. Press the Enter key on your keyboard to begin the
installation.
Pip3
Guizero will now install, taking a little time. Once complete, close the
command prompt.
Remember that this installation method only works if you have already
installed Python using the method in appendix A. You can also check out the
installation instructions on the main guizero webpage
https://lawsie.github.io/guizero/.
The second category is widgets, these are the main components of the GUI
and there are fifteen widgets that you can use in your GUI. For example, the
PushButton widget creates a button with a text label that can be clicked. The
ButtonGroup widget creates an option button where you can select from
several choices. You will use the widgets throughout the various projects, and
you can refer to appendix D for more details.
When writing each program, the code will always have four main sections
(figure 1.3). These sections break up the lines of code into organized and
manageable chunks. This organization will make it easier to check your
program for errors and will also make it easier when you wish to make edits
or changes. When you organize your code, good organization makes it easier
to find the code that you need.
An input is defined as one of two things. Firstly, an input can be a device that
is used to control the computer; for example, a mouse, a keyboard, and even a
gamepad is an input you can use to control your computer. The second
definition of an input is data or information that is put into program. One
example is when you log onto your computer, and it requires you to enter
your username and your password. You input your username and your
password into the software. Output refers to a device that is used to display
data or information. The most common output is a screen or monitor which
displays what a program is creating that is supposed to be visible; that’s
called a program’s output.
In this version of the hello world program, we are going to add an input in the
form of a text box that will enable you to enter your name or any name that
you want to. The GUI also features a Button that, when pressed, tells the
program to display a pop-up window that will say “hello” followed by your
name, as shown in figure 1.5.
Guizero modules
Guizero stores the modules in a folder called guizero. If you are interested,
you can open this web link
https://github.com/lawsie/guizero/tree/master/guizero and see the modules
and code for yourself. You will notice that the name of the file is the same
name of the module that you use when importing them. For example, the
PushButton module is named PushButton.py.
The module enables you to create the widgets (appendix D) that we can then
use in the program. Modules save us time and complexity. For example, the
PushButton module contains prewritten code to program features of the
buttons such as, the size of the button, the color of the button, what the button
does when pressed, the amount of padding around the button and more.
Lucky for us we can simply use the PushButton()function which is a single
word. Functions are so useful and efficient. You can find a list of all the
Elements and Widgets and what they do in appendix D.
In your Python program file, type the code shown in listing 1.1.
# Imports
Comments
A comment is a reminder or notice that tells you something about the code. A
little bit like a keep off the grass sign, it tells you what to do and which grass
to keep off! Comments start with the # symbol indicating something that the
program code will ignore or not execute.
which tells your Python program to go to the guizero library and then import
the modules listed in the same line. The modules used in the HelloWorld GUI
program and each of their purposes are,
App, used to create the main window that holds all the widgets
info, this displays a pop-up message window
PushButton, this creates a button that can be clicked
TextBox, is used to enable the user to enter text which can be used by
the program
Text, displays the title of the GUI
Creating the variables
The next stage in writing your program is to create the variables. A variable
is a location in the computer’s memory that stores data or information. The
data is only stored whilst the program is using it. When you close the
program, the data is forgotten. The content or value stored in the variable can
change; that is, it can vary.
Programs need to be able to find data quickly, so each variable you create
must be given a unique label. Think about how food in your house may be in
a jar or a box which has a label (figure 1.7). The label helps you to identify
what food is stored in the jar.
Figure 1.7 Labels on Jars are like variables; they tell you what is stored in each Jar
In a similar way, labeling a variable means the program can find the memory
location quickly and go straight there and collect the data.
You can label a variable almost anything that you want; however, it’s good
practice to use a name that represents what data is being stored in the
variable. For example, if the variable was storing the name of a person, then
you might label it persons_name. When creating the label for the variable, it
has no spaces between the words. Should you use spaces, then the variable
won’t work, and you’ll get an error message.
Constants
The opposite of a variable is a constant. Guess what, constants stay the same
and do not change. For example, Christmas Day is always on 25 December.
That makes it a constant. The present or gift that you get each year, is a
variable as it changes each year, unless you are over 50 years old, and then
you always get given socks!
In this program we are using some variables to create the widgets, the text,
the textbox, and the button. The code for these widgets is written in the #App
section of the program, so it makes sense to store these variables in the #App
section of the program. Although it will remain empty for this program, add
the #Variables comment to the program, as we will be using variables in the
chapter 3 and it is good practice.
A function is a reusable block of code that can be called and used at any point
in your program. Imagine you are playing your favorite computer game and
you are down to your last life; you can die or lose a life at any point in the
game. So potentially, there are millions of points during the game where it’s
game over and the game would end. If the game programmers didn’t use a
function, they would have to program the “game over” code millions of
times, once for every scenario where you lose your last life. This would be
very tedious and make the program’s code massive. Instead, developers use a
flag, which is triggered when the game is over. The flag informs the program
to run the game over function.
Using a function, listing 1.2 means the developers can write the “game over”
code once and then when the game ends, the program calls the function, and
it runs. You only need to write the block of code once, then you can use it as
many times as you like, which saves processing power and makes the
program more efficient.
# Functions
def Hello():
info("Welcome", "Hello " + textbox.value + ", you just made your first G
The line of code in listing 1.2 looks long and has a lot of elements, so let’s
break it down. To create a function in Python, you use the keyword def,
which indicates to the Python program that it should expect a function to
follow. Then you give the function a name and type it in. In our program, the
function is called Hello(). The name Hello is used to call the function,
calling means that the program runs the function when a particular action is
performed by the user. In this program the function is called when a button is
pressed.
Using suitable function names will also help other programmers that look at
your code, understand how the program works. It also makes error checking
easier. For example, if the error is in the function, Python will inform you of
the error and you can easily find the relevant area of your code. You can find
the function in your code without having to check every line for the error.
Python will inform you where it found the error; it will display a message
something along the lines of
SyntaxError: invalid syntax. Perhaps you forgot a comma in the function Hell
A syntax error indicates that the way the code has been written does not
follow the required Python structure rules. In some ways, syntax is like
grammar. For example, Thor from the Avengers owns a hammer, which only
he and several other characters have ever been worthy enough to lift. (Do you
know who they are?) The correct grammar or syntax for referring to that
hammer is “Thor’s Hammer.” That is, you use an apostrophe to indicate that
the hammer belongs to Thor. The incorrect syntax is Thors Hammer, which
implies that there is more than one Thor. You can read more about types of
errors in Python code in appendix E.
A function ends with (): which is the syntax that Python uses to indicate
that anything in the next section of the code belongs to the function. You may
have noticed that the line of code under the function name is slightly indented
to the right. To get the amount of indentation correct you can press the TAB
key once or the spacebar four times. Ensure that you always use the same
amount of indentation throughout your program.
By indenting the lines of code (see figure 1.8), you tell the program which
lines to include within the function, and to only include these lines. So how
does the function know what the last line of code in the function is?
The last line of code and the end of the function is indicated when the next
fully left-aligned line of code appears in the program. Now that you have
created the function and you know what it does and why we are using it, you
can add the function’s contents. The first part
info()
tells Python to create and display an information message box (figure 1.9).
Figure 1.9 An information pop-up
The information box pops up when you press the “click me” button (which
we will code in the next section) and combines the name that you enter into
the text box and the string, “Hello” to create a final message (figure 1.10).
Digits and numbers can also be a string, for example, “C3P0” is a string.
Now you might say that this is the name of the droid that you are looking for,
therefore it uses letters and numbers, similar to a car registration plate or your
zip / post code. A car license plate or a postal code are both created with
letters and numbers. However, a list of digits or a number can be a string; for
example, this number “221” is a string because the numbers are enclosed
within quotes. However, the number has no value. It is not two hundred and
twenty-one, it is simply the symbols 2, 2, and 1.
If you look again at code listing 1.2, you will see the strings being added
together,
"Hello " + textbox.value + ", you just made your first GUI")
The first variable labelled, app, creates the main window of your GUI.
The second, text, holds the instruction that tells you what to do (the
instruction tells you to enter your name).
The third variable, textbox, stores the data to create the text box and
also stores the name that you enter into the text box.
The final variable, button, holds the information about the button.
# App
The first line of the code creates the GUI window and positions the name
“Hello World” at the top left of the window. You can name the GUI window
differently if you wish; just ensure that you enclose the name in quotes
because, yes, you have guessed it, this is a string. The App is the main
window which contains all the other widgets. You will notice in line two that
the word app also appears:
Text(app, text="Enter your name")
This is because we use the app object to edit and add content to the main GUI
window. (There is also a Box object that works in a similar way to the App;
you can add and edit content. A box is usually held within an App. You will
come across boxes in chapter 3 when you make a FART soundboard!) An
object can be thought of as a way to define the properties and features, so the
app object enables you to set the properties, say the size and color of the app
window.
The second line creates and displays a line of text with the instruction to
“Enter your name”. Notice that it uses app after the Text(). This tells the
program where to display the text; in this case, to display the text in the App
window. The third line is responsible for creating the text box where you
enter your name.
Next, on line 4, add the code to create the button. You need to tell guizero
which function you want the button call, (which function to run) when it is
clicked (figure 1.12). Notice here that, confusingly, the function is called a
command. When you create a function like you did in section 1.2.3, it is
called a function. When you write code in guizero to call or run this function
then you use the code, command = . Finally, you need to tell the program to
display all the elements that you have just coded. To do so, simply add the
line app.display()to the end of the program.
So, let’s try to run the program. Press F5 on the keyboard. (If your keyboard
does not have function keys then, at the top of the IDLE window click, Run
and select Run Module from the drop down menu. You may be prompted to
save the program file (figure 1.13). Choose OK and the program will save,
and then the program will run. Fingers crossed!
If your program fails or does not run as expected check for these common
errors:
# Imports
# Variables
# Functions
def Hello():
[CA] info("Welcome", "Hello " + textbox.value + ", you just made your fi
# App
app = App("Hello World")
text = Text(app, text="Enter your name")
textbox = TextBox(app, width=20)
button = PushButton(app, command=Hello, text="Click me")
app.display()
where bg is short for background. The line of code is saying “make the
background color equal to red.” In the App section of the program, locate the
first line where you named the GUI, "Hello World". Add the additional code
to the line, bg = "red".
app = App("Hello World", bg ="red")
Press F5 on the keyboard to save and run the program. The background will
now be red. There are many colors that you can choose from. Check out this
website, https://wiki.tcl-
lang.org/page/Color+Names%2C+running%2C+all+screens, which lists the
names of each of the colors. Try some out.
In the last change to the program, edit the function so that a warn window is
displayed instead of the info window (figure 1.14). The warn pop-up window
has an image of a yellow warning sign. It is often used in GUIs to grab the
user’s attention and warn them that an event is about to happen. To make this
edit, change the word info to warn on the line of code held in the Function,
def Hello():
app.warn("Welcome", "Hello " + textbox.value + ", you just made your fir
# Imports
# Variables
# Functions
def Hello():
[CA] app.warn("Welcome", "Hello " + textbox.value + ", you just made you
# App
Conclusions
In this chapter you have created your first GUI. This project is important as it
has introduced you to some of guizero’s basic features. In this chapter you
were introduced to the programming language Python. This language is a
popular language amongst developers and can be used to create websites,
games, perform data analysis and much more. You can download the chapter
code here:
https://github.com/TeCoEd/Twisted_Python_Projects/tree/main/Project_Codes
If you are new to Python, you can read more about the features of the
language in appendix E before you start your next project. Or just jump
straight in. Have fun!
Statements of fact
Guizero is a package that is installed and enables programmers to easily
create GUIs using the Python programming language.
Widgets are the guizero name for the elements or items that appear on
the GUI. Widgets enable you to interact with the GUI.
Functions are reusable blocks of code that can be called and used
anywhere within a program. Functions save time and make the program
more efficient.
A module is a library of code that contains a set of pre-built functions.
Modules are imported at the start of a program.
A variable is a location in the computer’s memory which stores
information and data.
A string consists of either text, numbers or characters enclosed within
quotation marks. Strings can be stored and combined together to create a
longer string. Numbers that are strings are valueless.
Popups are message boxes that appear on your screen. Programmers use
pop-ups to display information.
The App windows holds all the elements and widgets of the GUI.
A PushButton is a pressable button. Programmers assign functions to a
button; when the button is pressed, the program calls and runs the
function.
2 Are you funnier than a hyena?
In this chapter, since laughter is the best medicine, you will build a Joke
Machine (figure 2.1) to spread laughter all around. The Joke Machine
consists of a simple button which, when pressed, will display a random joke.
Don’t like the joke? Not a problem. Simply press the button again and a new
joke will be displayed. As people tell you or you hear more jokes, you can
collect them and add them to your Joke Machine so that it always makes
people laugh. You will need four jokes to start with for this project, you can
use the ones in this chapter and if you hear any good ones, write them down
so that you can use them in this project.
While building the project you will learn the skills shown in table 2.1,
including the random function, which is used to select a random item from a
list. Choosing random items is a common feature of games such as Minecraft
where the game world is randomly generated. A staple method of most user
interaction with a device, from mobile phones, smart TVs even washing
machines is via buttons. This project covers how to set up and add interaction
to a push button, this is a visual button in the GUI that you interact with to
make something happen. You press the button, and the joke is displayed on
the screen. Text is used everywhere, and this project covers how to display
and edit text.
Let’s begin to build the Joke Machine. The project consists of several steps,
which are shown in figure 2.2. Follow the steps in order.
You are also going to create a list. Lists are a useful method of holding more
than one item in a single variable. We will go into more detail about lists later
in this section. For this program, you will use the list to store the jokes and
assign them to a variable.
Open a new Python program file in your editor. Refer to chapter 1 and
appendix A for a reminder about editors. From the File menu,
1. Choose File > New File. Your Python editor will prompt you to save the
file.
2. Save the file with the name Joke_Machine.py and choose Save.
Remember
(as with the previous projects, if you used the guizero quick install method
from Appendix C then you must ensure that you save the file into the same
folder as the guizero.)
Begin the Joke Machine program code by importing the required modules
(listing 2.1) from the guizero library. (You installed this library in chapter 1.)
The modules provide all the code you need to create the various elements and
widgets of your GUI.
This program also uses the random module which is imported from the
Python program. This module is used to select a random joke from the list.
This is instead of always displaying the jokes in the same order each time the
program runs. It would be unfunny if you always already knew the joke and
its punchline.
Your list of jokes is stored in a variable with the label list_of_jokes. You
may recall from chapter 1 that the label cannot have spaces in between the
words, but it’s hard to read words when they’re crammed together without
spaces. To solve this, you can join the words using underbars (_). The
variable list_of_jokes is easier to read than listofjokes.
A variable is a location in the computer’s memory that stores the jokes. The
label or name of the variable references the location in the memory location
so the information can be accessed quickly by the program. The Joke
Machine program needs to be able to find the memory location where the
jokes are stored, so you name or label the location so the program can quickly
go straight there and collect your jokes. Write up and add the code below in
listing 2.2, underneath your imports.
# Variables
list_of_jokes = ["What do you call a man with no shins? Tony (Toe – Knee)",
"Nothing begins with N and ends with G",
"What kind of tree can fit in one hand? Palm tree",
“[CA]”"Why do owls not go dating in the rain? Because it’s t
print (list_of_jokes)
On the last line, the code print(list_of_jokes) is used to test that your
program is working correctly. Without the final GUI window, this is good
developer practice, testing parts of your program and small sections of the
code to catch any problems early on. Press F5 on the keyboard to save and
run your program; you should see all your jokes displayed in a long line in
the window of the Python editor, as shown in figure 2.5. When you have
tested the program, change the last line of code to #print (list_of_jokes),
this will stop it printing out all the jokes.
If your program fails or does not run as expected, check for these common
errors:
Imagine you are playing your favorite computer game and you are down to
your last life; you can lose your final life at any point in the game. So
potentially, there are millions of points during the game where it’s game
over. Most games contain a “game over” animation where the game character
dies, faints, falls over, melts, dissolves, and even flashes. If the game
developers didn’t use a function, they would have to program the ”game
over” animation code millions of times, once for every possible scenario
where you lose your last life. This would be very tedious and make the
program code massive.
You only need to write the block of code once (figure 2.6), then you can use
it as many times as you like, which saves processing power and makes the
program more efficient.
Figure 2.6 Creating a function to select a random joke from the list
The function in the Joke Machine program will be assigned to a button in the
GUI, which when pressed, will call the function and then run the code to
select a random joke. This happens every time the button is pressed. Figure
2.7 shows the flow of the function on the left side, and on the right, what the
outcome is in the program.
def select_joke(): #A
random_joke = random.randrange(0,len(list_of_jokes)) #B
joke_message = list_of_jokes[random_joke]
joke_to_display.value = joke_message #C
A function begins with the text def, which stands for define. This tells
Python that you are creating or defining a new function. Then you must name
the function so that you can call it by its name and reuse it. (If you have a
dog, it has a name; usually when you call their name, they come up to you!
Not all the time. Likewise with cats! But functions must come every time that
you call them) The function in the Joke Machine program is called
select_joke(): as its purpose is to select a joke from the list. Note the use
of the (): at the end of the function, you must use this syntax, so Python
knows that you are creating a function.
The next line of code selects a random item. In this program, the random item
is a random joke from the list. Consider the image in figure 2.8 of a shopping
list (in the style of a Python list) and number each of the items starting from
zero to the end. The first item, milk, would be numbered 0, then butter
numbered, 1, then meat 2, rice 3, and so on. The line of code uses
random.randrange which means a random selection within the range, and
you may know from maths that a range is from the first number to the last
number in a list. You can read more about the random module on the official
Python website, (https://docs.python.org/3/library/random.html)
In the example of the shopping list, our first item on the list is milk and the
last item, an onion. The position of the onion is eighth, so the range of the
shopping list, is 0 to 8. Now, you need to tell the program what the range of
the list of jokes is so that it knows the total number of jokes in the list and can
select a position that exists in the list. (Basically positions 9 and above do not
exist and the program would fail). Finding the start of the list is simple as it
starts at zero, it starts at the beginning. You then set the end of the range as
three since we have 4 jokes and joke 0, joke 1, joke 2 and joke 3 will give us
four positions to hold each individual joke.
However, what happens if you add more jokes? That would mean you would
have to change the range. For example, if you add 8 jokes you would need to
change the end of the range to 7. If you forget to do this, the program will
never display the new jokes as it is unaware of their existence! (figure 2.9).
The solution is to instead, use the code len(list_of_jokes) which finds and
returns the length of a list with any number of items stored in it. The len()
function, short for length, enables the program to find the length or the end of
the variable called list of jokes that we created in listing 2.2. So, this line of
code is basically looking up how many jokes you have stored in the list and
then returning the end value of the range.
Figure 2.9 How the program selects a random number from a list of any length
Since the program knows the length of the list, it can then use the
random.randrange to select a random joke from your list of jokes. This is a
prewritten function from the Python random module included within Python.
The function consists of code that can select a random number from a range
of numbers defined by the user, in the similar way that you can roll a
standard die and it will land on one of six numbers.
Note that at this stage the program is only returning the position of the item,
not the actual joke. This position value is then stored in a variable named
random_joke.
So now the variable random_joke holds a random position number from the
list of jokes (note that this is just the number of the item and not the physical
text of the joke). In order to extract or collect the joke that will be displayed,
use the code
joke_message = list_of_jokes[random_joke]
The last line of code assigns the joke, as a string, to a new variable
joke_to_display.value = joke_message so that the computer can pass the
joke to the GUI and display it. The term “passing” describes the process of
taking the joke that is stored in the computer’s memory and making it
available for the program to display it as text in the GUI window. You will
see that this code uses .value at the end of the variable, this tells the program
that the data the variable holds will be updated with a value (a joke). You will
see how this works later after listing 2.4.
The .value code is responsible for replacing the existing joke. What this
means is that each time the program calls the select_joke() function, it
overwrites the current joke with a new joke. A different joke is displayed.
If the value was not updated, then all the previous jokes would still be
displayed, and there would be a long list of jokes cluttering up the GUI
window. Note that this variable, joke_to_display.value, currently has no
value as the program has not run and the function has not been called.
Therefore this variable is empty.
Now you are ready to create the App section of your program (listing 2.4).
The App section brings together all the features into a GUI.
The first line of code names your GUI. The name will appear at the top left of
the GUI window. Then you can set the GUI’s height and width. You may
need to change these values depending on the length of your jokes. If you
have chosen longer jokes, then you may need the GUI window to be wider.
Next, we set the background color of the GUI to white. You can change the
color by replacing the word White with the color that you want the
background to change to. Simply replace White with the word Green, to
change the background to the color green.
Then display the title of the program in your GUI and set the size of the text.
You can change this if you want to call your Joke Machine something else,
like “Ha Joke Teller!” Simply replace the text but remember to use the " ".
Finally, set the font (what the text looks like) to Impact. You do this using
this line of code:
title_text.font = "Impact"
You put the name of the font you want use between the quotation marks. The
fonts that you can use depends on which Operating System you are using
and, which additional fonts you have installed.
# App
The last part of your program code adds the button, which, when pressed,
will run the function from listing 2.3. When the function runs, it displays a
random joke from the list.
Start by creating a variable which will hold the code instructions to create the
button. In listing 2.5, the command= tells the program which function to run—
the function that you created. The code basically says that when the button is
pressed, run the function called select_joke.
Lastly, add the text that you want to display on the button. Something simple
like “Tell me a joke” provides the user with an instruction about what the
button does when it is pressed.
If you look at listing 2.3, you see the last line of code uses the variable
joke_to_display.value. This variable holds the joke that is going to be
displayed. However, the program needs to firstly be expecting a joke.
Imagine you invite six friends round to your house, and an extra friend turns
up. So, there are now seven friends, not six. You were not expecting them, so
you don’t have a chair for them to sit on. Now as a kind human you would
share or maybe give up your chair for the extra person. However, alas
computers are machines and would not.
They follow exactly what the program instructions ask them to do, computers
cannot adapt to deal with unexpected or additional requirements. So, in the
computer world, if a seventh friend turned up and the computer was
expecting six, then this would cause an error as the program was not
expecting it.
In the program we can create a list of six jokes, but creating the jokes is not
the same as telling the program to expect a joke. You have to program in the
expectation!
To solve this issue, we create the joke_to_display variable, and use the
Text command so that the program knows that it will be holding a string,
because it is going to display the joke as text. Next set the text to empty/blank
using two quotation marks with nothing in between them, like this "". This
means that when the program runs, the variable is storing an empty string.
The line of code is basically getting a chair ready for when your friend
arrives. They are not seated in the chair until they arrive; however, you still
get the chair ready for them. You can think of this line of code as creating a
placeholder for the joke. It must be blank at the beginning of the program
because the joke is only displayed when the button is pressed.
The final line of code simply tells your program to display the GUI when you
run it. Copy the lines of code from listing 2.5 into your program.
Well done. You have now completed the Joke Machine. Press F5 to save and
run your program and have a giggle! If the program doesn’t run, check out
the troubleshooting section.
# Imports
# Variables
list_of_jokes = ["What do you call a man with no shins? Tony (Toe – Knee)",
"Nothing begins with N and ends with G",
"What kind of tree can fit in one hand? Palm tree",
"Why do owls not go dating in the rain? Because it’s too we
print (list_of_jokes)
# Functions
def select_joke():
random_joke = random.randrange(0,len(list_of_jokes)) # selects a random
joke_message = list_of_jokes[random_joke] # selects the text of the joke
joke_to_display.value = joke_message
# App
app.display()
Imagine if you were listening to music and every time you wanted to change
to a different song it required you to firstly stop the song you're listening to,
locate the new song you want to listen to, load that song, and press play.
(This is how listening vinyl records works.) It would be frustrating and time
consuming.
Instead what happens is the software is automated. You simply click the
songs or playlist you want to listen to, and the program automatically plays
through the songs.
To automate your Joke Machine, you are going to add a line of code that
makes the program repeat itself. A program or a section of a code that repeats
is called iteration. An iteration is used to run a part of the program repeatedly
as long as a given condition is met. In the Joke Machine, the condition is that
the set time between jokes has passed.
CONFUSING TERMS
Often the terms loop or looping and repeat are used to denote the use of
iteration.
app.display()
This line of code is very simple and consists of a repeat function to instruct
the program to repeat the function called select_joke. Then you tell the
program how often you want it to repeat the function. In listing 2.7, the repeat
time is set to 1000. This means that the repeat time is set to 1000
milliseconds, so the function runs every second. The Joke Machine
automatically will display a new joke every second, this is probably too fast
as it will not give you time to read the joke. The joke may also be very funny,
and it makes you laugh a lot. By the time you have finished your laughing fit
you will have missed maybe 20 other jokes. However, one second is a
suitable time period for testing to observe that the program is working
correctly.
The program uses milliseconds to store the time so you will need to be able to
convert seconds into milliseconds. You need to calculate the milliseconds
before you add them to your program code. Use the simple formula shown
below,
However, you will also have to covert minutes into seconds which uses the
following formula,
Seconds = minutes * 60
Let’s look at an example, if you want your Joke Machine to display a new
random joke every 5 minutes, then you would calculate the required number
of milliseconds as follows,
5 minutes is 5 * 60 seconds,
this is a total of 300 seconds
300 * 1000 is 300,000
For your convenience, table 2.2 provides the time in minutes, seconds, and
milliseconds of common time intervals.
Once you have added the extra line of code and decided on your time
interval, press F5 on the keyboard to save and run your program. (It’s always
useful to set the time interval to 1000 at first, so that you can test the code is
working correctly). Congratulations, you now have an automated Joke
Telling Machine but, the real question is are your jokes funnier than a
Hyena?
The jokes will be displayed automatically without you having to press the
button. However, the button is still there and if you want a new joke, you can
still press the button to display different joke. The timer is independent of the
button, so if you press the button, it may be that the joke changes straight
away as the timer has expired.
You can also change the style of font by adding this line of code after the line
of code that changes the color:
joke_to_display.font = "fontname"
Replacing the name of font with the name of the font that you want to use.
The fonts that are available depends on which operating system you are
using. Why not try one of the following, “Arial”, “Impact” or “Verdana”.
There are so many funny pictures that it seems a shame not to display one in
your GUI. You can choose a meme if you like.
Start by saving the image file that you want to display, into the same folder
where the GUI code is stored. Remember that the file needs to be either a
PNG or a GIF. Also select a small picture so that it fits into the GUI window.
Next, in the # Import section of the code add the Picture import to the end
of the list. This imports the code that enables the program to display images.
from guizero import App, Text, PushButton, Picture
Then in the #App section of the program, underneath the line of code,
joke_to_display = Text(app, text = "") and before
app.display()insert the following line to display your picture,
Replace the name of file with the file name of your picture and ensure you
have the correct file type, either a .gif or .png. Save your program and run it.
You may notice that despite using a small image it does not fit neatly into the
GUI window, figure 2.12. This is easy to resolve.
You may find that you need to experiment to find a suitable set of width and
height values. Figure 2.13.
# Imports
# Functions
def select_joke():
random_joke = random.randrange(0,len(list_of_jokes)) # selects a random
joke_message = list_of_jokes[random_joke] # selects the text of the joke
joke_to_display.value = joke_message
# App
app.display()
Statements of fact
A variable is a location in the computer’s memory which stores
information and data. You create variables and use them to store data
and strings.
A list is a type of variable that can store more than one item. You create
lists when you want to store more than one item in a location.
Iteration is repeating or looping parts of the program. You use iteration
to tell the program to repeat part of, or to automate parts of, the code.
Iteration reduces the amount of human input required.
When testing programs that use time, pauses and delays, it is always
useful to initially set the time interval to 1000 milliseconds, so that you
can test the code is working correctly.
3 Making a F.A.R.T. box, a
disgusting soundboard
Using layouts
Making pushbuttons
Assign sounds to Pushbuttons and playing audio
Creating functions
Trumps, bottom burps, gas, pump noises are funny and make most people
laugh. Farts have an amazing habit of being able to distract anyone hearing
one, especially if they are playing an online game. So, in this project we will
build a fun GUI that combines a selection of fart noises to create a Fluff
Audio Resonance Transmission (F.A.R.T.) sound board.
In this chapter you will build a F.A.R.T. Box soundboard (figure 3.1). This
soundboard is a GUI with seven buttons. When the user presses a button, the
app plays a fart sound. Press a different button and it plays a different fart
sound. The last button closes the soundboard.
However, if you prefer, you can collect your own sound clips and make your
own soundboard; for example, cat meows, famous quotes from a TV show,
and so on. The program code and the process are still the same; you just
replace the sound clips with your own audio.
https://github.com/TeCoEd/Twisted_Python_Projects/tree/main/Project_Codes
Or you can collect your own audio files. These sound files need to be .wav
(waveform) audio file format, as this file format is compatible with the
Python module that we are using to play sound. More detail on this later, in
the paragraph after we import the modules in the listing 3.1.
The project has six buttons. Therefore, the project requires six fart sounds.
The soundboard also has an exit button which, when pressed, closes the GUI
window, but not before leaving you with the sound of a loud burp! The GUI
also displays a suitably related image file, of a poo, that is 160 pixels wide
and 180 pixels high. The image will be displayed in the GUI window.
Guizero uses .png and .gif file formats, so make sure that your file has the
correct format. If working on an Apple computer, macOS only supports the
GIF file format.
Let’s begin to build the F.A.R.T sound board. The project consists of several
steps which are shown in figure 3.2. The main steps of the project are to
1. Download the collection of audio files of the fart noises and the image .
2. Create a new folder, then copy and store the audio files in this folder.
3. Start a new Python file and import the required modules.
4. Code six versions of a function that will each play one of the audio files
when a corresponding button is pressed.
5. Create a function to exit the soundboard once you have had enough of
all the fart noises.
6. Create the main GUI window to hold the title, image, and buttons.
7. Create the required buttons.
8. Save and test the soundboard
9. Turn up the volume, press a button and make a fart sound!
Figure 3.2 Flow diagram of the building the Fluff Audio Resonance Transmission (F.A.R.T.)
soundboard
You are now ready to write the program code and create your disgusting or
not so disgusting soundboard.
# Imports
You may recognize the PushButton and Text modules from chapter 1. These
modules import the prewritten code to display text and create a button that
you can push. In this GUI, we also use the Picture module to add a picture
to the GUI. The Box object operates as an invisible container that holds the
buttons and creates an ordered layout.
Next, we import the winsound module. This module is included in the Python
installation files and provides basic access to the software in Windows OS
that plays sound. You can read more about the features of winsound here,
https://docs.python.org/3/library/winsound.html. (If you are using a macOS
or Linux, then refer to the section on the last few pages of this chapter for
information about a compatible audio module.) Save your program before
you move on.
This program has no discrete variables, however, there are variables that
create objects that hold the related code for the title, the image and the
pushbuttons, so we will write them in the #App section of the program.
Therefore, the variable section in this project is left blank. You may recall
from chapter 1 that a variable is a location in the computer’s memory that
stores data or information.
# Functions
def fart_1():
winsound.PlaySound("Farts/fart1.wav", winsound.SND_ASYNC)
def fart_2():
winsound.PlaySound("Farts/fart2.wav", winsound.SND_ASYNC)
def fart_3():
winsound.PlaySound("Farts/fart3.wav", winsound.SND_ASYNC)
def fart_4():
winsound.PlaySound("Farts/fart4.wav", winsound.SND_ASYNC)
def fart_5():
winsound.PlaySound("Farts/fart5.wav", winsound.SND_ASYNC)
def fart_6():
winsound.PlaySound("Farts/fart6.wav", winsound.SND_ASYNC)
Each of the six functions use the same code but with a different function
name and audio file name. You just need to remember to update the number
used in the name of the function and update the name of the sound file.
REMEMBER
If you have a different folder name other than Farts/ to store your sound
files, then you must replace the Farts/ folder name with the name of your
folder.
If you used a different file naming structure for your audio clips, then
you need to use these names instead, replacing, for example, fart1.wav
with your file’s name.
If you are using Linux or a MacOS look at the section on the last few
pages of this chapter which covers how to code the sound.
def exit():
winsound.PlaySound("Farts/burp.wav", winsound.SND_ASYNC)
app.destroy()
The GUI interface allows the user to interact with the soundboard. It consists
of
This code adds the text to the top left corner of the GUI window.
In this section of the program, we are going to display the name of the GUI
which is ‘F.A.R.T Box’ at the top of the window. This title will grab the
user’s attention and tempt them to press one of the buttons. We also need to
set the size of the app window. The reason for setting the size of the app
window is because the soundboard only has seven small buttons and a small
image. Therefore, it does not require a large window, which would make it
look bad and be a waste of screen space. Imagine drawing a small two
centimetre by two centimetre picture on
These values are measured in pixels. We are going to set the size of the
soundboard GUI to 350 x 400 pixels, that is a width of 350 pixels and a
height of 400 pixels. The code that sets the size is included after the App
window’s title. It does not matter whether you put the width or the height
value first, line 1 in listing 3.4. Add the code from listing 3.4.
What is a pixel?
# App
On the second line of code you will notice the connection between the color
of poo and the background of the F.A.R.T. soundboard. Yep it’s the
background color of the GUI. The last line of code in listing 3.4 uses the code
app.bg = "saddle brown", like in chapter 1, to change the color to saddle
brown.
You have many color choices to use. The names and shades are all available
on this website: https://wiki.tcl-
lang.org/page/Color+Names%2C+running%2C+all+screens. Why not try out
some other colors? But remember to keep them a shade of brown so that the
color is related to the theme of the project.
When creating the label for a variable, you can use more than one word, but
if you do so, ensure that it has no spaces between the words. If you add
spaces, then the variable will not work, and Python will present you with an
error message when the program runs. To add the title and the image, type
the code from listing 3.5 into your program.
The first line of code in listing 3.5 declares the variable. Declaring is the
proper name for creating and labeling a variable in a program. This variable
has the label, title_text, which is assigned the Text widget. With this
widget, we can add text to the GUI window. After the variable is created, the
contents of the variable tell Python where to display the text. The word ‘app’
references the app window that you made in listing 3.4. So, the code is saying
“display the title in the main GUI window; that is, the app window.”
On the second line, the code uses .text_size to set the size of the text. In
this program, we set the size to 28, which makes it stand out and grab the
viewers’ attention. If you are creating your own soundboard, you can alter the
text size as required.
Next, we set the font style of the text, using the font function
title_text.font = "Impact" where the font style is Impact. The font
styles that you can choose depends on which operating system you are using
and which fonts you like using.
The first line of code in listing 3.5 tells Python where to display the text, and
in a similar way, the last line of code tells Python where to display the picture
assigning the image to the app window. We declare a variable labelled
poo_picture = Picture, which assigns the Picture widget to the variable.
The final part of this line of code (image = "poo.gif") is the name of the
image file.
The image dimensions are 160 pixels wide and 180 pixels high. If you decide
to use your own image and replace the project image then ensure that it is a
similar size to ensure that the picture fits within he app window. (You can
alter the size of the GUI window to hold a larger image).
REMEMBER
Figure 3.6 Layouts when using and not using the Box object.
In this project we will create and use a Box to hold the six buttons that when
pressed, will each trigger their corresponding functions and play a fart audio
clip, figure 3.7. This means that the buttons are grouped together, and they
are easy to arrange into a neat and tidy order. Add the code in listing 3.7; it
starts with a variable labelled box. By now you will be noticing that variables
are a staple part of programming.
Figure 3.7 Code to create and configure the Box within the app window
Then we add the code to configure the box. The first word, app, shows that
the box is part of the app window. Then we set the size of the Box like you
previously did in listing 3.4, where we set the width and height of the GUI
window. Here we are setting the width and height of the box, which you will
notice is smaller than the app window. This is so the box fits neatly inside the
App window.
In chapter 1, when we added the widgets, we simply added them to the GUI
and the program automatically took care of laying them out. In this project,
we want to control the layout, so we use a feature called grid layout and add
it to the box variable using the code
layout = "grid"
This layout offers more control over where the buttons are displayed. With
the grid layout, you can position widgets into a virtual grid inside the box.
Imagine dividing the box into equally sized blocks, and then using an x and y
value to locate one of the grids, in a similar way that you do when you play
battleships or if you have ever used a cell reference in a spreadsheet to locate
a specific cell. At school, math teachers used to have a phrase to remember
the order of the x and y coordinates as “along the corridor and then up the
stairs,” where the x value is first and horizontal (along the corridor), and the y
value is second and represents to vertical values (up the stairs).
The grid layout uses an x and y value (the x and y are called a coordinate) to
place the button in a specific location in the box. For example, button 1 has
the following coordinate, [0, 0], where the first 0 is the x value and the
second 0 is the y value. This coordinate places the first button in the first line
in the box and on the left. Figure 3.8. Where it can be confusing is that [0,0]
is located at the top left-hand side of the grid and not the bottom left-hand
side as with graphs.
The essential feature of the code is the command, which is passed to the
PushButton widget and is used to call one of the functions from listing 3.2.
The called function then plays the fart audio clip. Commands make it
possible for the user to interact with the GUI; for example, when you press
the button, the command calls the function which makes the GUI respond
creating interaction. In the chapter 1 GUI, the command made the GUI say
Hello to you. In other chapters, a command will make it possible for you to
draw. In this chapter, the commands are linked to
In chapter 1 we gave the button a label so that the user knows what it does.
Do the same thing here and label the button with fart 1. You can label the
button with any text, so you could use the name of the fart sound instead? For
example, you could label one of the buttons, ‘squeaker’ or ‘loud and proud’,
‘silent and deadly’ or how about, ‘Trump’. Then use the grid code to align
the button’s layout (figure 3.9).
Do not worry if the program fails the first time. With a longer program, it is
likely that you will have some errors. Commonly, errors are syntax errors. A
syntax error is like a grammar error, only more serious. With human
language, people can generally understand you even if you made grammatical
mistakes. Programming languages, such as Python, expect you to use proper
syntax for the program to work correctly.
Press F5 on the keyboard. Python prompts you to save the program file.
Choose OK. The program will save, and then the program will run, and the
F.A.R.T. GUI soundboard will be ready. The GUI should display the title, the
poo related image, and only one button, which when pressed plays fart sound
clip 1.
If your program fails or does not run as expected, check for these common
errors:
Once the program is working, you can then delete the app.display() from
the last line and then add the additional buttons from listing 3.8.
The last stage of the program is to add the code that creates a button that
when pressed closes the disgusting soundboard. This is important, as the user
may have had enough of the fart sounds and want to leave! Also, it is good
GUI practice to include a method to cleanly close the GUI. In chapter 1, to
leave the ‘Hello GUI’ program, you chose the x in the top right corner of the
GUI window. This used the standard close a window feature built into the
Windows OS. Creating a dedicated close or exit button means that you can
customize it. Add the final code from listing 3.9 to your program code.
You will notice that the code for the close_button is the same code that we
used in listing 3.7 where we created the buttons to trigger the audio clips. In
listing 3.9, we use the variable close_button to store the information related
to the button including which function to run when the button is pressed. The
button appears in the box, so the element box, is included after the first
bracket.
Next, assign the exit function that you created to the command using the line
command = exit. This tells the button to run the function that closes the GUI
when the user presses it. Then we name the button. Here we have called it
Exit. Lastly, use the grid alignment to display the button in the middle of the
very last line, underneath the other buttons.
The next line of code changes the color of the button to red, so that the user
can see that it is not an audio clip. Also, the color red acts as a warning that if
they press the button something else will happen, the program will stop
running and the GUI will close. Finally, on the last line you add the code
app.display() to run the GUI window.
# Imports
# Variables
# Functions
def fart_1():
winsound.PlaySound("Farts/fart1.wav", winsound.SND_ASYNC)
def fart_2():
winsound.PlaySound("Farts/fart2.wav", winsound.SND_ASYNC)
def fart_3():
winsound.PlaySound("Farts/fart3.wav", winsound.SND_ASYNC)
def fart_4():
winsound.PlaySound("Farts/fart4.wav", winsound.SND_ASYNC)
def fart_5():
winsound.PlaySound("Farts/fart5.wav", winsound.SND_ASYNC)
def fart_6():
winsound.PlaySound("Farts/fart6.wav", winsound.SND_ASYNC)
def exit():
winsound.PlaySound("Farts/burp.wav", winsound.SND_ASYNC)
app.destroy()
# App
# Fart buttons
box = Box(app, height = "200", width = "350", layout = "grid")
One easy edit to make is to change the color of the buttons. For example, you
could color code the audio buttons in terms of, the browner the color the
more bombastic the fart noise is! This would make it easier for the user to
know which buttons would make a louder fart. For example, a lighter shade
of brown could be a squeaky fart, but the dark brown is loud. Coloring the
buttons is also a useful feature for future projects.
To edit the color, you simple create a new variable in the App section with
the same name as the button variable, then use .bg= color followed by the
color you want to use. For example, the first button is labeled fart_button1,
so the code to change the color of this button is
fart_button1.bg = "sienna"
I recommend that you add the line of code for the color underneath the code
for the buttons. This will make it easier to keep track of.
fart_button1 = PushButton(box, command=fart_1, text='fart 1', grid=[0,0])
fart_button1.bg = "sienna"
If you can’t get enough of the fart sounds, or your soundboard requires many
more buttons, then you can add more buttons. This involves three stages:
1. Collect or make the additional audio sound files that you want to use in
your GUI. Ensure that these files are .wav and save them into the correct
folder. (In this project the folder is named Farts.)
2. Create a new function for each of the additional sound files. This uses
the same code structure used in listing 3.2. In the #Function section of
the program, add the new Function, remember to use a different name
for the Functions and change the filename of the new sound clip, shown
in italics below.
def fart_1():
winsound.PlaySound("Farts/fart1.wav", winsound.SND_ASYNC)
3. Add the code to trigger the additional button. In the #App section under
the last button, which was fart_button6, add a new line and type in the
code for the new button:
fart_button7 = PushButton(box, command=fart_7, text='fart 7', grid=[2,1])
Remember to change the name of the button and link the command to the
new function. You will also need to update the grid numbers. Otherwise,
when the program runs, Python will try to create two buttons in the same
place. To make the new buttons fit, you may need to extend the height of the
box that holds the button. Do this by adjusting the width value (shown in
bold) in this line of code:
box = Box(app, width = "400", height = "200", layout = "grid").
Statements of fact
A package is a collection of different Python modules.
The Text() object displays text that cannot be edited while the GUI is
running. It is useful for titles, labels, and instructions.
Objects are a bundling of variables and functions so they work as a
single unit.
The Picture() object displays images in the GUI. The default file
formats are .GIF and .PNG. macOS only supports GIF format.
Commands add interactivity between the user and the GUI interface.
A window is the main app window of the GUI. It holds the parts of the
GUI, widgets, text, and buttons.
A Box is an invisible container that, like a window, can hold widgets,
text, and buttons. Editing a Box does not edit the main GUI window.
A grid layout uses an X and Y coordinate to position a widget in a
precise location within the GUI.
INSTALLATION
Wait for the program to download and install, and you are ready to make
disgusting FART sounds, well, your GUI is! The program code, as the name
suggests, is simple to use, first you import the audio module using the line,
import simpleaudio as sa. Then you create an instance of the audio file
and assign it to a variable.
You can now control when the sound plays using the code, play_obj =
wave_obj.play(). The program needs to wait for the sound to play through
before moving to the next line of code, to do this use the code
play_obj.wait_done()
# Imports
# Variables
# Functions
def fart_1():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart1.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def fart_2():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart2.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def fart_3():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart3.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def fart_4():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart4.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def fart_5():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart5.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def fart_6():
wave_obj = sa.WaveObject.from_wave_file("Farts/fart6.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
def exit():
wave_obj = sa.WaveObject.from_wave_file("Farts/burp.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
app.destroy()
# App
# Fart buttons
box = Box(app, height = "200", width = "350", layout = "grid")
app.display()
4 Photo book: Show off your pics
The year 2016 was a significant year, do you know why? The number of
photos taken in 2016 exceeded the total amount of photos ever taken in the
history of taking photos! Just let that sink in for a moment. More photos were
taken in 2016 than in the whole time between 1830 (when the first official
photograph was taken) and 2015, a period of 185 years! (The Online
Photographer)
Taking photos has become an everyday feature of our lives, even to the point
where some people say, “if you didn’t take a picture of it, it never happened!”
This has led to a rise in fake news where images are manipulated or used out
of context to make the reader believe that something happened, or never
happened, or happened in a different way to how it really happened!
The data around photos is interesting. Here are some facts from
Photutorial.com (https://photutorial.com/photos-statistics/)
Photos are taken everywhere now, and there is no indication that the number
taken is likely to slow down at any point. However, what is odd is that many
people do not look at their photos. The image files simply stay housed on
their smartphone or transferred to their computer, where they are stored and
never looked at.
In the 1990s and even early 2000s, the use of a photo album was quite
popular. You would print out your favorite photos, or memories as they were
often referred to, and then stick them into a book called a photo album. Then,
under each photo you added a suitable caption like “A sunny day at the
beach, with lots of ice-cream.” You would flick through the book and share
the photos and stories with friends and family members.
Since the average phone user has around 1,500 or more photos on their phone
and never really looks at them, we are going to build our own Instagram style
digital photo viewer called Photo Book (figure 4.1).
The program that we will code will enable the GUI to automatically pull the
photos from a folder on your computer. This means that if you want to
change the photos or add more photos, you just move the new photos into the
folder, without changing the code. It is that easy. You don’t even have to
change the file names, which saves time. Want to make a Photo Book for a
party? Copy your party photos over to the folder. How about a Photo Book of
your pet? All you need to do is copy over your favorite photos of your pet to
the folder. Each time you run the GUI the program will automatically pull in
your new images and create your new Photo Book.
Let’s begin to build the Photo Book. The project consists of several steps
which are shown in figure 4.2. The main steps of the project are to
To download the images, open your web browser and enter the address,
https://github.com/TeCoEd/Twisted_Python_Projects/tree/main/Project_Codes
If you are using your own images then ensure that they have the file
extension .gif, else the picture will not be displayed. This is because by
default guizero supports and displays gif image files on all operating systems.
Windows and Linux also support .PNG files. To use images saved as JPEG
file format we will need to first install some additional software. This is
covered later on in the chapter, (in the three other things to try section) once
we have built the Photo Book GUI.
1. Move to the folder where you are saving your GUI programs.
2. Create a new folder.
3. Name the folder Photo_Book_Images, you can use a different name,
but you must remember to change the file name in the main program
code so that it matches.
4. Drag and drop or copy over your edited images / photos into the
Photo_Book_Images folder.
1. Choose File > New File. Your Python editor will prompt you to save the
file.
2. Name the file with the name Photo_Book.py and choose Save.
Begin the program code by importing the required modules (listing 4.1) from
the guizero library.
Listing 4.1 Importing the modules
So, what is glob? It sounds kind of slimy! Well, you will be pleased to hear
or maybe disappointed that glob has nothing to do with slime. The glob
module is really useful for finding the photos that we want to display in the
Photo Book.
When using pictures in guizero, the image file will have the file extension
.gif. The file extension .gif is an example of a file pattern that we can use
with glob to find the image files. When glob is looking for files, it only looks
for files that end in.gif and we can use this to find and make a list of the
names of the files that match the required pattern.
Glob is short for global, and is a module, (you may recall that a module is
code or really a function that is prewritten and you can use it straight away)
built into Python for finding files that match a particular file extension.
In the Photo Book GUI, we need a variable to keep track of which photo is
being displayed, figure 4.3. A variable is a location in memory that holds or
stores a piece of data. This data is usually a number or text, and you guessed
it, when the program is running the variable can change. Therefore, you need
to label the variable with a suitable name so that you, well your program, can
easily find it again. This is known in computing as declaring a variable, it is a
little like knighting someone. I declare you Sir Photo Number a lot! It helps
the coder and also the program code to know where to find and hold data.
Figure 4.3 The GUI can display any photo, so the variable needs to track which file is currently
stored.
What will be new to you is that there are two types of variables, a local and a
global variable. In most homes you will probably find a framed photo that is
either hanging on a wall or above the fireplace or placed on a shelf. The
photo may even be pinned to the fridge. This photo is often a picture of a pet
or embarrassing cringy family photos. This photo can only be seen when you
are in the house; you cannot see the photo when you are next door, or in the
car, or on holiday. This is like the local variable; it is only accessible within a
specific part of a program.
Here is another example. Consider going to the cinema, once you enter the
lobby, you can buy a ticket for any film. When you have bought your ticket
you go and watch that specific film and only that film. You must be in screen
6 to watch the film, you cannot watch any other films. This is like the local
variable; it is only accessible within a specific part of a program.
Alternatively, when you are at the cinema you could buy a weekly pass
ticket, this allows you to watch any film that you want at any time, there are
no restrictions, all the films are accessible. This is like the global variable
which can be accessed by any part of the program.
A global variable (nothing to do with glob which is the module that finds
files with certain names) is accessible by any part of the program. This is like
the photos that are available on your social media feed; anyone can access
them from any location in the world. The same is true of the global variable:
any part of the program can access the contents of that variable.
Listing 4.2 Declaring the variables
# Variables
global photo_number
photo_number = 0
This program only has one main variable, photo_number that holds
information about which image is currently being displayed in the app
window. The variable holds the current image number from a list of numbers
representing each image file. It is a similar concept to the list of jokes in
Chapter 2 where the program keeps track of the joke by the position that the
joke is located in, in the joke list. You will be relieved to hear that in the
program we will use the glob module to automatically build the list, rather
than you having to create it manually.
Numbering in Python always starts from zero. The first item in the list is
stored in position zero.
1. The forward() function. When you press the button, this function is
called and moves the photo onto the next one. Basically, it moves you
through the images stored in the folder and displays each photo.
2. The back()function, moves you back through the previous photos when
you press the back button.
3. The exit() function closes the Photo Book GUI app.
Functions 1 and 2 keep track of the current photo being displayed and also
keep track of either the next or the previous image to display. Each function
also must keep track of the total number of image files there are in the folder.
If you have six photos, then the function needs to know when it has reached
the end of the list of photos and then say, “hey I need to go back to the
beginning of the list and display the first one again”. The function then
displays the first photo in the list. Function 2 also needs to do this and check
if it has reached the beginning of the list of photos, it tracks which number
photo is being displayed and then display the previous photo when the button
is pressed.
To make things easier and understandable let’s break down a function and
how it works in more detail. The first four lines of the function are simply,
def forward():
global photo_number
global photo
photo.destroy()
First, we define the function by naming it forward():. That was nice and
easy. Next, we need to bring in the variables, first, the number of the photo
(photo_number) and then next, the variable to hold the information about the
photo in the variable aptly named, photo. This is a new variable and will hold
all the information about the photo. This variable needs to be global so that
the program can update the image file number so that the correct photo is
displayed when the user presses either the Previous or Next button. If the
variable was a local variable only available in the def forward(): function
and not a global variable, then the number of the image file currently being
displayed would not be updated correctly when the Previous button was
pressed. This means that the photo order would be incorrect and the user
would not experience ‘scrolling’ through the Photos.
The last line of code calls the destroy function to destroy the information
about photo. This might seem odd and a little dramatic! Why destroy the
photo? Well, the destroy function is not really deleting the image file from
the folder, it is removing the image from the GUI window. The reason for
this is because if you do not remove the current photo from the GUI, it will
continue to be displayed even when a new image is loaded. This means we
will soon end up with a stack of photos on top of each other!
The remaining section of the function is the part that moves the picture
forward, figure 4.5. First, we tell Python which photo we want the GUI to
display. This requires us to use the photo variable that we just created, to
hold this information and combine it with the Picture() object to display the
image.
On the first line the function adds 1 to the photo_number, this is because the
user has pressed the Next button and wants to see the next image in the list.
This new value is then divided by the total number of images in the list.
(Currently 6 images.) So, the line of code calculates 1 ÷ 6 which equals 0.16
however, you will have noticed that the division symbol used is %. In Python
this symbol performs a modulo division which means that the calculation
returns the remainder of the calculation.
Modulo division
The modulo operator, % returns the remainder after one number is divided by
another. This is known as the modulus of the operation. Take two positive
numbers 12 and 3, a modulo 3 (12 % 3 ) returns 0 as 3 goes into 12 exactly 4
times. However, 12 % 7 returns 5 as 7 goes into 12 once and leaves 5
remaining (12 – 7). Often in math the term is abbreviated to mod, for
example 12 mod 7.
The last line of code tells the GUI which image to display. The value stored
in the photo_number variable that we calculated in previous line with the
modulo division, is combined with the image_file_names list, which holds
the list of images, figure 4.6, which selects a position in the list of image
files. (We will create the contents of this list later in chapter, in the # App
section of the program where we build the GUI.)
Then we use this code and combine it with the Picture() object, to display
the image. We also include app, in the photo variable to state where the
photo will be displayed, (the image is displayed in the app window!).
So, what happens when the user selects the last photo in the list and the
function gets to the end of the list? Well, the Photo Book needs to return to
the first item in the list, the image file that is stored in position zero.
# Functions
def forward():
global photo_number
global photo
photo.destroy() #A
photo_number = (photo_number + 1) % len(image_file_names) #B
photo = Picture(app, image=image_file_names[photo_number]) #C
Before moving on, let’s walk through the stages of the function one more
time.
Now to create the back() function, which does the opposite of the forward()
function. When the Previous button is pressed it displays the previous photo
in the list. These two functions enable the user to scroll back and forth
through the images. Type up listing 4.4.
def back():
global photo_number
global photo
photo.destroy()
photo_number = (photo_number - 1) % len(image_file_names) #A
photo = Picture(app, image=image_file_names[photo_number]) #B
This function begins with the same variables as the forward() function. Then
it uses modulo division, which hopefully makes more sense now that you
understand how the forward() works, to select the image number. The code
is the same except for this time we are subtracting 1 from the photo_number.
In the previous function we added one to move forward, this function
subtracts one, so the previous image in the list is selected and displayed.
Let’s walk through process of this function.
1. The user presses the Previous button which calls the back()function.
2. The function pulls in global photo_number and takes current value
stored in the variable; for example 3. (Image 4 is currently being
displayed)
3. The global photo variable is pulled in.
4. The current photo is removed from the GUI, meaning the image on the
display is cleared and the photo variable is empty. There is no
information stored about a photo.
5. The photo_number value is decreased by one, (becomes 2) and then
divided by the number of the images in the image list (6) using modulo
division, (2 % 6 = 2) which will select the second item in the list.
6. The image=image_file_names[photo_number] combines the
photo_number which displays the third photo in the list. Remember lists
start from 0 so item 2 is image number 3. Figure 4.6.
7. The previous code is combined with Picture() and assigned to the
variable photo which displays the new image.
One of the challenges when writing longer functions is ensuring that the
indentation levels are correct and match. Indenting refers to the use of white
space before the text, which means the text starts a little distance award from
the left hand margin.
white space
In coding, white space is the term used to describe the space on the left hand
side of your line of code that is not taken up by code or characters. It is useful
for organizing your code and telling the program which lines of code belong
to various sections.
After you create a function, the lines of code that follow underneath, are
indented. This is so Python knows which lines of code are part of the
function. To use the correct amount of indentation you can press the TAB
key on your keyboard once (or the spacebar four times) this moves the cursor
across to the right about 1 cm, so that when you start typing the text it is
indented. You can see the first line of the function ends with a colon :, when
you type in a : and press the enter button, usually your Python editor will
move to the new line underneath the previous and automatically indent it.
Always ensure that you always use the same amount of indentation
throughout your program. Check that your indentation is the correct level
before moving on (figure 4.8).
You will be pleased to know that the last function is much simpler than the
previous two. It consists of just two lines of code and is assigned to a button,
which when pressed closes the Photo Book GUI. Add the code in listing 4.5.
def exit():
app.destroy()
This section of the program needs to find your photos and make them
available for the Python program to use and display in your GUI. Look at
listing 4.6, the first line of code uses the glob module to find the image files.
This line consists of creating a variable to store the image files that the glob
finds. Then we use the code, f for f in glob.glob which basically means
“for the files in the list of files that glob found”, and then you must tell glob
where to look for the files, to return a list of file names and store them in the
variable.
Just like looking for a book in a library, you need to know the area to look in
and the type of book, the author and usually the title of the book. When using
glob, we need to provide it with two pieces of information. Firstly, we need
to tell it which folder to look in (the one we made at the start of the chapter to
store the images in, Photo_Book_Images) and secondary, the type of files to
look for, *.gif. Figure 4.9.
Figure 4.9 The glob code to find a build a list of image files
The * Symbol
The * symbol tells glob to look for any file that ends with the file extension
.gif. For example, glob would find cat.gif and mydog.gif but it would not find
mydog.jpg because the file type is .jpg, which we have not told glob to search
for.
As the program is looking specifically for a file type, it means we don’t have
to worry about the naming convention used on the files. Glob is always
watching and will find the image files. To add the glob code, type the code in
listing 4.6.
# App
image_file_names = [f for f in glob.glob("Photo_Book_Images/*.gif")]
As with the previous GUIs, at this stage we now configure the size of the
window and add the name of the Photo Book. This follows the same steps as
we have used before in previous chapters. First define the size using the
width and height values. Then add the title of the app, this appears in the
main GUI window. In this project we also add a catchy subtitle, to interest
the users and tell them the theme of the photos that are displayed. Photos
could be of cats, friends, places, trees, food and so on. Add the code from
listing 4.7.
You may recall from previous chapters that when setting the width and
height, the line of code still runs the same if you define the order, height and
width. You can use an alternative name rather than Photo Book simply
replace the title with your preferred text.
Now to add the images and create the navigation buttons. These buttons
enable us to control the Photo Book, moving forward or backwards through
the photos and, a button to close the Photo Book. As with all previous
buttons, we link one of the functions to the button using the command = code,
followed by the name of the function that we want to run when the button is
clicked. For example, the back_button is linked to the back() function,
which displays the previous photo in the list. Add the code from listing 4.8.
app.display()
Listing 4.8 begins with the code to display the first photo when the GUI
loads. We need to tell the program which photo to display because the image
files in your folder will all have different names. This is because the program
does not know what each reader’s image files are called and therefore when
the GUI runs, no image will be displayed until the first button is pressed, so
the GUI window will be empty when the program loads. (All the image
displaying is handled by the forward() and backward()functions).
To solve the issue, we use the code
image=image_file_names[photo_number] where photo_number = 0, (from
when we previously declared it in the # Variables section). When the
program runs it pulls out the photo which is stored in position 0 in the
image_file_names[] list and displays it.
The code for the three buttons uses the standard button code. If you have
already completed other GUI projects, then you will be familiar with the
code. First create a variable to hold the code for the button. Assign the button
to the app window and use the command= to assign a function to the button.
Give the button a label and then use the align= code to place the button
either on the left, the right or the middle of the main GUI window. Finally
add the code to display the app when the program is running. Save your
program code.
Button location
When you first run the program, you may wonder why the three buttons
appear at the bottom of the GUI. This is due to the method that guizero uses
to stack the GUI elements in the order that they appear. Once you click either
the Previous or the Next button, the button placement will change to the
sides.
1. Check that the filename and file path are both correct, are the image files
stored in the correct place, have you used the correct filename for glob
to find?
2. Are the image files the correct type? They should be .gif.
3. Indentation is important and can often lead to errors. Are the levels of
indentation correct in the program? Either one TAB key or 4 spacebars.
4. Does the indentation remain the same throughout the program code?
5. When creating the buttons, have you used the same function name in the
command?
6. Have you used the correct case? Some syntax has capital letters in the
middle of a word. For example, App, Picture, PushButton.
7. Did you spell all the words correctly?
8. Check the final code listing below.
# Imports
# Variables
# Functions
def forward():
global photo_number
global photo
photo.destroy()
photo_number = (photo_number + 1) % len(image_file_names)
photo = Picture(app, image=image_file_names[photo_number])
def back():
global photo_number
global photo
photo.destroy()
photo_number = (photo_number - 1) % len(image_file_names)
photo = Picture(app, image=image_file_names[photo_number])
def exit():
app.destroy()
# App
image_file_names = [f for f in glob.glob("Photo_Book_Images/*.gif")]
app.display()
So, you can use .png files in your Photo Book but you will need to ensure
that the image file is a .png file format. You also need to change the code so
that it searches for .png files, for example change the line of code from
image_file_names = [f for f in glob.glob("Photo_Book_Images/*.gif")]
to
image_file_names = [f for f in glob.glob("Photo_Book_Images/*.png")]
The Python Imaging Library (PIL) adds additional image processing powers
to Python. However, this library is no longer maintained and has been
transferred to a new library named Pillow. This means that we can use Pillow
to display more image file types in the Photo Book. This is useful as the most
common image file type is JPEG. Most images taken with your smartphone
camera are saved as JPG, many images on websites are JPEG too. Pillow
supports the following image files: GIF, Animated GIF, BMP, ICO, PNG,
JPG, TIF. This means that you can use the images that you have taken with
your smartphone and use them in your Photo Book. These images will need
editing as they are rather large, to edit them see Appendix E Editing your
images, which covers using your own images section at the end which covers
how to resize the images.
Smartphone Cameras
Most cameras and smartphones save image files in the JPEG format. These
files are a compressed version of the image file that when saved, takes up less
storage space than the original image. Depending on the type of compression
used, the quality of the image can be reduced, usually this is negligible and
cannot be detected by the human eye.
If you are using Linux then you can install Pillow using the same process,
first open the terminal window and enter the command, install pip3
pillow. Press enter to install.
One way to find out what image file types are supported by your computer is
to create a Python program to check. Open a new Python file and enter the
code:
from guizero import system_config print(system_config.supported_image_types)
then save the file and run it. Python will print out a list of the supported
image file types. Similar to the output below,
>>> from guizero import system_config
>>> print(system_config.supported_image_types)
['GIF', 'Animated GIF', 'BMP', 'ICO', 'PNG', 'JPG', 'TIF']]
Upgrading guizero
If you installed guizero using pip, then you can upgrade guizero in the
terminal window using the commands in table 4.3.
To change the color of the other buttons, use the same line of code, just
change the name of button variable and the color you would like to see
displayed.
There are several stages to follow to add this feature to your program, we will
need to:
Since you already have a working version of the Photo Book, we don’t want
to overwrite the original program and lose it. Saving the file with a new name
means that you will not overwrite your original program code; whatever
happens, you will still have your original Photo Book. Begin by saving the
file with a new file name. With your original Photo Book program,
Photo_Book.py, open in Python,
Now we import the Operating System (OS) module. This module enables you
to write code that controls features in Windows OS, which means that you
can use it to trigger the print function of the OS to load. The module is part of
Python which means that if you have a Linux operating system and use
import os, then it will enable you to control the features of the Linux OS
through Python code.
At the top of your program, under the #Imports section which contains the
guizero and glob modules, add the following line of code,
from guizero import App, Picture, PushButton, Text
import glob
import os
Save the file before moving onto the next section, select the menu option,
File > Save.
Now to create the function that will print the current photo that is displayed
in the GUI window. In your program find the #Function heading, then on a
new line underneath the last function, the exit() function, add the code in
listing 4.10.
def print_to_paper(): #A
global photo_number #B
photo = image_file_names[photo_number] #C
os.startfile(photo, "print") #D
Next, we pull in the global variable photo_number into the function. Global
functions are accessible by any part of the program and enables the function
to know which number image is currently being displayed. Then we use the
value stored in photo_number to locate the image file in the list of images.
To access and print these files, you need to use this folder location so that it
can be accessed by the OS. Basically, you are telling Python where the
photos are stored and where to find them. This is relatively easy to do as we
just need to find the full file path name of where the currently displayed
image is stored.
A file path is like a house address that tells the program the exact location
where a particular file is stored. Similar to an address, if you miss a line, then
it is difficult to find the house, the same applies with the file paths. If you
omit part of the file path, then the program cannot locate the folder or the
files.
The good news is that Windows OS provides a simple method to ensure that
you get the correct file path, and the full file path, figure 4.12.
1. First, open the folder that contains all of your image files, this will be,
Photo_Book_Images or your folder may have a different name.
2. In the address bar at the top, (which displays the file path) right click
anywhere on the address.
3. A menu will load, select the Copy address as text option from the list.
This will copy the full and correct file path for the folder that contains your
images, for example,
O:\OneDrive\ManningBooks\CODE\draftcode\Photo_Book_Images
Your file path will be different from the one displayed above as you will
have stored your image files in your own unique location, although you will
recognize the Photo_Book_Images at the end of the text.
Head back to the Python program and find the line of code where glob
searches for the gif images and builds a list of the image names,
image_file_names = [f for f in glob.glob("Photo_Book_Images/*.gif")]
Where you replace the underlined code with your own unique file path. Note
that in Python the file path is separated with forward slashes, so if you copy
and paste the file address you will need to change these. Ensure that all the
backslashes \ are changed to forward slashes /.
This new line of code is the same as we used in the previous version of the
Photo_Book.py except that this time we are providing a different file address
or location for glob to search for the image files in. Remember to replace the
file path with your own unique file path.
Remember that the file path is unique to your computer and depends on
which folders you have created and where they are saved. The
O:/OneDrive/ManningBooks/CODE/draftcode is an example.
File paths or addresses can be quite tricky to work with and you may be
presented with a red error message if the path is incorrect. In Python this
message often appears unrelated to the address. The message usually
displayed is, IndexError: list index out of range.
If you get this error message it means that the program cannot load an image
because it hasn’t built a list of them. It cannot build a list because it cannot
find the images, as the file path is incorrect. Recheck the file path that you are
using and compare it with the correct example code below,
[CA] = [f for f in glob.glob("O:/OneDrive/Manning Books/CODE/draft code/Phot
The code for this button is the same as the previous buttons. First create a
variable to hold the code for the button. Assign the button to the app window
and use the command to assign a function to the button. Give the button a label
and then use the align= code to place the button at the top of the GUI
window. Save your program and then press F5 to run it. As with the previous
Photo_Book GUI, the first time the program runs all the buttons will initially
appear at the bottom of the window. They will rearrange on your first click.
Use the forward button to move through the images, when you are on the
image that you want to print, press the print button, it will trigger the print
option window to open up and you can adjust the settings before printing
(figure 4.13).
# Variables
# Functions
def forward():
global photo_number
global photo
photo.destroy()
photo_number = (photo_number + 1) % len(image_file_names)
photo = Picture(app, image=image_file_names[photo_number])
def back():
global photo_number
global photo
photo.destroy()
photo_number = (photo_number - 1) % len(image_file_names)
photo = Picture(app, image=image_file_names[photo_number])
def exit():
app.destroy()
def print_to_paper():
global photo_number
photo = image_file_names[photo_number]
print(photo)
os.startfile(photo, "print")
# App
app.display()
Statements of fact
The glob module enables Python to find and access files that are saved
on your computer.
A variable is a location in the computer’s memory which stores
information and data.
Global variables are variables that hold data which can be accessed in
any part of the program.
Modulo division uses the % operator and returns the remainder of a
division calculation.
Indentation is the number of spaces at the beginning of a line of code.
Indentation in Python programs is used to indicate a block of code, for
example, the code that is part of a function and code that is not.
The OS module contains functions to enable Python code to control
features of the Operating System such as managing files and folders,
opening software and printing.
The os.startfile() command opens a file with an associated program.
Using startfile on a word document will open the file with MS Word, the
associated program
5 It’s just a prank, bro!
Rick Astley is a famous English singer who has a popular song called “Never
Gonna Give You Up.” In May 2007, during an online chat, a user uploaded
and shared the song to troll the other users. This began a trend of people
sending a file to other people pretending it was something else, when
actually, it was the song, “Never Gonna Give You Up.”
For example, you receive a message along the lines of “open this photo of
your brother falling over.” When you open the file it plays the song. This
prank is known as being Rickrolled, or Rickrolling. Rick has said that even
he has been Rickrolled by his own song. He was sent an email from someone
claiming to have met him backstage at a concert when they were 12.
However, the prankster posted a link to the song instead of a picture of the
meeting.
If you want to learn more about the prank, click here:
https://www.youtube.com/watch?v=dQw4w9WgXcQ.
Figure 5.1 A prank quiz, looks like a simple quiz, but it Rickrolls the player.
In this chapter you will build a quiz, figure 5.1. However, this quiz is a fake
quiz. It only has one question and two answers. It does not matter which
answer the player (I will call them a player as they think that they are playing
a quiz) selects, they are both wrong and will trigger a Rickroll. Later you can
edit the program and make it into your own version, such as a jump scare, the
quiz button triggers a scary sound and then a picture appears, or a happy
birthday prank, plays happy birthday.
The GUI will change color, display an image of Rick and most importantly,
play the song, “Never Gonna Give You Up”. The following happens:
When using audio with guizero you need to ensure that the file is stored in
the same folder that you have saved the Python program file in.
To do this, let’s begin by opening the folder where you are saving your GUI
projects,
You are now ready to write the program code and create the fake quiz.
# Imports
The first set of modules on line one will be familiar, we have used them so
far in all the previous projects. The modules enable you to create the GUI
window, add text, buttons, and images. Line two introduces a new feature
from the random module, import choice.
In chapter two we used the random module to select a random joke from a list
of jokes. Each joke was assigned a number based on its position in the list,
for example, joke0, joke1, joke2 and so on. The random module was used to
select a random number which told the program the number of the joke to
display.
In this project we are going to use from random import choice. The choice
allows Python to select a random item from a list. This method is more
efficient since each item is going to be a single word, rather than a long joke
containing lots of words.
We will use the choice to change the background color of the GUI to a
random color each time that the player is pranked (they are Rickrolled). This
makes the prank colorful, eye catching and fun. We create a list of colors and
then use random choice to select a random color from the list. This color is
then set as the background color.
On the third line we import the time module. This is the first time that we
have seen the time module and it allows us to control time. Well, sort of. We
can use the line of code time.sleep(2) to add a two-second delay before the
picture of Rick is displayed in the GUI. This delay is purely artistic so that
the person you prank hears the intro drums, and then as the main song kicks
in, is presented with Rick’s happy face. (If you know the song, you will know
it makes sense!) The last module that we will use is winsound, which is
included in the Python installation files and provides basic access to the
software in Windows OS that plays sound.
If you are using a Linux or Mac OS then you will need to use the alternative
sound module used in Chapter 3, simpleaudio
https://pypi.org/project/simpleaudio/. The full code listing can be found in
listing 5.10.
To do this we create a new variable called colors, and then add the names of
the colors that you want to use, into a list. For example, to add the color
yellow, simply add it to the list, "yellow”; to add white, do the same thing,
"white".
Variables
A variable is a location in the computer’s memory that our Python code can
access. In this memory location, we are storing the names of the colors. In
order to make it easy to find the location we label the variable: colors, so
that the program can find the location.
You can add as many colors as you want to, and this website has a list of the
names of all the colors that you can use with guizero and Python:
https://wiki.tcl-lang.org/page/Color+Names%2C+running%2C+all+screens.
There are easily well over one hundred names, so you will be able to pick the
ones that you like. Under the import lines of code, add the code in listing 5.2
and select your colors.
# Variables
1. The Never Gonna Give You Up audio file is loaded and starts playing.
2. The background changes to a random color.
3. There is a 2 second pause.
4. An image of Rick Ashley is displayed.
5. The title changes to, “YOU GOT RICK ROLLED”.
6. The Score changes to, “Your current score = ricked”.
7. The second function ricked_again() loads and asks you if you want to
be pranked again, then responds to the player’s choice.
When you create the function, you need to ensure that you use the correct
indentation. The colon symbol : at the end of a line of code means that the
next line of code will be indented. Most Python editors will automatically
indent the next line of code when the previous line ends with a : symbol. One
of the challenges when writing longer functions is ensuring that the
indentation levels are correct and match.
Indentation reminder
Indenting refers to the use of white space before the code, which means the
text starts a little distance away from the left-hand margin. Indentation is used
so that Python knows which lines of code are part of a function, and which
lines are not and belong to the rest of the program.
# Functions
def prank_me_play_music(): #A
winsound.PlaySound("Rick.wav", winsound.SND_ASYNC) #B
app.bg = choice(colors)#C
sleep(2)#D
rick_pic = Picture(app, image="rick_dance.gif") #E
When writing any function, we start on the first line by defining the name of
the function so that it can be called and used elsewhere in the program. This
function is defined as def prank_me_play_music(): as its name reflects the
fact that the function runs when you prank the player and music plays.
The winsound module allows Python to use the Windows sound functions to
play audio clips.
The third line of code manages the background color. The function choice()
makes a random choice from the list of colors held in the colors variable
from listing 5.2. The program then sets the background to that color. For
example, if the random choice is yellow, it will change the background of the
GUI window to yellow. The background change is simply part of the prank.
Then, we program In a short pause of 2 seconds using sleep(2) before
displaying the image of Rick using Picture().
Next, we use the Text() widget to set a caption at the top of the GUI that
displays, “YOU GOT RICK ROLLED”, and make the font bigger using the
line of code, title_text.text_size = 18. This makes the caption stand
out telling the player that they have been Rickrolled!
answer_grid
The answer_grid is a variable that holds the information about where the
answer buttons will be displayed in the GUI window.
On the last line of the function, we call the second function, which we will
write in the next section. The second function is called ricked_again() and
asks the player if they want to be pranked again. If they select yes, then the
prank_me_play_music(): is called and runs again and the user is pranked
again. If they select no, then the GUI closes.
For example, in this game the player is asked if they want to be Rick Rolled
again, they can respond with Yes (True) or No (False). If they select Yes then
the prank repeats and plays again, if they select No, then the GUI closes. You
have seen and used conditionals when you enter a password to log into a
computer(see figure 5.6)
Remember
The person writing the code must write both the condition and the responses.
The program only knows how to respond because we have told it how to.
Figure 5.6 How a condition and selection are used to check a user password.
In this function, if the player selects Yes, (True) then the condition is met,
and a the prank_me_play_music() function is called to run the prank again.
Should the player select the No option (False), then the condition is not met,
and the program responds differently using app.destroy()to close the GUI.
def ricked_again(): #A
prank_again = app.yesno("Rick Rolled", "Want to be Rick Rolled again?")
if prank_again == True: #C
app.info("Rick says", "Never gonna give you up!") #D
prank_me_play_music() #E
else: #F
app.error("Rick says", "I let you down...") #G
app.destroy() #H
In Python, = means has a value of. It is used with variables, list and assign
codes and functions (prank_again = app.yesno….). To check if something
is equal, Python uses two equal signs ==, figure 5.8.
Figure 5.8 The meaning of the symbols, = and ==
Once the program has confirmed that the player pressed the Yes button, then
the app.info()widget is used to load a popup box that displays the message
that “Rick is never gonna give you up”. The program then calls the previous
prank_me_play_music()function which runs again, playing the song intro,
making the background a different random color and displaying the picture.
Once the prank ends, the player is again given the option to run the prank
again.
When the No button is pressed, the if statement loads a different popup box
that displays a message that Rick “let you down” (another reference to the
song lyrics) This popup is an error Pop-up window which uses a red banner
to signify the fact that the app is closing. The player then presses the OK
button, and the program runs the code app.destroy()and the program closes
the GUI. To start the prank again you need to run the program again.
The second line of code creates a popup box using the function
app.question() that asks the player to enter their name. Their name is used
to personalize the quiz and display the player’s current score (even though
this is a fake quiz, and they never score anything, it makes the quiz appear
more realistic). Remember the app.yesno() Pop-up that we previously
created? Well, guizero does a similar thing with app.question() the widget
automatically creates the question box and displays a question, creates a
space for the player to enter in the answer, then saves their input. The pre-
built components are being used to support achieve our rick-rolling dreams!
The last line of code uses the Box object to create a space to display two
answer buttons. In guizero, the Box object is a container which can hold other
widgets. Unlike the App window, a box is invisible. Using the Box neatly
lays out widgets and elements contained inside it. In this project, the Box
neatly lays out the buttons. If we use the App window instead of the Box, it
will just stack the buttons vertically on top of each other.
# App
In the next part of this section of the program code, listing 5.6 we use code
Text() to create and display the fake quiz question. The question is stored as
a string; you may be familiar with strings from the other chapters, they are
single character or a series of characters, numbers or symbols that are
displayed or printed out in the program.
We use a string to hold and display the quiz question, “What is a baby sloth
called?”, which is a real question about what a baby sloth is called. We add
the question inside the Box() which keeps the layout neat and tidy.
Next, we use Text() again, to create another string that will display the score.
This string combines the name that the player enters (from listing 5.5), and
was saved into the your_name variable, with the text current score = 0. Let’s
say for example, that your name is Amy. The combined string would be
“Amy’s current score = 0”. Remember that the score is not real and is simply
there to make the quiz look more realistic.
Finally, we set the font size and the style of the font. You can choose a
different font by replacing the current font name with the name of your
preferred font. We have used Comic Sans as it is a funny looking font that,
change the fun is just to make the GUI look cooler.
app.display()
First, we start by creating an instance of the button object using the name
answer1 this holds all the code about the button, what it does, how it looks.
Then create a button using the PushButton()code. We need to tell the
program to display the button neatly inside the answer_grid, which makes
use of the Box()layout, and then we use the command
command=prank_me_play_music to tell the program to call the function that
pranks the player. This is the function we created in listing 5.3 that plays the
music, changes the color etc.
Next, add a label to the button that displays the answer to the question about
Sloths, for example, Pup. A label is added so that the player thinks they are
selecting an answer to the question. Finally, use the grid=[] code to align the
first button. All these parts create a line of code that displays a button that
when pressed triggers the Rickroll.
The second button follows the same code as the first and is used to create a
second answer option for the question. (This provides the player with two
answers, although we know that pressing either button will trigger the prank).
However, we need to change the label to ‘Cub’ and use different values on
the grid=[] to place this button underneath the previous.
# Imports
# Functions
def prank_me_play_music():
winsound.PlaySound("Rick.wav", winsound.SND_ASYNC)
app.bg = choice(colors)
ricked_again()
def ricked_again():
prank_again = app.yesno("Rick Rolled", "Want to be Rick Rolled again?")
if prank_again == True:
app.info("Rick says", "Never gonna give you up!")
prank_me_play_music()
else:
app.error("Rick says", "I let you down...")
app.destroy()
# App
app.display()
When using more than two buttons, you’ll need to increase the length of the
GUI window. This is because each button takes up space and pushes the
picture of Rick further down the GUI window.
Figure 5.9 shows the GUI with three buttons, and you can see that Rick has
lost his legs, the image has been cut off as the GUI needs to be longer to
display the full image. You can also see that the text, “Your current score =
ricked”, is now shown after the second button and not the third. The players’
current score is also still shown.
The first step is to save your file with a new name, this means that you still
have your original working version if things go wrong or don’t work as
intended. To do this, follow the instructions below,
You now have a new version of the file which you can edit.
Find the line of code that contains the original question and replace it with
the new questions. You only need to change the question (underlined in
listing 5.8), not the code. You can always run your GUI program to check
that the question is displayed correctly before you edit the answer buttons.
If the answer to your new question only has two options, then simply keep
the same two answer buttons and just change the labels to display the new
answers to your new questions. If you want to add more answer buttons, then,
in your program, then use this line of code:
[CA]answer1= PushButton(answer_grid, command=prank_me_play_music, text='Past
Add the code underneath the answer2 button code, shown in bold in listing
5.8. Change the name of the variable to answer3, change the label to the
answer, and then set the grid value to grid =[0, 6] this places your new
answer button neatly underneath the previous buttons.
Listing 5.8 Changing the question and adding an extra answer button
Next, we need to change the place where the GUI displays the score. The
value that indicates the location is easy to calculate, as the new location is
underneath the last answer button. The last answer button is stored at [0,6]
which means that the new position for the score is now [0,7]. In your
program code, find the line of code that contains your new question,
underneath it, is the code that displays the score. Change the grid value to
grid=[0,7] as highlighted in bold and shown in listing 5.9.
When the prank runs it changes the score to display the text, Your current
score = ricked. This text also needs to be moved to the same location as the
original score text that you moved in the previous paragraph.
Change the grid layout from, grid =[0,5] to grid =[0,7]so that it matches
the same values used for the score in listing 5.9. For example, if you set the
value to grid =[0,11] then replace the grid value with the same value, grid
=[0,11].
Now to check how much of the picture of Rick has been cut off or is missing
from the GUI window. Run the program, (Press F5 on your keyboard, you
may be prompted to save the file first) enter your name and then select one of
the answers buttons. The prank will run, look at the image displayed in the
GUI and estimate how much is missing. In figure 5.9 about 15% has been cut
off. Select the No option when asked if you want to be pranked again and
return to your program code. Find the #App section and the line of code,
app = App("General Knowledge Quiz", width=330, height=338)
The code height=338 sets the height of the GUI window, which currently is
too small to display the additional answer buttons and all the image. You can
use some simple math to calculate that 15% of 338 is approximately 50, so
we need to add 50 to the current high value. Change the new height value to
height=388.
If you have added more than three buttons, then the easiest method to set the
new height is to try some height values until you have a good fit. Figure 5.10.
Remember that you will also need to change the score grid values so that they
are still at the bottom of the GUI window under the buttons.
# Imports
# Variables
# Functions
def prank_me_play_music():
winsound.PlaySound("Rick.wav", winsound.SND_ASYNC)
app.bg = choice(colors)
ricked_again()
def ricked_again():
prank_again = app.yesno("Rick Rolled", "Want to be Rick Rolled again?")
if prank_again == True:
app.info("Rick says", "Never gonna give you up!")
prank_me_play_music()
else:
app.error("Rick says", "I let you down...")
app.destroy()
# App
app.display()
Statements of fact
choice()is a feature of the Python random module that picks a random
item from a list.
A Pop-up is a window that interrupts the user by asking question or
providing information.
The yesno() is a premade Pop-up in guizero which displays yes and no
options. The user can press Yes which returns a value of True. Pressing
No, returns the value, False.
The info() Pop-up is a premade popup in guizero that displays
information and the Windows information icon.
An error() Pop-up is a premade popup in guizero that displays a
message with the error icon.
Indentation is the number of spaces at the beginning of a line of code or
is used to indicate selection code, for example, the code that is part of
the IF statement.
A conditional statement checks if a condition has been met and then
responds.
Conditions can check values of a number, text and Yes and No (True /
False) responses.
Selection is where the program selects a particular action or outcome
based on a condition. It is often referred to as, an If Statement.
An If statement checks if a condition is met and then responds. Else, is
used to respond when a condition is not met.
INSTALLATION
Wait for the program to download and install, and you are ready to make
disgusting FART sounds, well, your GUI is! The program code, as the name
suggests, is simple to use, first you import the audio module using the line,
import simpleaudio as sa. Then you create an instance of the audio file
and assign it to a variable.
You can now control when the sound plays using the code, play_obj =
wave_obj.play(). The program needs to wait for the sound to play through
before moving to the next line of code, to do this use the code
play_obj.wait_done()
# Imports
# Variables
# Functions
def prank_me_play_music():
wave_obj = sa.WaveObject.from_wave_file("Rick.wav")
play_obj = wave_obj.play()
play_obj.wait_done()
app.bg = choice(colors)
ricked_again()
def ricked_again():
prank_again = app.yesno("Rick Rolled", "Want to be Rick Rolled again?")
if prank_again == True:
app.info("Rick says", "Never gonna give you up!")
prank_me_play_music()
else:
app.error("Rick says", "I let you down...")
app.destroy()
# App
app.display()
6 Are you a mind reader?
In this chapter you will build a version of the higher or lower number
guessing game where a witch or other character of your choice has chosen a
number between 1 and 100. They have given you five lives or chances to get
it right, if you do guess correctly, then you are free to go. You have won.
Unfortunately, if you do not guess the correct number in five tries, then you
lose. On the positive side, if you do guess the number correctly, the witch
will invite you to try again, if you dare! Figure 6.1
Figure 6.1 Can you guess the number and beat the witch?
Creating the project
For this project you will need a suitable image file to display in the GUI. This
is a picture of the challenger whom you are playing the game against. You
can either download the witch image (this is covered later), or source your
own image. The witch (or image of a witch) is who you are playing against
and trying to guess their number. They will choose a random number
between 1 and 100. Before we begin, let’s look at the steps required to build
the project (figure 6.2). The main steps are:
If you have been working through the other chapters, you are already aware
that when using guizero you need to ensure that image files are stored in the
same folder that you have saved the program file in. To do this,
1. Open the folder where you are saving your GUI projects.
2. Create a new folder and name it MindReader.
3. Download the project image file of the witch from Chapter 6
https://github.com/TeCoEd/Twisted_Python_Projects/tree/main/Project_Codes
or use your own image file.
4. Save or copy the image file to the MindReader folder.
You are now ready to write the program code and create the Mind Reader
game.
# Imports
The first set of modules that are imported, shown on the first line, will be
familiar by now; we have used most of them in the previous projects. These
modules enable you to create the GUI window, use Box to lay out the
widgets, and display an image, buttons, and text.
One line two a new method from the random module, randint() is
introduced. In chapter 2 we used the random module to select one random
joke from a list of jokes. In chapter 5, you used choice()to choose a random
background color from a list and set it as the background color of the GUI.
In this project we are going to use
from random import randint
This method from the random module allows Python to generate a random
integer. What is an integer? An integer is a whole number. For example, a
number such as 65 or 23 or 2. Integers have no decimal place values, so the
numbers 65.2, 23.7, 2.89 are not integers.
A method
When the GUI is running to make the game create the illusion that the witch
or your character is really thinking of a number, we need Python to select a
random number and save it without us knowing what number has been
picked. This means that since we don’t know the number, we can try to guess
it.
However, since Python could choose any number in the world, we must set a
boundary. This boundary is the lowest and the highest values the random
number can be between. The code randint(1,100) generates a number
between and 1 and 100 including the numbers 1 and 100. We will set this
boundary later in the variables section when we use the randint(). You can
change the boundaries to make the number easier or harder to guess.
On the third line we import sleep() from the time module. This module
enables us to control timings within the program and add a short delay
between the previous and the next line of code running. We will use a small
pause between the GUI saying the answer is wrong and prompting the user to
guess again. This gives the player enough time to read the message before
they respond.
The lives, and the guesses are always the same value, but it is more
motivating for a player to say that they have lost a life rather than that they
have lost a guess.
Since the number of lives needs to be used by other parts of the program it is
declared as a global variable. Global variables hold data which can be
accessed by other sections of the program code (figure 6.3). In this program,
the variable lives is accessed by the three separate areas of the program:
Local variables can only be accessed by specific parts of the program. The
GUI displays an image of the witch. To do this we will create a local variable
called pic = to hold the image details. This Variable only appears in the
App() section (as this is the section that is responsible for displaying the
image) and is inaccessible by other parts of the program.
Figure 6.3 Data held in global variables can be accessed by any part of the program code.
After declaring the variable global lives, we use lives = 5 to set the
starting number of lives to five. This variable is also used to keep track of the
number of remaining guesses that the player has left and ensures that the
game ends when all the player’s lives have been used up.
Under the import section of the program code, add the code in listing 6.2.
# Variables
global lives
lives = 5
The first line of code creates the global variable lives. This is a location in
the computer’s memory that stores the number of lives. As a global variable,
it ensures that the information held can be accessed by other parts of the
program, in particular, the check_the_guess() function that we will code in
the section, “Running and testing the GUI,” that checks whether the player’s
guess matches the witch’s number. Then we set the lives variable to a value
of 5. These are the five lives that the player starts the game with.
A fourth rule might be to know the step size. For example, in this program we
are using the default increments of 1 in the loop. (One life is lost each time
you guess incorrectly) We shall look at the condition later in this section.
What is a Loop?
Loops mean that, we as the programmers, can write quicker and more
efficient program code. Let’s consider the program we are writing. As part of
the game, we want the witch to ask the player to try and guess their number,
they get five chances to guess it correctly. One way to code this in the
program is to ask the player five times to enter a number,
guess = app.question("Guess", "Mortal, enter the number I am thinking of")
guess = app.question("Guess", "Mortal, enter the number I am thinking of")
guess = app.question("Guess", "Mortal, enter the number I am thinking of")
guess = app.question("Guess", "Mortal, enter the number I am thinking of")
guess = app.question("Guess", "Mortal, enter the number I am thinking of")
Not using a loop means that when the GUI runs, Python will have to ask the
player to enter their number and then process their response. This could take
4 or more lines of code. The player has 5 chances to guess the number, which
means the program could use an extra 20 lines of code. This requires
additional memory and processing power from your computer. Meaning that
it must work harder. This is not really an issue for 5, 10 or even 1000 lines of
extra code and will make little noticeable difference. However, if we scale up
the size and consider a bank program that has to check 14 digit account
numbers for a million customers, then we are into more than 14,000,000 lines
of additional code!
The solution is therefore, to write the lines of code once and then use a loop
to repeat the line 14,000,000 times. In our program we use the loop to repeat
the line of code five times.
Previously I mentioned that the loop needs to know when to start and when to
stop. We control this using a conditional. A condition is like a check, the
program checks if the condition has been met, if it has been met, then the
program breaks the loop and moves on to the next part of the program. While
the condition is not met, the loop continues to repeat.
Loops in school
Think about when you were in class at school. At the start of each lesson, the
class register is taken. The teacher calls out the name of the student and waits
for a response, then they move onto the next student in the register and call
out their name. This process loops until the last name has been called out.
In this example, the condition is “have all the names been read out?” The
teacher keeps looping and calling out all the names until the last name has
been called out.
When the Mind Reader program runs, the player is given five lives which we
can use as part of the condition to check when to break the loop. The program
runs the block of code, in our case the check_the_guess()function
repeatedly until a given condition is satisfied. Whilst the player has lives left,
the program carries on asking them what their next guess is.
The program loop is asking the question, (checking the condition) is the
number of lives greater than something? Now we need to think about what
the lives are greater than. Let’s consider this, when does the game end? When
the player has used up all their lives.
Therefore, we can say that if the player has no lives left, they have zero lives.
In Math the more than comparison is called ‘greater than’. Combining this
altogether we can create the condition, while lives is greater than 0, then
replace the greater than with the mathematical symbol > and we get while
lives > 0.
# Functions
def check_the_guess(): #A
global lives #B
number = randint(1,100) #C
One of the challenges when writing longer functions is ensuring that the
indentation levels are correct and match. This refers to the alignment of the
lines of code and is used so that Python knows which lines of code are part of
the function and which lines are not. Indenting refers to the use of white
space before the text, which means the text starts a little distance away from
the left-hand margin. Check your indentation to ensure that it is correct.
We then declare the variable number, which stores the random integer that
the program will generate. The random integer is generated using the
randint() function and we now set the boundaries for the numbers.
To set the lower and upper values we include them, expressed as numbers,
within the brackets, like this, randint(1, 100). This sets the lowest integer
that can be selected to 1 and the highest to 100. The player is attempting to
guess any number between one and one hundred. If you want to, you can
change the boundaries values to make the game easier or harder. You may
also want to adjust the number of lives that the player has. This will give
them at least some chance of guessing the correct number before their lives
run out!
Next, we add the lines of code that we want the loop to repeat, while the
player has more lives than zero. The first repeated line of code is the question
asking the player to enter their guess, their number is then stored into the
guess variable. Then, because the player has used one of their chances the
program needs to remove a life and update the lives left from 5 to 4. This is
done using the line:
lives_left_text.value = lives – 1
where .value updates the text label displaying the remaining lives and, =
lives – 1 , subtracts 1 life from the remaining lives.
After the player enters their number, then the program needs to check their
guess against the witch’s number, and then tell the player if their number is
either too high, too low or correct.
In this program, we use the IF Statement to check the follow conditions, table
6.1.
Each time an if statement runs, it always starts at the beginning and checks
the first condition. The second condition only runs if the first condition is
false (or not met). Then, it checks the second line condition, if this is false (or
not met), only then is the third condition checked and so on. Figure 6.7.
However, using logic we can know that if the player’s guess is not higher
and it is also not lower than the witch’s number, then, the player’s number
must be the same as the witch’s number. Therefore, this means that both
numbers are equal, and the player has guessed correctly. So, we do not need
to use elif for the third condition, we can replace it with an else clause. We
also replace the math related terms with the equivalent symbols, and we get
the final conditions of the if statement. Table 6.3.
Number Condition
1 if the player’s number > than the witch’s number?
2 elif the player’s number < than the witch’s number?
3 else the player’s number = the witch’s number? (Player has
won)
Add the code from listing 6.4 to the check_the_guess() function ensuring
that the indention levels are correct.
The first line of the if statement, if int(guess) > number is checking that
the player’s guess is greater than the random number. As an example refer to
table 6.4, let’s say that the player’s guess is 34 and the witch’s number is 17.
Line one of the code checks if 34 is greater than 17. It is, so the next line of
code runs displaying the error Pop-up and the message, Poor effort, the
number is lower. One of your lives is deducted, you now have four left.
As a smart player, on your next guess you will want to enter a lower number
than 34. You enter the number 12. This time the first line of code runs and
checks if 12 is greater than 17. It is not, so the program jumps to the eilf and
checks if the number is less than 17. It is, so the next line of code runs
displaying a popup and the message, No fool, try a higher number. Again,
one of your lives is deducted. You now have three lives left.
Table 6.4 An example of the guessed number and then outputs
Considering your next guess, you know that the number is greater than 12
and less than 34. You decide to go for the middle value and guess 23. This
time the first line of code runs and checks if 23 is greater than 17. It is, so the
next line of code runs, displaying the error popup and the message, Poor
effort, the number is lower. Again, one of your lives is deducted, you now
have two left.
Your next guess is 13 and the program states, No, fool, try a higher number.
You now have only one life left. It is your final guess. You guess 16, the If
statement checks if 16 is greater than and then less than 17, and then removes
your last life, you have zero lives left.
At this point the program returns to the start of the loop, and it runs the loop
again. Remember the loop only runs while lives > 0, and guess what, you
have zero lives and your lives are no longer greater than zero, so the loop
breaks, and the game is over. The if statement does not run, and the program
jumps to the code under the loop code. The witch tells you that you have lost!
Complete the check_the_guess() function and type up the code from listing
6.5. Be sure to watch the indentation levels ensuring that all the code aligns
correctly. Any issues or uncertainties then check out listing 6.6.
[CA]app.error("Lost", "You have failed my pretty, the number was " + str
sleep(0.5)
app.destroy()
Before we do this, we convert the number from an integer into a string using
the code str(number) using a technique called casting. In Python, the term
casting refers to the process of converting the data stored in a variable from
one type of data to another. For example, changing the number 45 to text,
which removes the value of the number and is simply the symbols 4 and 5.
The number must be changed to a string otherwise Python will try and add
You have failed my pretty, the number was and the 45 together. This
will result in an error since you cannot add text and numbers together.
On the next line of code, we add a short pause to give the player time to read
the message before the program code closes the GUI. The player has lost so if
they want to play again, they have to restart the GUI. Listing 6.6 shows the
complete function, ensure that your indentation is correct and matches before
you move onto the next section.
# Functions
def check_the_guess():
global lives
number = randint(1,100)
lives_left_text.value = lives - 1
[CA]app.error("Lost", "You have failed my pretty, the number was " + str
sleep(0.5)
app.destroy()
The second function manages the process of playing the game again. This
involves the following steps.
This function also uses IF statements again to respond to the choice that the
player makes when asked if they want to play the game again. Add the code
from listing 6.7.
def play_again(): #A
global lives #B
play_again = app.yesno("Witch", "Do you want to play again mortal?") #C
if play_again == True: #D
lives_left_text.value = 5 #E
lives = 5 #F
app.info("Witch", "Excellent choice!") #G
check_the_guess() #H
About ==
Remember that in Python, = means has a value of. It is used with variables
and lists, and to assign data, or to declare variables and functions; for
example:
play_again = app.yesno() or PI = 3.141592653589
To check if something is equal, Python uses two equal signs == for example:
if play_again == True: 20 == 10 + 5 + 5
Create the new the new function called play_again()on the first line, then on
the next line import the global variable lives which means that all parts of the
program, mostly the functions can access the current value of lives. Then we
declare a new variable called play_again and a pop-up window app.yesno()
that asks the player, Do you want to try again mortal? (figure 6.8.)
True or False
In the program code you will have seen that True and False are used to mean
Yes and No. Computers do not understand the meaning of Yes or No, or even
True or False, but they do understand numbers. This means the computer can
respond to a player’s choice and store their response.
Since the condition has been met, the player clicked Yes, the next four lines
of code run. The lives_left variable is reset to 5 so that the GUI displays
that the player now has 5 lives. The code lives = 5 resets the number of
lives back to 5 to ensure that as we are starting a new game the player starts
with 5 chances again. The witch displays a message via a popup and then the
check_the_guess() function is called, and the game begins again.
Now let’s consider what happens if the player decides they do not want to
play again. The popup window appears, and the player selects No. The
variable play_again stores the data ‘False’, in this context False means No.
The if statement runs and checks if play_again is True, it is not so the if
statement skips the indented lines of code and jumps to the elif condition,
listing 6.8. The lines of code related to the elif then run, a popup is displayed
with a message from the witch, there a short delay to give time for the player
to read the message and then lastly, the GUI closes.
In this if statement there is also an else clause, this is not needed as there are
only two options, Yes and No. However, it is good practice to end the
statement with an else clause. We don’t want anything to run on else and we
use pass which does what it says, it passes and jumps to the next line of
code.
Add the code from listing 6.8 to complete the function. Remember to keep an
eye on accurate indentation.
else:
pass
Remember
The person writing the code must write both the condition and the responses.
The program only knows how to respond because we have told it how to.
This last section of the chapter covers how to build the main GUI app. If you
have already worked through some of the other chapters, then you will be
familiar with the code and what it does. We begin by naming the app and
setting the size of the GUI window.
Then use Text() to prompt the player what to do, “Can you guess my secret
number?” and set the font size and color of this text. Lastly use Picture() to
display the image of the witch or witch-ever(!) character you have chosen to
challenge you in the game.
The final section of code creates the button which when pressed by the player
calls the check_the_guess() function and begins the game. Add the final
section of code from listing 6.9.
app.display()
Apart from the if statement in the functions, this program builds on the things
we have used in previous chapters and includes many of the widgets, features
and lines of code from the previous chapters. Any errors that occur will
probably be syntax errors. This is caused where the code has been typed
incorrectly and the program does not understand how to proceed, and so the
program stops.
To run the GUI, press F5 on the keyboard, you may be prompted to save the
program file. Choose OK, the program will save, and then the program will
run, and the Mind Reader GUI will load. Can you guess the witch’s number?
If you encounter any issues, or the program does not run as expected, check
for these common errors:
# Imports
# Variables
global lives
lives = 5
# Functions
def check_the_guess():
global lives
number = randint(1,10)
lives_left_text.value = lives - 1
[CA]app.error("Lost", "You have failed my pretty, the number was " + str
sleep(0.5)
app.destroy()
def play_again():
global lives
play_again = app.yesno("Witch", "Do you want to try again mortal?")
if play_again == True:
lives_left_text.value = 5
lives = 5
app.info("Witch", "Excellent choice!")
check_the_guess()
else:
pass
# App
app.display()
Here are some other features that you might want to try:
This will make the game easier, or you could increase the values and make it
more of a challenge; for example, number = randint(1,1000). You will
need to remember to increase or decrease the number of lives that the player
is given, as a larger range of numbers will require more guesses to correctly
guess the correct number.
Figure 6.10 Python error caused when you select not the play the game again
This is because the App is destroyed (closes) but the program is still running.
To resolve this issue, we need to exit the program. This is a technique that
can be applied to other GUI program where you encounter this error.
The solution uses the code, sys.exit() which is a built in function that
enables Python to end the execution of the program. Follow the steps below
and make the following edits to your program:
1. First, add systems module in the # Imports section of the program using
the code import sys.
2. In the play_again() function, locate the last line of code,
app.destroy(). Underneath this add the line of code sys.exit(). This
will stop the program from running and no error will be produced.
3. Save your program (F5) and test it.
Adding sound
One more thing to try is to add sound. How about if the witch cackles every
time you guess incorrectly, or insults you if you lose the game? If you have
previously completed chapters two or five, then you will be familiar with
how this works. We use the winsound audio software installed with Windows
and import the module into Python.
Guizero plays .wav sound files, so you can either download the file from the
project page,
https://github.com/TeCoEd/Twisted_Python_Projects/tree/main/Project_Codes
or you can use your own audio file.
1. Copy your audio file into the MindReader folder where the
Mind_Reader.py file is saved.
2. In the # Imports section of the program import winsound by adding the
code, import winsound
3. Let’s say that we want to add a witches laugh each time that the player
makes an incorrect guess. In the check_the_guess() function, find the
if statement shown below,
if int(guess) > number:
app.error("Lower", "Poor effort, the number is lower")
lives = lives - 1
elif int(guess) < number:
app.warn("Higher", "No fool, try a higher number")
lives = lives – 1
after the line that displays the messages, shown in bold below.
if int(guess) > number:
app.error("Lower", "Poor effort, the number is lower")
winsound.PlaySound("MindReader/laugh.wav", winsound.SND_ASYNC)
lives = lives - 1
elif int(guess) < number:
app.warn("Higher", "No fool, try a higher number")
winsound.PlaySound("MindReader/laugh.wav", winsound.SND_ASYNC)
lives = lives – 1
5. Save the program (press F5) and try out the new features. Don’t forget
to turn your speakers on and ensure the volume is up.
Statements of fact
A loop is a section of the program code that repeats until a condition is
met.
While loops repeat the section of code while the condition is being met.
Inequalities refer to a value being greater than >, less than <, or equal to
==.
In Python, two equal signs ==,means equal to, or equivalent to. A single
equals sign = means assignment.
A conditional statement checks if a condition has been met, and then
code is executed in response to the condition being met.
If statements are used to check and respond when certain conditions are
met.
Selection is where the program selects a particular action or outcome
based on a condition.
If is used to check the first condition.
The elif statement only runs when the if condition is not met.
elif is used to if there are one or more conditions to check.
An else clause, else, is used to respond when none of the conditions are
met.
7 Is your password secure?
Did you know that it takes a supercomputer less than one second to crack a
seven-character password that contains only lowercase letters! In contrast, it
takes nearly 200 years to crack a 12-character password made up of lower-
and uppercase letters. However, most systems limit the number of times that
you can enter an incorrect password before the system locks you out. This
means that even though it takes less than one second to crack a weak
password, on the third attempt the system would lock out the user.
Since passwords are used everywhere for protecting data and keeping
information safe and secret, it is essential that your passwords are secure.
If you want a secure password that is easy to remember but hard to guess,
then the password should meet at least the following criteria:
For example, jelly22fi$h meets all the criteria and is secure. However, you
still need to use common sense when thinking of a password. For example,
consider if my password was DanAldred1. It meets all the criteria of a secure
password, but it is easily guessed as it contains my name. Ensure that your
password is random enough, you can do this by replacing the letters with
numbers or symbols. So DanAldred1 becomes D@nA1dr3d1, making the
password a lot harder to guess.
In this chapter we build our first and only sensible program, a password
checker. Passwords are so important that it would be foolish to make a prank
version of a password checker.
Instead, we will build a GUI that allows a user to enter in their password,
then the program checks that the password is a suitable length, and contains
at least one uppercase letter, one lowercase letter, and at least one number.
Skill
Python Checking strings, checking a single letter, not if
statements, for loop, any() not
Guizero Enabling and disabling buttons
For loop
The GUI also uses several string functions that check the length of the string
and the case of the letters. The main stages of the project are:
In this chapter you will come across several terms that are used in everyday
life to mean the same thing (table 7.1). This is confusing! Therefore, this
chapter uses the following definitions:
# Imports
Like some of the previous projects, the variable that holds the instruction
about the TextBox() is coded in the #App section. This is to ensure that the
TextBox() is created and displayed when the app runs at the start of the
program.
# Variables
The conditionals in the code are the criteria features that make a strong secure
password: a certain length of characters (8 or more) a lowercase letter, an
uppercase letter and a digit. If the password meets the first criteria, then the
next condition is checked (figure 7.3).
Figure 7.3 Flowchart of conditionals that are checked and the outcomes.
If the password does not meet the first criteria, then the user must edit their
password, add the additional secure feature, and then resubmit it for
checking. This process creates the illusion of the program looping. However,
what in fact is happening is that each time you press the Check Password
button (which we will create later), the conditions are checked. This happens
until all the criteria are met.
The function is called each time the player presses the Check Password
button, and the following happens:
# Functions
def PasswordCheck():
password = password_textbox.value
if (len(password)<8):
app.error("Length ", "Your password must be at least 8 characters lo
As with all functions, we begin by declaring the function. In this program the
function is named PasswordCheck() since it is checking the Password.
Remember that functions only run when they are called and are named so the
program can locate them when needed!
On the next line, underneath the function name, we add the code to instruct
the program to transfer the characters that the user enters in the
password_textbox(), into a variable labeled password. (We will create the
password_textbox() in the # App section of the program so this is why it is
the first time you have come across, password_textbox())
Transferring the characters in the user’s password into a new variable makes
the code that checks the password simpler. There is less chance of making
syntax (typing) errors if you are using a familiar word such as password.
We write
if (len(password)<8):
rather than
if (len(password_textbox.value)<8):
The program has no idea how long the user’s password is and therefore it
uses the len() function to measure and return the length of the password,
before combining it with the < 8 to check that “the password’s length is less
than 8 characters.”
Figure 7.5 Code to find if the length of the password is less than 8 characters.
We now have a conditional that checks that the length of the password is at
least eight characters or more. Figure 7.5. To do this, the program is actually
checking if the password is less than 8 characters long. This uses the math
equality < symbol followed by the number 8 (which means “the item on the
left is less than the item on the right”). In this case, is the length of the
password on the left, less than the number 8 on the right?
Figure 7.6 Function moves to the next criteria once password is correct length.
When the function checks the first condition, if the password is less than 8
characters, if it finds that the answer is Yes (True), (the password is less than
8 characters long) then the error pop window displays a suitable error
message. Figure 7.6. If the condition is No (False), then this means that the
password is 8 or more characters long and meets the first secure password
check. The if statement then checks the next set of conditions which are
discussed in the section below.
Checking strings
In this section we look at the next set of conditions that check the password is
secure. These conditions are shown with their Python function in table 7.3
and focus on checking each individual character to confirm that at least one
character in the password is a lower case letter, an upper case letter, and a
digit.
The program needs to check every individual character and not just the
password as a whole; otherwise, it may miss finding a condition.
Let’s assume that the password is TFGGHSTH and is tested with the
password.islower() code. The GUI would return False, since there are no
lowercase letters. If the password was tfgghsth, then the condition would
return True because the password is lowercase.
What happens if the password is TFGGhsth where the lowercase letters are at
the end? The code would not identify the lowercase letters because the
function is checking the password as a whole.
So, the solution to this problem is to check each individual character in the
password and return True or False (Yes or No) based on an individual
character and not the complete password. Imagine that the program is asking
each character if it is lower case, figure 7.7. It does not stop asking until it
finds the first lowercase letter.
However, the difficulty with checking every letter is that the password could
be any combination and length of characters in the world, and most likely
made up of a random combination of upper and lowercase letters. So, we
cannot tell the program to check for 10 characters as there may be 14
characters in the password, or 6 characters, or 25, we don’t know.
All is not lost. Since we can use len() to return the length of the password,
then we can use a loop to check each character islower() and loop over all
the individual characters in the password, the number of times that len()
says.
For example, if len() returns that the password is 17 characters long, then
the loop will run 17 times and check if each individual letter is lowercase.
You may recall that using a loop means that we can write more efficient
program code. In this program we will use a for loop. The for loop is used
for repeating a section of code over the contents of a string, which is perfect
because the user’s password is stored as a string!
What is a loop?
To create the loop, we use the code for and then tell the program the string to
loop over, which is password. So, the combined final line of code is for x
in password where x refers to each individual character in the password.
Figure 7.8.
Figure 7.8 Code that creates the loop that checks each character in the password as used in listing
7.4
x is a variable that changes each time the loop repeats by replacing each
character from the password whilst it is checked. In programming, the proper
term is iteration, the program iterates over each letter in the password and
apply the check.
x and i in Python
In Python programming when iterating over a word using a line of code such
as, for x in password the standard is to use a lower case x to represent each
letter. When the variable contains numbers then the letter i is used, for i in
numbers.
Consider this everyday example: Imagine you have ten chocolate bars and six
friends. You will give each friend (f) a chocolate bar, so for each f in your
friendship group, give them a bar of chocolate. In code this would look like
this: for f in friendshipgroup. The value of f must change each time the
loop repeats; otherwise, you would be giving a chocolate bar to the same
friend six times. Figure 7.9.
Figure 7.9 Using a loop to give your friends a chocolate bar each.
with the lowercase letter check, and we have the following line of code:
x.islower() for x in password
Then, we combine this line of code into the elif statement, and we can check
whether each letter in the password is lowercase, regardless of what or how
long the password is. Add the code from listing 7.4.
You may have noticed that the first line of code uses an elif statement and is
then followed by the word not and the function any().
Let’s first discuss not. The not is known as a not operator. It checks if a
condition is not met the same way you might say “it is not raining” or “I am
not hungry.” The not operator uses reverse logic to check if there are no
lowercase letters in the password. Figure 7.10.
Figure 7.10 Using not to find lowercase letters and if you are hungry!
You can think of it as a question: Is it true that there are not any lowercase
letters in the password? Then the program returns either True or False. If
there are no lowercase letters, the program returns True, the for loop stops,
and the app.error()message is displayed. The user must then adjust and re-
enter their password and run the check again.
The any() function is a really useful function that checks each character and
returns either True or False. We use any()to return an outcome based on any
individual letter of a whole password meeting or not meeting a certain
condition, in this part, any question that is not lowercase. Figure 7.11.
Figure 7.11 Using elif not any to check a password does not contain lowercase letters.
Consider an everyday example. You and three friends are at a theme park
queueing (lining up) to go on a roller coaster. Each car holds four people and
must be full before it leaves. Perfect, as there are four of you! To ride the
roller coaster, you must be at least 1.53 meters (5 feet) tall.
The attendant checks your height and you are tall enough. They check that
each friend meets the height requirements. When they check your fourth
friend, they measure that they are only 1.46m and therefore under the height.
Figure 7.12 Using any() to check if any of the people meet the height requirement.
As the check is an any()check, it means that if any of the four of you do not
meet the requirement, then none of you can ride the rollercoaster (figure
7.12). The attendant asks all four of you to leave the ride! (In real life this
would not happen because you would have all checked your heights before
you queued for the ride. You would know if one of you was not tall enough.)
Table 7.4 shows the outcomes of checking various versions of the password
THRS with different combinations of upper and lower case letters. The code
checks each individual letter by saving it into the x variable. After the check,
the next letter is moved into x. Once one lowercase letter is found, the checks
stop as the password only requires at least one lowercase letter to meet the
criteria.
The program uses the same technique to check for upper and lowercase
letters, and digits using elif statements. Each time the if statement runs, it
always starts at the beginning of the password and checks the first character
followed by the next, and then the next, and so it continues until all the
characters have been checked. If all the letters fail the check, then the error
message is displayed.
Checking for uppercase letters
In an if statement, the next condition only runs if the first condition is False.
Then it checks the second condition, if this is false, only then is the third
condition checked and so on. This means that, for example, if the user’s
password is missing a lowercase letter, the if statement will not check for the
uppercase and digit until the user adds a lowercase letter to their password.
When the password is eight or more characters in length and contains at least
one lowercase letter, one uppercase letter and a digit, then all of the
conditions are met, and the statement jumps to the else clause.
The else displays a popup informing you that your password is secure. Type
out the code in listing 7.5, ensuring that the indentation is correctly aligned.
else: #E
app.info("SECURE", "*** YOUR PASSWORD IS SECURE ***") #F
This section covers how to build the main GUI app. As in the previous
chapters, we use create App() then display the name of the GUI, (Password
Strength Checker) and set the height of the GUI window. Next, we change
the background color to white because this is a serious app! Then add a title
that introduces the GUI, setting the font size and the font type. Add the final
code from listing 7.6.
#enter text
text = Text(app, text="Enter your Password Below")
password_textbox = TextBox(app, width=50)
#button
button = PushButton(app, command=PasswordCheck, text="Check Password", )
app.display()
The middle section in the code listing creates the text box where the user
types or inputs their password for checking. Figure 7.13. This uses the
TextBox() widget set to a width measurement of 50 to create a suitably sized
input spot for the password. Then we add a button which, when pressed, calls
and runs the PasswordCheck() function. The data in the TextBox() is passed
to the password variable and the checks begin:
That wraps up the final program code. In the next section, we will check for
any errors before running our GUI.
If you encounter any errors, or the program does not run as expected, check
for these common errors:
# Imports
# Variables
# Functions
def PasswordCheck():
password = password_textbox.value
if (len(password)<8):
[CA]app.error("Length ", "Your password must be at least 8 character
else:
app.info("SECURE", "*** YOUR PASSWORD IS SECURE ***")
# App
app = App("Password Strength Checker", width=700, height=300)
app.bg = "White"
title_text = Text(app, "Password Strength Checker")
title_text.text_size = 28
title_text.font = "Impact"
#enter text
instruction = Text(app, text="Enter your Password Below")
password_textbox = TextBox(app, width=50)
#button
button = PushButton(app, command=PasswordCheck, text="Check Password")
app.display()
The first step is to save your file with a new name. This means that you still
have your original working version if things go wrong or don’t work as
intended. To do this, follow these instructions:
You now have a new version of the file which you can edit.
Did you know that a password that contains twelve characters takes 3,000
years to crack! This surely is an extremely secure password! The first other
thing to try is to increase the length check of the overall password from eight
to twelve characters. In the # Function section of the program find the line
of code
if (len(password)<8):
You will also need to change the message that informs the user that their
password no needs to be 12 characters in length. Find the line of code,
app.error("Length ", "Your password must be at least 8 characters long")
There may be some situations where you want to clear the password in the
TextBox() and start again. This could be because you are checking a second
password or checking someone else’s password and you don’t want them to
see yours first. No good having a password that takes 3,000 years to crack
and then you accidentally show it to someone!
So, this next other thing to try is to add a button that clears the password. In
the # Function section of the program, create a new function below the
PasswordCheck(): which closes the GUI when a button is pressed.
def ClearPassword():
password_textbox.clear()
Next, we need to create a new button and assign the new function to the
command. This means that when the button is pressed, the program calls the
ClearPassword() function, which clears any characters in the TextBox().
In # App section of the program find the code where we create the buttons,
underneath these lines, add the new line of code to insert the button:
[CA]button_clear = PushButton(app, command=ClearPassword, text="Clear Passwo
Save the program (press F5) and run and test the new GUI. Enter some
random characters into the Text Box and then press the clear button.
This is an additional security feature that ensures that the user’s password is
secure before they can exit the program. To do this, when the program starts
the exit button is greyed out and cannot be clicked. It is not until the
password has passed all the checks that the button will be enabled (figure
7.14).
Figure 7.14 Final GUI with Clear Password and Exit buttons added.
Begin the edit by enabling the button in the PasswordCheck(): function. The
button is only clickable when all the checks are passed therefore the code is
added to the else clause underneath app.info(). Add the line of code:
else:
app.info("SECURE", "*** YOUR PASSWORD IS SECURE ***")
button_exit.enable()
Next, we define a function to close the GUI. As with all functions, we start
by creating the name and then include the line of code to display a message
that reminds the user to keep all their passwords safe. The last line of the
function code is app.destroy(), which closes the GUI. Locate the #
Functions section and type up the code below:
def ClosePasswordChecker():
app.info("Goodbye", "Remember to keep all passwords safe")
app.destroy()
To add the button to trigger the GUI to close, use the standard PushButton()
code and include the command command=ClosePasswordChecker and the text
label, Exit. When the button is pressed the ClosePasswordChecker()
function is called and closes the GUI. Add the line of code below directly
underneath the last button line of code in the # app section.
button = PushButton(app, command=PasswordCheck, text="Check Password")
[CA]button_clear = PushButton(app, command=ClearPassword, text="Clear Passwo
button_exit = PushButton(app, command=ClosePasswordChecker, text="Exit")
Finally, we only want the exit button to be clickable once the password goes
through the conditions in the if statement and is confirmed as a secure
password. To do this, we disable the button when the GUI first runs. This still
displays the button; however, it is greyed out and it stops the button being
clickable. Under the exit button code that you just typed up, add the last line
button_exit.disable().
To ensure that a password really meets the highest level of security, special
characters are always included as well as letters and digits. A special
character is a character that is neither a letter nor a digit. It is one of the
symbols usually found on the number keys on a keyboard. Common special
characters are ! @ # $ £ % ^ & * ( ) -+ ? _ = , < > /
Let us add the lines of code to the program to check for special characters;
this will ensure that the user has a really super secure password.
First locate the variable section of the program, which is currently empty, and
create a new variable called special_characters. Use a string to assign the
symbols, ! @ # $ £ % ^ & * ( ) -+ ? _ = , < > / to the variable. You do not
have to use all of them, just start with one or two to begin with and then build
up the symbols in the variable.
# Variables
special_characters = "!@£#$%^&*()-+?_=,<>/"
TIP
Good programmers start small and build up. That makes it easier to test and
debug your code. Then you can build up and add more special characters.
else:
app.info("SECURE", "*** YOUR PASSWORD IS SECURE ***")
button_exit.enable()
To run the new GUI, press F5 on the keyboard. You may be prompted to
save the program file. Choose OK and the program will save, and then the
program will run.
If you encounter any errors, or the program does not run as expected, then
check the section titled “Running and testing the GUI” for support and
solutions.
# Imports
# Variables
special_characters = "!@£#$%^&*()-+?_=,<>/"
# Functions
def PasswordCheck():
password = password_textbox.value
if (len(password)<12):
[CA]app.error("Length ", "Your password must be at least 12 characte
else:
app.info("SECURE", "*** YOUR PASSWORD IS SECURE ***")
button_exit.enable()
def ClearPassword():
password_textbox.clear()
def ClosePasswordChecker():
app.info("Goodbye", "Remember to keep all passwords safe")
app.destroy()
# App
app = App("Password Strength Checker", width=700, height=300)
app.bg = "White"
title_text = Text(app, "Password Strength Checker")
title_text.text_size = 28
title_text.font = "Impact"
#enter text
instruction = Text(app, text="Enter your Password Below")
password_textbox = TextBox(app, width=50)
#button
button = PushButton(app, command=PasswordCheck, text="Check Password")
[CA]button_clear = PushButton(app, command=ClearPassword, text="Clear Passwo
button_exit = PushButton(app, command=ClosePasswordChecker, text="Exit")
button_exit.disable()
app.display()
Statements of fact
Special characters are !@£#$%^&*()-+?_=,<>/ and can be used to make
a password more secure.
A loop is a section of the program code that repeats until a condition is
met. This is an efficient way to repeat sections of code by reusing the
same code.
A for loop repeats a section of code. The loop repeats for each item in a
string.
Typically in Python the letter x is used to hold each character in a longer
string, in this chapter the x is used to hold each letter in the password as
it is checked.
islower() checks for lower case letters and is useful for checking the
case of a string or character.
isupper() checks for upper case letters
isdigit() checks for digits in a string.
Elif is used to assess one or more conditions. The elif statement only
runs when the if condition is not met, this means the program does not
have to check every condition which saves processing time.
The not() operator returns a True or False value where a condition is
not met, this is useful for program responses where a condition is not
met.
elif not checks if a condition is not met. The program responds when a
condition is not met.
The any() function returns a value of True or False if at least one
element of any does not meet the condition. This is useful as you can
check the individual entries and characters in strings and lists.
Combining elif not and any() returns a value of True if at least one
element of the condition is not met and False if the condition is met.
Buttons can be enabled and disabled. This prevents a user from
accidentally clicking the button. The GUI can make a button available
only when certain conditions are met.
Appendix A. Installing Python on
Microsoft Windows
This appendix walks you through downloading, installing, and testing Python
on a Microsoft Windows computer. If you are using macOS or Linux, or
another operating system then check out appendix B which provides the
instruction to do this.
Python is a free programming language. This means that you can use Python
for free to create, edit, and share your programs. Python is popular because
you can use it to write programs for many different applications and
purposes. However, its real strength lies in the simplicity of using the code
compared to other languages. You can learn more about Python in appendix
D.
Getting Python
Let’s begin. The first step is to head over to the Python website and download
the Python install program so that you can install it on your computer. Open
your web browser, (like Chrome, Safari, Edge etc.) and go to
www.python.org. This will take you to the home page for Python. Over time
newer versions of Python are released, so remember to check this site
regularly if you wish to upgrade your version of Python at a later date.
When the Downloads page opens, the site automatically displays the most up
to date version of Python for the Microsoft Windows operating system. Click
the button to download the latest version.
Note
If you are using Mac or Linux, click the link underneath the download button
to navigate to the appropriate page. (Remember to check out appendix B for a
detailed guide on installing on macOS and Linux.)
To begin downloading the Python installation file, click the download button.
It’s okay if the version number is different from what you see here.
3. The Python installer loads the Optional Features window. All these
options are ticked. This is correct.
a. The first option, the first box, is to decide whether you want to
install Python for all users of the computer. Say for example that
you are using someone else’s computer. They might not want
Python installed. In that case, leave this option unticked. If the
computer is a shared computer and used by others who may also
want to build the projects in the book, then they will need Python
installed, so you can tick this button.
b. The second option, the fourth box is Add Python to environment
variable. This option is essential and must be ticked. The option
ensures that your Windows operating system can locate Python and
all Python’s associated files. Select the Add Python to
environment variable option.
5. After you have selected these two options you are ready to install
Python. Press the Install button. Unless you change the location, this
will install Python onto the C drive of your computer
8. Open the Windows start menu. If you are using Windows 10 then you
will see that Python has been added to the top of the menu under the
Recently added section. If you are using Windows 11 then simply type
Python into the search bar.
10. Locate the Python icon on your Windows task bar at the bottom of your
monitor’s screen. Right click and select Pin to Taskbar. This makes
Python always on your taskbar, which saves you having to look for the
program in the future.
1. In the IDLE Shell window, click where the >>> is displayed. The >>> is
called a prompt.
2. Type in this line of text exactly as it is shown here. This is programming
code!
print("Hello Python")
You’ve successfully installed Python and written your first program. If you
want to learn more about the Python programming language, then be sure to
check out appendix D for an overview of Python’s uses and functions.
Mu. This IDE describes itself as a “simple Python editor for beginner
programmers.” It has a nice eye-catching interface. Download here:
https://codewith.mu/.
Replit. This IDE is cloud based, which means you don’t have to
download and install any software. The advantage to cloud-based
software is that you can access you projects on any device that has a live
data connection or is connected to the Internet. Before using Replit, you
need to create a free account. You can access Replit at
https://replit.com/.
Thonny. This IDE describes itself as a “Python IDE for beginners.” It
provides a colorful user interface and has stripped out all the features
that may distract a user. Download here: https://thonny.org/.
Visual Studio Code. This IDE describes itself as “a lightweight but
powerful source code editor which runs on your desktop and is available
for Windows, macOS and Linux. It comes with built-in support for
JavaScript, TypeScript and Node.js and has a rich ecosystem of
extensions for other languages and runtimes.” Note that to run Python
code you must install an additional extension, and then you have to
configure the setup.
Appendix B. Installing Python on
other operating systems
This appendix walks you through downloading, installing, and testing Python
on operating systems other than Windows, such as macOS, or Linux, or
Chromebook.
Python is a free programming language. This means that you can use Python
for free to create, edit, and share your programs. Python is popular because
you can use it to write programs for many different applications and
purposes. However, its real strength lies in the simplicity of using the code
compared to other languages. You can learn more about Python in appendix
D.
There are other IDEs available although these alternatives may not run on all
operating systems. This book is written using the standard IDE that comes
with Python, which means that if you are searching for your own instructions
or videos, you should search for:
This will ensure that the guizero program will work correctly and you can
build the projects in each of the chapters.
Getting Python
Let’s begin. The first step is to head over to the Python website and download
the Python install program so that you can install it on your computer. Open
your web browser, (like Chrome, Safari, Edge etc.) and go to
www.python.org. This will take you to the home page for Python. Over time
newer versions of Python are released, so remember to check this site
regularly if you wish to upgrade your version of Python to the latest release.
Downloading Python
On the Python home page, find the navigation menu at the top of the website
and select the Downloads button. This takes you to the downloads page
where you can select which version of Python you want to install.
When the Downloads page opens, the menu displays all the download
options in a list. Click the tab for the OS that you are using, for example, if
you want to install Python on macOS, then select this option.
To begin downloading the Python installation file, click the download button.
It’s okay if the version number is different from what you see here.
There are many versions of Python available on the main website, so if you
are using a different OS, be sure to check out the downloads page.
Select the version that you want, usually the latest stable release and then
locate the Download and select the macOS 64-bit universal2 installer.
This will download the Python set up program. Once the Python installation
file downloads, on your computer, use the folder browser and head to the
folder where the Python installation file has been downloaded to. Locate the
downloaded Python file.
When you’ve found the file, select it (usually double-click) to start installing
Python. You will be presented with a menu window that has several steps.
For further details and a video see this weblink,
https://www.jcchouinard.com/install-python/#Install_Python_on_MacOS.
Many versions of Linux already have Python installed so the first step is to
check if it is installed.
If the response displayed says that Python cannot be found, then it means that
Python has not been installed. Linux may then provide you with a set of
instructions covering how to install Python, follow these and Python will
install. If not then follow these simple steps,
If this does not work then you may need to install Python using pip, follow
these instructions,
Other versions
There are many versions of Python available for many operating systems,
including those that run on tablets and mobile devices. Check out the
Alternative Implementations on the downloads page to find out more.
Testing your installation of Python
Now to test that Python has installed correctly and is working. Complete the
following steps,
6.
The Python Shell shows the words Hello Python underneath the line of
code you just wrote.
You have successfully installed Python and written your first program. If you
want to learn more about the Python programming language, then be sure to
check out the projects, and of course, read and try all the examples in this
book.
Appendix C. Installing guizero on
other operating systems and
features of guizero
You may remember from chapter 1 that GUI stands for Graphical User
Interface and is pronounced “gooey.” A GUI offers an easy way for the user
to interact with a computer or device using graphics and images. Guizero is a
programming library that contains all the code and widgets to create and
build GUIs in Python.
There are several methods to install guizero onto your computer and it has
even been designed so that you can simply download the program files and
build GUIs.
The Easy Install method is useful if you are not permitted to download and
install software on your computer. For example, if you do not have the
required access permissions, or you are using a computer that you share with
other people. Maybe you are using someone else’s computer and they do not
want you to install additional software!
The last section of this appendix covers the key features of the guizero. Let us
start with the Easy Install method first.
Easy installation
This installation is the simplest and easiest as it requires no installation of the
software and therefore no special permissions or administrators’ rights. To
use this method, complete the following steps.
5. Select the Download Zip option. This downloads the guizero files.
6. Open the ZIP folder. This folder contains a folder named guizero-
master.
7. Open the guizero-master folder.
8. Select all the files and folders and copy all the files into a folder on your
computer.
Important
Now all your GUI projects and code will run, as long as you save your
Python file into the same folder as the guizero files. You can read more
details at the official guizero website https://lawsie.github.io/guizero/.
1. Open the terminal window click selecting Applications > Utilities >
Terminal (or type terminal into the search bar).
2. In the terminal window type pip3 install guizero.
3. Press Enter to install guizero.
There are other versions of Linux. If you are using the Debian version, then
you can install guizero in the terminal using the following command:
sudo apt-get install python-guizero
Table C.1 Installing additional guizero features using the pip command
Note
These additional image features are not available if you use the Easy Install
method.
Upgrading guizero
Over time, guizero will be updated and you will want to keep your version up
to date. If you installed guizero using pip, then you can upgrade guizero in
the terminal window using the commands in table C.2.
Features of guizero
For ease of understanding guizero and its features, you can split guizero into
two distinct groups. Group one contains the main categories of the software
(table C.3). These categories are called elements and are the overall building
features of a GUI. Elements allow you create interactivity between the user
and the GUI. Interactivity is where, for example, the user presses a button,
and the GUI displays a message via a popup. Or the user presses a button,
and it triggers a sound to play.
These elements also enable you to build a GUI. For example, using the
Layout element, you can adjust the size of the GUI window and position
buttons and text within the GUI window. With the ‘Events’ , you can
program an action to respond (called triggering an action) when something
happens; for example, when a user double-clicks the left mouse button on a
picture, some text is displayed.
The second group is widgets. Widgets are how you physically build the GUI;
they are the main building blocks of a GUI. There are fifteen widgets that you
can use. Each one is an object (think of objects as an item) that appears
within the GUI, everything from the app itself to text boxes, buttons, and
pictures. Some of the widgets are used with the Elements of the GUI. For
example, the Box widget is a container that holds other widgets and is useful
for neatly grouping them together. The Box widget is used as part of the
Layout Element to create and customize the layout of the GUI. Table C.4
describes what all the guizero widgets do.
Some widgets are similar but have different properties. For example, the
PushButton widget creates a clickable button, whilst the ButtonGroup widget
creates a button with options where the user can select from several choices.
You will use the widgets throughout the various projects, and you can refer to
tables C.3 and C.4 as required.
The reason is because GitHub uses version control. Version control is a way
to keep track of all different versions of documents, such as program files.
Consider the example where you start writing a program and over the course
of developing it you make 10 changes to the code. If you are using GitHub,
then each of the previous 9 versions are stored and available on GitHub. This
means that if you break the program code you can return to a previous
version that worked. Furthermore, you can share any of these versions with
other people without the worry that they will destroy or break the current
code.
This appendix tells you how to get the project files from GitHub.
https://github.com/TeCoEd/Twisted_Python_Projects
This takes you to the main page of the book’s repository where it is possible
to download all the code and resources. The repository will also always
contain the most up to date versions of the code.
Figure D.1 Press the Code button. You will get a dropdown menu with options.
Locate the Download ZIP option at the bottom of the menu and press it. This
will start the process of downloading a ZIP folder of all the files to the
Downloads folder on your computer. Once complete, you can extract and
open the folder and use the files as required. This is the fastest way to get all
the program code and resources from the book.
1. Click the Project_Codes link which will open and display the chapter
folders (figure D.2).
Figure D.2 The Project_Codes folder contains code for all the chapters
2. Then select the required chapter folder and click it, for example, chapter
3 Fart_Box (figure D.3), which opens the folder and displays all the
resources and the code for that project.
4. Next locate the download button toward the top right of the window and
press it (figure D.5). Pressing this button downloads the program file to
your Downloads folder, where you can access the file.
5. An alternative option to access the code is to click the middle icon, the
Copy raw file option. Pressing this button copies the code. Open your
Python editor and you can then directly paste the program code into it.
Downloading image and sound files.
Files which are not program files, such as the images and sound files, can be
downloaded in a similar way. For example, the Chapter_3_Fart_Box folder
contains an image file. To download this image,
1. Click the file name of the image. This opens the image in a new window
where you can view it (figure D.6).
2. Click the download icon to save the image to your Downloads folder.
3. An alternative download method is to right-click on the image and select
the “Save image as…” option from the drop down menu. Select the
folder location where you want to save the image and press Save.
1. If there are several audio files, first open the folder that contains the
audio files.
2. Click the name of the audio file that you want to download.
3. A new window opens. This window displays the words “View raw”.
4. Click either the View raw or the download icon to download the file to
your device.
Remember that for guizero to access and use the downloaded files they need
to be in the appropriate folder. (guizero will not automatically link to the files
in the Downloads folder.)
Ensure that you move the files to the required folders. These folders are
referenced in each chapter. You can use your own folder locations and file
names, but ensure that you edit the file location information in your program
code to match this.