The Ultimate Guide to Python Programming for Beginners by Megabyte Publishing
The Ultimate Guide to Python Programming for Beginners by Megabyte Publishing
F B
Y 7-D G T S P
E C W H -O E
T U C O
© Copyright 2023—All rights reserved.
The content contained within this book may not be reproduced,
duplicated or transmitted without direct written permission from the
author or the publisher.
Under no circumstances will any blame or legal responsibility be held
against the publisher, or author, for any damages, reparation, or
monetary loss due to the information contained within this book, either
directly or indirectly.
Legal Notice:
This book is copyright protected. It is only for personal use. You
cannot amend, distribute, sell, use, quote or paraphrase any part, or
the content within this book, without the consent of the author or
publisher.
Disclaimer Notice:
Please note the information contained within this document is for
educational and entertainment purposes only. All effort has been
executed to present accurate, up to date, reliable, complete
information. No warranties of any kind are declared or implied.
Readers acknowledge that the author is not engaged in the rendering
of legal, financial, medical or professional advice. The content within
this book has been derived from various sources. Please consult a
licensed professional before attempting any techniques outlined in this
book.
By reading this document, the reader agrees that under no
circumstances is the author responsible for any losses, direct or
indirect, that are incurred as a result of the use of the information
contained within this document, including, but not limited to, errors,
omissions, or inaccuracies.
Table of Contents
Preface
For the Readers
Writing Conventions
Unveiling Python: From Its Origins to Global Prominence
What is Python? A Brief History
Why Should You Choose Python as Your First Programming
Language
Easy to Learn
Easy to Read and Write
Syntax Is Simple
Abundance of Resources
Open-Source and Free
In-Demand
Large and Supportive Community
How Python Differs From Other Languages
Python vs. JavaScript
Python vs. Node.js
Python vs. Java
Python vs. Ruby
Python vs. PHP
Python vs. R
Python vs. C++
Python vs. C#
Where Does Python Stand Today
The Pros and Cons of Python
Pros
Cons
Introduction
But Why Python?
Chapter 1: Python Fundamentals
Getting Started
Before You Do—Installing Python the Smart Way
For Windows
For Mac
For Linux
Instal Python
Installing Python on Windows
Installing Python on Mac
Installing Python on Linux
Installing Your IDE
IDLE
PyCharm
Visual Studio Code
Sublime Text 3
Atom
Other IDEs and Code Editors
Your First Step to Code
Python Variables
How to Name Your Variables the Right Way
The Data Types in Python
Integers
Float
String
Boolean
List
Dictionary
Tuple
Set
Exercises
Exercise 1
Exercise 2
Chapter 2: Python Basic Operations and Input/Output
Basic Operations in Python
Arithmetic Operations
The Arithmetic Operators
Addition
Subtraction
Multiplication
Division
Modulus
Exponentiation Operator
Floor Division
String Concatenation
Using the + Operator
Using the * Operator
Using the join() Method
Using % Operator
Using format() Function
F-string Method
Python User Input and Output
Comments
Exercises
Exercise 1
Exercise 2
Chapter 3: Control Structures and Data Collections
Conditional Statements
Comparison and Logical Operators
Logical Operators
Loops and Iterations
For
While
Break
Continue
Pass
Lists and Dictionaries
List Operators
Diving Deeper Into Dictionaries
Exercises
Chapter 4: Python Functions and Modular Programming
Introduction to Functions
The Syntax of a Function
Parameters and Return Values
Functions With No Parameter
Scope and Variable Lifetime
Exercise
Simple Calculator
Chapter 5: Advanced Data Structures in Python
Tuples
Accessing Items Inside a Tuple
Sets
Modifying Sets
List Comprehension in Python
Set Operations
Set Union
Set Intersection
Set Difference
Set Symmetric Difference
Exercise
Chapter 6: The Basics of Object-Oriented Programming (OOP) Using
Python
Basics of Python OOP
Classes and Objects
Objects
Creating Class Methods
Inheritance and Polymorphism
Extending Classes
Method Overriding
Exercise
Chapter 7: Error Handling and Debugging in Python
What Is Error Handling in Programming?
What Is Debugging?
Understanding Exceptions
Types of Exceptions
NameError
TypeError
ValueError
IndexError
IndentationError
ZeroDivisionError
ImportError / ModuleNotFoundError
AttributeError
KeyError
Python Debugging Techniques
Using the Print Statements
Using Python Debugger
Using the Logging Module
The Try and Except Statements
Recommended Workflow of Debugging for Beginners
Exercise
Chapter 8: Python File Operations and Data Storage
Reading and Writing Files
File Access Modes on Python
Opening Files
Closing Files
Writing
Reading
Appending
Working With CSV Data in Python
Opening a CSV File
File Modes
Closing a CSV File
Reading a CSV File
Writing on CSV Files
Read CSV File Into Dictionaries
Writing CSV File From Dictionary
Handling Errors
Working With JSON Data in Python
JSON Serialization
Deserialization
Exercise
Bonus Challenge
Chapter 9: Fundamentals of Python Web Development
Introduction to Python Web Development
The Basics of Framework—Flask
Step 1—Installing the Virtual Environment
Step 2—Creating an Environment
Step 3—Activating the Environment
Step 4—Installing Flask
Step 5—Testing the Development Environment
Building a Simple Python Web App
Routing
Flask HTTP Methods
Using Templates
Exercise
Chapter 10: Introduction to Python Game Development
Project Overview
Preparing for the Project
Pros
Cons
The Right Option
PyGame Tutorial
Import and Initialize
Create a Game Window
Updating Games Using Loops
Drawing Graphics
Creating a Working Game: Circle Escape Challenge
Importing Modules and Initializing Pygame
Setting Up the Display Window and Display Variables
Define Colors, Shapes and Player variables
Game State Control
Create the fonts for the Score and Instructions
Display Functions
Game Loop
Full Code - Circle Escape Challenge
Code Challenge
Conclusion
Preface
File names are typically displayed in italics. This style indicates that
the text represents a suggested file name you might encounter in
your programming journey.
NOTE: E-Readers will not always display these differences. In our
testing, code does highlight with a different background color. Other
text such as variable names, output and even command line
instructions may not have the same format as shown in the print
version of the book.
Unveiling Python: From Its Origins to Global
Prominence
Learning any language is an exciting prospect. While most people
learn languages that they rarely use, programming languages are
slightly different. Programming is about being creative, thinking out
of the box, and doing something different. It grants you the power
to create something, and the great feeling of knowing you can do
that is just incredible.
Ever since Python was invented, it has gone on to attract the
attention of the world, and the programming community at large,
and it continues to draw a lot of attention. While its simplicity is the
leading reason why everyone wants to learn Python, the rise of AI
and machine learning are two other driving reasons.
If that wasn't enough, almost every leading business school today
teaches Python and some of its libraries to business graduates. You
might wonder how the two relate, and you wouldn't be wrong to
assume that a business graduate has nothing to do with
programming. However, Python proves to be a vital piece in their
academic journey. Using Python, business analysts can filter, refine,
and extract data. They can work up charts, export data into files, and
simplify everything for them and their clients.
Python continues to make a case for itself, and it is safe to assume
that Python is here to stay. With all the technological
advancements, such as AI and machine learning, knowing Python is
becoming a skill garnering a lot of attention and demand. Therefore,
let's understand exactly what Python is, where it came from, and
why it has become so popular.
What is Python? A Brief History
For years, there have been many programming languages that have
been created for a variety of purposes. Each of them boasts an
advantage while also lacking in some departments, and it's easy to
see why that was the case.
The first language, invented by Ada Lovelace, surfaced in 1843. She
created the entire language on paper because computers had not yet
been invented. Her programming language was best described as a
machine algorithm.
After a century, between the years 1944–45, the first actual
programming language was invented by Konrad Zuse. This
programming language was called Plankalkül (better known as
Plain Calculus). What this language did was to allow the creation of
procedures. Procedures were chunks of recallable code that could be
used to carry out various operations. Sure enough, it caught on.
Around 1949, just a few years after Zuse's language, another
language made itself known to the world: the assembly language.
For those who may not know, programming languages have levels,
high and low. The low-level languages are generally system-level
programming. These are difficult to read and, for someone who has
never programmed before, almost impossible to comprehend. Low-
level languages create the basic structures for software that
eventually interact with hardware.
The assembly language remains the first low-level language, was
popularly used, and is still under use today. Of course, this was hard
to learn, meaning that it was only natural someone would come up
with something slightly better and more understandable. Besides, a
low-level language could only carry out limited operations.
During the same year, Shortcode was also introduced. Unlike the
assembly language, Shortcode was the first high-level programming
language that John McCauley invented. A high-level language is
what some of the most popular programming languages are, such as
Python. You can use high-level languages to carry out various tasks,
operations, and more.
Three years later, in 1952, Alick Glennie developed Autocode, a
language he created for use on the Mark 1 computer at the
University of Manchester. What truly made Autocode a hit was that
it was the first-ever compiled language. Unlike any other language
before it, this was the first language ever where a compiler would
translate the code into binary code, a series of zeros and ones that
the computer understands, without needing to do that manually.
This saved a lot of time and allowed programmers to do so much
more than before.
Next came the FORTRAN in 1957, which stands for Formula
Translation. It was created by John Backus, and it remains the
oldest high-level programming language still in use today. This
programming language could easily perform scientific, statistical,
and mathematical operations.
The world of programming language was now populating faster than
ever before. Every bright mind was developing some new and
ingenious way to compute and create programs. In the ten years
since FORTRAN was invented, four additional languages were
invented. These were:
After Microsoft's massive success at the start, the race to find better
programming languages took a new turn. From there, the world
went on to welcome PASCAL, a language that was quickly favored
by another tech company named Apple. The language was easier to
use, offered more flexibility, and was something Apple preferred
using for all its projects.
In 1972, Smalltalk made its debut. While this wasn't such a
phenomenal hit, it was still fascinating that you could modify code
on the fly. Many of the programming languages of today, such as
Python, owe their success to Smalltalk. Even today, companies like
Logitech and Leafly continue to use Smalltalk for their tech stacks.
In the same year, the world was also greeted by arguably the most
significant programming language phenomenon of its kind: C.
Dennis Ritchie developed it at the prestigious Bell Telephone
Laboratories. He developed this language to be used with a Unix
operating system. By now, A and B, two more programming
languages, already existed, but they were not even close to being as
powerful and effective as C.
C gave the world an opportunity that it so desperately needed.
Because of C, many other off-shoots or derivatives came to life.
These included:
1. C#
2. Java
3. Perl
4. Python
5. PHP
6. JavaScript
Web development
Cybersecurity
Software development
Game development
Data Analytics
1. Speed to develop
2. Resources for the language
3. Trends in the industry
1. Data sciences
2. Research
3. Game development
4. Software engineering
5. Marketing and advertising
6. Ethical hacking and cybersecurity
7. Data analysis
8. Business reporting
9. Data extraction and filing
10. Web development
11. Machine learning
12. Artificial intelligence
13. Biology and bioinformatics
14. Computer vision
15. Image processing
16. Neuroscience
17. Psychology
1. Google
2. Intel
3. YouTube
4. PayPal
5. Facebook (Now known as Meta)
6. Amazon
7. Spotify
8. Dropbox
9. Netflix
10. Disqus
11. Pinterest
12. Uber
13. Reddit
14. Instagram
15. Instacart
16. IBM
17. JP Morgan Chase
18. Stripe
Cons
Not as fast as C or Java.
Memory intensive.
Does not support multithreading.
Can be misused or overly used.
With all said and done, it all comes down to one question: should
you use Python? The answer to that is "Yes!" You should choose and
learn Python as your first, third, or even the 10th programming
language. The fact is that Python's popularity is on the rise, and
almost every other major firm is switching towards Python. Then,
there is the fact that Python can be used for various reasons and
projects, which means that you'll probably end up using Python for
the project you've been considering.
Learning Python is significantly more beneficial if the entire
emergence of artificial intelligence and data sciences inspires you.
Python is the go-to language for all these projects, so you will also
need to learn Python to make the most of the opportunity. Besides,
you may not be willing to spend 3 to 4 years learning a single
language and may be in a bit of a hurry to get into the world of
programming. Python, as it happens to be, is your quickest entry
into programming. It's easy to learn, doesn't take much time, and is
very easy to use.
Introduction
Data scientists,
Data mining,
Web applications,
Games,
Machine learning,
Artificial intelligence,
Deep learning,
Hacking and cybersecurity.
For Mac
Mac users also have a few options, just like Windows users do.
However, before you go ahead and install Python on your Mac, it is
good to consider the following:
For Linux
Installing Python on Linux can be tricky, especially if you do not
know what you're doing. Unlike Windows and Mac, Linux has
distros or "flavors," which are essentially different versions of the
same OS. You will have a unique interface, a different package
manager, and so on, depending on your version.
If you
use a
Debian-
based
distro,
you
probably
use an
apt
package
manager
. If you
use a
Red Hat
based
distro,
you'll
use
yum.
Once you know what distro-specific package manager you are using,
you can easily install Python into your system.
With that said, let's dive in and install Python, starting with
Windows.
Instal Python
Installing Python on Windows
To install Python on Windows, make sure your Windows is updated.
If you have any pending updates, use Windows' update manager
first. Once all updates are installed, open your favorite browser and
head to www.python.org.
Step 1
The first step is to decide which version of Python you'd like to
install on your system. For most, it will be the latest version.
However, experienced programmers may require specific and older
versions of Python. You can find those under the Downloads
section.
Step 2
Once you've decided which version you'd like to install, hover your
mouse to where it says "Download" and click the button underneath
"Download for Windows" to start the download process.
Alternatively, you can click on "Windows" underneath "Download,"
this will take you to a page where you can see all the various
versions available for your chosen operating system. Find the
version you need and click the "Download" button to start
downloading.
Step 3
Once the download is complete, click on the executable file that has
been downloaded earlier. This will start the installer and the
installation process.
Be sure to check both the boxes at the bottom before proceeding
with the installation.
Step 4
After the installation, click "close" to close the installer window.
Now, it is time to verify whether Python is installed successfully or
not. To check that,
Step 5
Next, you want to verify that pip was installed successfully as well.
Pip is a very powerful and useful package manager that you can use
for Python packages. To check,
1. Open up terminal.
2. Type either "compgen -c python" or "python3 --version" and
hit enter.
3. You may also want to try "python --version" as your system
may have Python 2 installed.
Once you've ensured that you do not have the latest version of
Python installed (which happens to be 3.12.0 at the time of writing
this book), do the following:
With that, you should now install Python on whatever system you
use. However, we aren't done yet. To use Python properly, we need
an Integrated Development Environment (IDE), a software to help
you use and operate Python and other languages.
Installing Your IDE
For every programming language, you generally require an
integrated development environment. IDEs are what you'd call
software designed to help you harness the true power of any given
programming language that it supports.
Many IDEs these days come loaded with additional functionalities
and features. The goal of an IDE is to help you code better, debug
faster, and identify errors even before you execute a program to
ensure that your code doesn't crash. Sometimes, the IDEs can help
you learn how to code more efficiently by offering suggestions.
Furthermore, IDEs can help you keep track of your variables, which
is quite a good thing. In the past, most programming was done
either on Notepad or very old interfaces. All they offered was the
ability to code, compile, and export. Finding errors in a code would
be like finding a needle in a haystack. Today, all of that is done in
seconds.
Through the use of IDEs, you go on to improve your productivity by
using powerful features and functions built-in. It is also important
to note that not all IDEs can support Python, and not all IDEs
support other languages. Some are made exclusively to handle
specific types of programming languages, while others offer vast
support for various languages. Since we'll be using Python, it is a
good idea to familiarize ourselves with some of the most popular
and powerful IDEs for Python today.
IDLE
IDLE stands for Integrated Development and Learning
Environment. It is the default editor that comes with Python pre-
installed. IDLE is the go-to choice for those new to Python who
wish to get the hang of things.
You can use IDLE to learn Python, level up your skills, and even
work on initial projects before moving on to other IDEs. IDLE is
fully supported by Mac OS, Windows, and Linux, so installing IDLE
shouldn't be a problem. For this book, we will also be using IDLE.
PyCharm
PyCharm is an open-source, free-to-use IDE developed by JetBrains.
They are considered the masters of their craft, and that can be seen
in PyCharm, an IDE designed specifically with Python on their
minds. It is one of the most commonly used IDEs for Python today
and offers some of the most excellent and powerful tools known to
developers.
Now, you might be thinking, why not start with PyCharm if it is so
good? Well, the thing is that PyCharm is best suited for large-scale
Python projects. Since it has built-in support for JavaScript, CSS,
and TypeScript, it is best suited for those who know their way
around Python and would like to up their skills and projects to a
new level. Once you're done learning Python using IDLE, this is
where you need to go.
Visual Studio Code
Just like PyCharm, Microsoft created its own open-source and free
IDE. It is another great option for those using Python parallel to
other languages. It is lightweight and easy on the hard drive, too.
However, it stands out by offering many features that other IDEs
offer in their paid versions, and you get all of that for free.
Sublime Text 3
Sublime Text has been around for a while and is considered one of
the most popular code editors. With that, it is worth noting that
Sublime Text is a code editor and not exactly a full-fledged IDE. Its
goal is to help programmers code and edit codes. Because of its
niche focus, it offers lightning-fast development speeds and
reliability.
Atom
Atom is yet another popular open-source code editor that GitHub
develops. It is similar to Sublime Text and has almost the same
features you'd find in Sublime Text editor. Like Sublime Text editor,
it is also free to download.
Other IDEs and Code Editors
Jupyter
Sypder
PyDev
Thonny
Wing
Vim
GNU/Emacs
Eric
Dreamweaver
Visual Studio
Pyscripter
Rodeo
Hit enter/return, and the rest will be done for you. After the
installation, you'll see IDLE on your desktop. For Windows and Mac
users, search for IDLE, and they should be able to find it easily. It is
time to click and open IDLE to get a taste of the interface and type
in our first code.
Your First Step to Code
Exciting, isn't it? You're just moments away from typing in some
code and seeing a response. As all great programmers have done
before, we will start with Hello World. This simple program asks
Python to print out the words "Hello" and "World." How do we do
that? Let's find out.
Open up IDLE if you haven't done so already. Once it is open, you
should see the version of your Python at the top, followed by some
other messages. Your cursor, by default, would be placed next to the
>>> signs. This is where you will be typing in the following code:
print("Hello World")
Remember, all codes that we will do are case-sensitive. This means
that if you type in Print instead of print, it won't work. Therefore,
getting used to this type of typing is a good idea.
Once you've entered the code above, press the enter/return key.
VOILA! You just did a thing. If things went well, which they did,
you'll be able to see Hello World written in blue. That's the output
of the command you just used.
Yes, it's probably not as exciting as you may have thought, but the
goal is to take things slowly and go step-by-step. You might also be
wondering what is print, why the parenthesis, and what's with the
quotation marks. To understand that, let's start learning the basics
of Python.
Python Variables
Variables are just like empty containers. When you create them,
they can store some form of value in them. They can hold on to that
value for as long as you want. Their values can be modified,
changed, altered, or removed altogether.
Every programming language uses variables to store and recall
values. They serve as the building blocks for any code of any
programming language. They come with a reserved memory
location where they can store values. If you recall, Python has a
built-in garbage collection feature that dis-allocates and frees up
memory as you go along. This means we don't have to worry about
using more memory than we need.
Unlike other languages, we can create new variables easily using
Python. To create a new variable in Python, you do not need to
declare the kind of variable you create. For example, if you created a
variable containing whole numbers, such as 10, we'd first need to let
the compiler know, "Hey! I want to create a variable with an integer
value of 10." Of course, that's not exactly how you'd do that.
However, we don't have to worry about that in Python. How? Let's
have a look.
In the example below, we will create two new variables, var1 and
var2. These variables will have random numbers as values, say 312
and 944, respectively. To do this, return to your IDLE screen and
type in the following code.
var1 = 312
var2 = 944
Now, let's see if these values were correctly stored, and for that, we
want the system to print out the values individually. You do that
using the print() function, as shown below.
print(var1)
print(var2)
You should now be able to see the values as a result. It does look
easy. That's because it is. With that in mind, there's something
every programmer, new or old, must know and practice: naming
convention.
How to Name Your Variables the Right Way
You don't want to name variables a, b, xyz, uhd, or any of that. While
no one's stopping you from doing that, it's considered bad practice.
Why? Let's say you're a developer and have been tasked to handle a
project that someone else coded. As you go through the codes, you
come across variables with names like:
alpha
beta
var-z
tes1
None of these names will make any sense. You will never be able to
determine what exact purpose these variables serve unless you go
through hundreds or thousands of lines of code before you get an
idea. However, this can easily be avoided by correctly naming your
variables.
The name of your variables must make sense to any programmer of
any level. Therefore, if your variable is a character's name, it should
say something like char_name so that when you or any other
programmer sees it, they immediately know what this variable is
for. Similarly, if you are creating a variable for a high score, it
should say something like high_score or h_score.
Now that you have that in mind, it's time to learn how to type those
variables correctly using the correct naming convention.
To name a variable the correct way, you will need to do the
following:
With these rules in mind, let's look at how to type these names
properly. There are three types of conventions that you can use to
write your variable names. These are:
1. Camel Case
A. The first word must always be lowercase.
B. The first letter of every word that will follow is in
uppercase.
C. No space between words.
D. Example:
i. myNewVariable
ii. studentCount
iii. myNextLevel
2. Pascal Case
A. The first letter of every word is to be uppercase.
B. No spaces.
C. Example:
i. MyNewVariable
ii. StudentCount
iii. MyNextLevel
3. Snake Case
A. Add an underscore between each word.
B. No space between words.
C. Can use upper- and lower-cases at will.
D. Example:
i. my_New_Variable
ii. Student_count
iii. my_next_level
Using these, you can now name your variables. It's best to name
your variable with a simple name that shows precisely what they
should do. This will always help you and other programmers who
may work on your code to know what these variables should do.
The Data Types in Python
Every programming language comes with its own unique data types.
A data type defines what kind of value a variable will be storing. For
example, in the previous example, we used the word "Integer"
instead of a number or a whole number. That is because an integer
happens to be a data type found in all programming languages.
When it comes to Python, there are eight data types:
1. Integers
2. Float
3. String
4. Boolean
5. List
6. Dictionary
7. Tuple
8. Set
Integers
Integers are the most basic types of data a variable can store. When
a variable stores a particular data type, it changes its type.
Therefore, if my_var holds the value of 10, it becomes an integer
variable. Of course, you will need to specify this in other languages.
On the other hand, Python is smart enough to figure that out
independently.
To create an integer variable, type the variable's name and assign it
a value.
my_var = 10
Float
Integers aren't just any numbers, though. Remembering that
integers are numbers without any decimal points is a good idea.
When you add a decimal point to the value, it is classified as a float.
To declare a float, type in a name for your variable and assign it a
value:
my_float = 10.0
A float is a data type that holds numeric values with decimals.
Therefore, 10 is an integer, but 10.0 is not. The latter is classified as
a float value. That makes sense, right? However, what if you want to
store letters or words as your values? Where do they go? For that,
you need a data type called string.
String
String is a data type that stores letters, words, and even sentences.
You can store even paragraphs and paragraphs into a single variable
as long as the memory allows. Creating a string variable is slightly
different from the previous two data types.
To create a string variable, you start as usual and name your
variable. After the assignment sign (=), you use double quotes
before and after the letters or words you want to store. This lets
Python know you're trying to create and store a string value.
Therefore, if you want to store the value of "I am a Programmer" in
the variable my_job, you'll need to type this:
my_job = "I am a Programmer"
Now, go ahead and print this variable to see how it works.
Boolean
This is an unusual but quite useful data type. Unlike any other data
type in Python, this data type can only store two values: True or
False. This data type makes your code behave a certain way using
logical inputs and outputs.
Programmers use Boolean (or Bool) to create conditions and check
conditions and outputs, which can help make the program more
responsive and intelligent. To declare a Boolean variable, you do the
following:
sit_A = True
sit_B = False
If you like, you can use the following code to verify the values.
sit_A = True
sit_B = False
print("sit_A =" , sit_A)
print("sit_B =" , sit_B)
This will print out the following:
sit_A = True
sit_B = False
Of course, that's not exactly how we will use Boolean values. We
will use these in more complex situations, but we'll do that later.
List
As the name suggests, a list holds a group of values. For example,
you would like to store three names in the variable name. To do
that, you will need to do the following:
name = ["Joey" , "Ross" , "Chandler"]
Now, a single variable has three different values stored in it. To
recall these values, ask Python to print names, and you will see all
the names printed.
Remember, to declare a list, you must use the square brackets [ ].
Lists are handy because you can access individual components and
values anytime. For example, if you were only aiming for Python to
print "Ross" as an output, you'd do the following:
print(name[1])
This will print out Ross. You might wonder why Ross was the
second value, not the first. However, we will learn more about why
that is the case when discussing indexing.
Dictionary
The dictionary works a lot like lists. The difference is that a
dictionary stores a group of values in pairs instead of just single
values. Let's say you have the following data that you must store:
item_1 = butter
item_2 = egg
fruit = banana
You'd probably store them in three different string variables in any
other circumstances. That will take up more memory than needed.
A much more efficient way to store these will be through a
dictionary. To do that, you'll need to do the following:
shopping_cart = {"item_1" : "butter" , "item_2" : "egg" , "fruit" : "banana"}
Now, if you were to ask Python to print shopping_cart, it will show
you the following results:
{'item_1': 'butter', 'item_2': 'egg', 'fruit': 'banana'}
Dictionaries are excellent if you want to store data regarding specific
things, such as employee name, ID number, role, etc. It is also
important to note that dictionaries use curly brackets unlike lists,
which use square brackets { }. Every group is defined by the use of
the colon (:) symbol. The comma (,) is used to separate one pair
from another.
Tuple
Tuples are also quite like lists and dictionaries. They, too, store
multiple values in them. However, these can store multiple types of
data in order. Once a tuple is created, you cannot alter its value,
something you can do with dictionaries and lists.
To create a tuple, you use the regular brackets ( ), as shown here:
Today_Date = ("Sunday", "29th", "October", 2023)
This will store both string and integer data type values in the
variable Today_Date.
Set
The set is exactly like a tuple. The only difference is that you can
modify the values of a set, something you can't do with a tuple. To
create a set, use the curly brackets minus the colons and double
quotation marks we use for dictionaries.
my_set = {1, 2, 3, 4, 5, 6, 7}
Exercises
Now that you know how to create variables and store different
values, let's put that knowledge to the test before moving toward the
next chapter. I know this chapter was quite long, but now, you're
ready to move into the actual programming side.
Exercise 1
Exercise 2
Once you're done, it's time to move forward to the next chapter and
get started with coding.
Chapter 2: Python Basic Operations and
Input/Output
"Good code is its own best documentation."
–Steve McConnell.
Now that we know the data types and how to create variables and
store values, it is time to start coding. Right away, we will start with
basic Python operations, such as arithmetic and concatenation, and
then move on to input and output. Once again, be sure to have IDLE
open and ready to go. If you previously have values stored, it's a
good idea to shut the application down properly and restart IDLE so
that you start with a clean slate.
Basic Operations in Python
Arithmetic Operations
Like any other programming language, Python can carry out large
arithmetical operations with efficiency and finesse. While we will
not be diving into super lengthy arithmetical operations for now, we
aim to understand what kind of arithmetic operations you can carry
out and how.
The Arithmetic Operators
When it comes to Python, you can use the following arithmetic
operators to carry out a variety of operations. Each symbol shown
below is called an operator and tells Python the exact kind of
arithmetic operation that must be carried out.
1. Clark = 86
2. Barry = 51
3. Bruce = 92
So, how do these work? Let's take an example and use the data we
already have (marks from our three students).
# Grading Software
name = input("Please Enter Your Name: ")
print("Hello, ", name + "! Welcome to Our Grading Software!")
#marks to be stored as integers
marks = int(input("Enter your marks: "))
print("Fetching your grade. Please wait!")
#grade variable initialized, but the value will be decided based on marks
grade = ""
if marks >= 90:
grade = "A" #value of grade will automatically update depending on
marks achieved
print("Your grade is: ", grade)
elif marks >= 80:
grade = "B"
print("Your grade is: ", grade)
elif marks >= 70:
grade = "C"
print("Your grade is: ", grade)
elif marks >= 60:
grade = "D"
print("Your grade is: ", grade)
else: #for all other marks that are below 60
grade = "F"
print("Your grade is: ", grade)
print("Thank You for Using This Software!")
In the above, we have created a simple grading software that asks
users for their names and their marks. Based on the marks, the
program checks with all the conditions to see where it fits.
Depending on that, it returns a value for grade and provides it to us
as an output.
Using the code above, try to put in various numbers to see how it
works. Be sure that you only try integers and not float values.
Regarding conditional statements, we use if, elif, and else in that
specific order. However, you can always use if and else alone when
you do not have a third option or do not wish to provide one.
For example, a game character has arrived at a crossroads. The
character can either go left, or it can go right. There is no third
option here. In such a situation, you will only use if and else. One
will define a direction, and the other will be the only alternative.
That said, it is vital to understand how these codes work correctly
and what you should do to ensure they are written with the best
practices.
For if statements:
If (define condition):
#statement goes here (with indentation)
This is the same for elif statements as well. However, for other
statements, notice how there is no condition defined. To use else
statements, you do the following:
else:
#statement goes here
For all statements, you must end the else condition with a colon (:).
IDLE is smart enough to identify that you're typing in a conditional
statement. That is why the moment you press enter, it will leave an
indent. Having this indent is good as it makes the code more
readable.
With that said conditional statements need some other components
to work. You may have already noticed how we used > and =
symbols. These are just some logical operators conditional
statements need to perform flawlessly. Let's learn these and find
out what they do.
Comparison and Logical Operators
It is safe to say that all conditional statements are essentially
comparisons. A given value is compared with the statements before
the program makes a decision. To help do that, we need comparison
operators, and you saw three of those earlier.
The following are the comparison operators you can use to compare
situations:
The and-operator will return a bool value of True only when both
conditions are met. The or operator will return as True when either
one of the conditions is met. The not operator will return as True
when the condition is not met.
Let's look at a simple example and see how logical operators can
help us create better logic. For this example, we will create a simple
pre-qualification software to decide whether a person is eligible for
a loan.
For this, we will need a few things:
Be 25 to 40 years old.
Be currently working.
Be making at least $65,000 a year.
Not have any previous bad debts.
Now, there's a problem. If we type in the usual way, we will see that
we can only set one condition, as shown below:
if age > 24:
Using this will quite literally approve anyone who types their age
above 24. They'll be approved even if they have a bad credit history
or have no job. That's a problem. Therefore, we can use the and
operator here to help us create logic.
# Loan Application Software
# Data of applicant (input required by user)
print("Welcome to Your Bank! Please fill out the form below!")
f_name = input("Please, enter your first name: ")
l_name = input("Please, enter your last name: ")
age = int(input("Please, enter your age: "))
work_status = int(input("Are you currently working? 1 for yes, 2 for no: "))
income = int(input("Please, enter your yearly gross salary: "))
b_debt = int(input("Do you have any previous bad debts? 1 for yes, 2 for
no: "))
print("Thank you! Please wait while we process the information.")
if age in range(25, 40) and work_status == 1 and income >= 65000 and
b_debt == 2:
print("Congratulations! You are eligible to apply for a loan!")
else:
print("Unfortunately, your loan application does not meet our
requirements!")
print("Thank you for choosing Your Bank! Have a great day!")
In the above, you might have noticed two things:
You can use as many "and" or any other operator in the code as long
as it makes sense. As far as the range function is concerned, we used
that to ensure the age condition sticks to the range we need. We will
talk more about functions and methods later on, but we'll stick to
this for now.
Using the code above, try the program with different inputs and see
how the program behaves. Of course, this isn't the most convenient
way of writing code. So many things can be done to make the code
look and feel a lot nicer. However, since we are beginning, it's okay
to keep things as neat and sensible as possible without getting into
too many complexities.
Logical operators help us keep our codes more relevant and concise.
If you were only to use conditional statements, the same code
would end up longer, something like this:
# Loan Application Software
# Data of applicant (input required by user)
print(“Welcome to Your Bank! Please fill out the form below!”)
f_name = input(“Please, enter your first name: “)
l_name = input(“Please, enter your last name: “)
age = int(input(“Please, enter your age: “))
if age >= 25:
if age > 40:
print(“You’re age is higher than our maximum required age!”)
exit()
else:
print(“You’re too young for a loan application!”)
exit()
work_status = int(input(“Are you currently working? 1 for yes, 2 for no: “))
if work_status == 1:
print(“That’s great!”)
else:
print(“Since you do not have a job, you are not eligible for a loan!”)
exit()
income = int(input(“Please, enter your yearly gross salary: “))
if income >= 65000:
print(“You appear to have a higher income than the required minimum
level, great!”)
else:
print(“Your income currently does not qualify for a loan!”)
exit()
b_debt = int(input(“Do you have any previous bad debts? 1 for yes, 2 for
no: “))
if b_debt == 2:
print(“Everything looks good here!”)
else:
print(“You are not eligible for a loan!”)
exit()
print(“Congratulations! You appear to be eligible for a loan!”)
print(“Thank you for choosing Your Bank!”)
See the difference?
Loops and Iterations
Next, we have something called loops. As the name suggests, loops
are used when you wish the program to loop through a range of
values, carry out multiple iterations of a command in a swift go, and
carry on doing this until the condition is satisfied.
To use loops, Python uses two reserved keywords:
1. for
2. while
For
The for loop is used when you wish to iterate over a given range of
numbers or sequences. This can be a list, a range, a dictionary, a
tuple, a string, or even a set. If you already have exposure to
programming, it is worth noting that this for is very different from
the one you may be used to seeing.
In Python, the for loop executes a given set of statements for every
item within the given list, set, et cetera. The loop will continue to
function until the given condition is no longer true or until it is
ultimately achieved. Let's see this in action:
my_fruits = ["Apple", "blueberry", "cherry", "orange"]
We created a list named my_fruits in the above variable and inserted
four values. Now, we want Python to print the content of the list. To
do that, we will need the for loop.
#x is a loop variable that is local to the loop only
for x in my_fruits:
print(x)
The outcome will be as shown below:
Apple
blueberry
cherry
orange
The for loop will go through each value, print it, move on to the
next, and continue until all the lists' elements are printed.
You can also go through a string and have individual components of
the string printed separately.
for x in "pomegranate":
print(x)
This will print out the following:
p
o
m
e
g
r
a
n
a
t
e
While
Besides for loops, Python also has while loops. This kind of loop
continues for as long as the condition remains true. The moment it
stops being true, the loop is terminated.
i=0
while i < 10:
print(i)
Before
you
execute
this,
though, it
is crucial
to
understan
d that this
will lead to
a system
crash.
Why?
Reread the code and see if you can find out what the apparent
problem is.
Yes! The variable i will always be 0, and it will always be less than
10. This means that the loop will never end, and that will crash
IDLE and probably the system. To overcome that problem, we want
to ensure that we instruct Python to add increments after every
iteration.
In the first go, i will be 0. For the next iteration, we want it to be 1,
then 2, and so on. To do that, we must add the following line of code
just underneath the print(i) command.
i=0
while i < 10:
print(i)
i += 1
The += is an incremental sign that tells Python to increase the value
of the variable on the left by one every time it loops. You can also do
the opposite and have -= 1, which will decrease the value of i by one
for every iteration.
Now, if you run the above code, you'll get:
0
1
2
3
4
5
6
7
8
9
Since the condition stated Python would print i as long as it
remained less than 10, it did just that. When it became 10, the
condition was no longer true, and the loop was terminated.
With that in mind, let's explore some control statements we use
with for and while loops. These are great to ensure that we aren't
stuck in a never-ending loop and to do some additional things.
Break
Let's say you have a list of five items. You want the for loop to go
through all the iterations and stop when it comes across the value
"Orange." You will need to use a break statement to do that.
These statements are beneficial to ensure that the loop doesn't
continue forever. When a condition is met, the loop will go to the
next line, read break, and stop executing further. This helps prevent
your program or system from crashing.
cart = ["apple", "banana", "blueberry", "orange", "cheese"]
for x in cart:
print(x)
if x == "orange":
break
Now, if you execute this, you will find the following:
apple
banana
blueberry
orange
With that said, what do you think will happen if we do the
following?
cart = ["apple", "banana", "blueberry", "orange", "cheese"]
for x in cart:
if x == "orange":
break
print(x)
In this case, Python will only print the first three values and stop
the minute it reaches orange. This is because Python goes through
its code line by line. Therefore, once it realizes it is dealing with
orange, it will understand that the if conditional statement is met. It
will then move to the following line to check what it must do, and it
immediately sees break, and that ends the code there. It will not take
into account the print(x) anymore.
Continue
Besides break, you may sometimes want the for loop to continue
even after it has found what you were looking for. In such a case,
you can use the continue keyword, as shown below:
cart = ["apple", "banana", "blueberry", "orange", "cheese"]
for x in cart:
if x == "orange":
continue
print(x)
The output, however, will be as shown:
apple
banana
blueberry
cheese
Once the value matches the condition, the loop will skip that over
and move forward to carry out its process to completion.
Pass
For loops are never meant to be empty. Having one can often cause
things to go wrong. However, there will be instances where you may
need to write a for loop and then leave it empty until a better use is
found or a certain condition is met for them to execute.
For empty loops, we use something called a pass statement. The pass
statement lets Python know, "Hey! It's okay! I did that deliberately.
Ignore this for now!" Python will skip over it and move on with the
rest of the program. How does it work? Quite simple!
for x in [10, 11, 12]:
pass
In the above case, Python will skip over this line of code and move
on. The pass statement can often be used as a placeholder for future
code you will write later. Not having the code at this time is not
essential to debugging and testing certain conditions.
Lists and Dictionaries
"Wait, didn't we cover that already?" We did, but we only touched
upon what these are and how to create them. Remember we said
we'll look into indexing and other aspects later? Now's the time.
Lists and dictionaries, to serve as a refresher, allow us to store
multiple values in a single variable. A list can contain numerous
values in an ordered manner. A dictionary, on the other hand,
contains data in pairs. Lists are created using the [] brackets,
whereas dictionaries are created using the { : } format. Now, we will
look deeper into these, starting with list operators.
List Operators
You can create a list with an empty value and populate it later.
How? Here's how!
my_list = []
What this will do is create a list variable named my_list. However, it
will have no item in it. To add items to the list, we use append. To
access this function, we do the following:
my_list = []
print(my_list)
print("List is empty")
my_list.append("First item")
print(my_list)
Notice how we used a period (.) before the word append. Using a
period allows you to access methods and other functionalities
available to a given variable. One of the available ones happens to be
append. Append is used to add items to a list. It adds the item to the
very end of the list. In the above case, the result will now look like
this:
[]
List is empty
['First item']
However, notice what happens here.
my_list = []
print(my_list)
print("List is empty")
my_list.append("First item")
print(my_list)
my_list.append("Third item")
my_list.append("Second item")
print(my_list)
[]
List is empty
['First item']
['First item', 'Third item', 'Second item']
The result shows the first, third, and second items, in that specific
order. Why? This is because append only adds one item at a time,
and it does so right at the end of the list. This brings us to an
important question: how do you remove items from a list? That's
simple! Just like append, we can use remove.
my_list.remove("Third item")
print(my_list)
['First item', 'Second item']
From there, you can use append to make the adjustments to the list.
However, that does seem somewhat time-consuming. Indeed, there
must be a more efficient way to remove a value in a particular
position in the list. Well, there is.
Let's say you have a long list of items inside a list. You want to
remove the item that is entered and stored at position number 4.
You don't want to first print out the list, find out what's at number
4, and then restart all over again. Instead, you just want to tell
Python "Whatever's in 4th place, remove it." Here's how you can do
just that.
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
del my_list[3]
print(my_list)
"Wait. I said 4th, not 3rd."
We knew you'd say that. However, trust us and execute the code to
see what happens.
[1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12]
"How?"
This is precisely what we were talking about. Whenever you
populate a list, you place each item in a specific index position.
Unlike our numbers that start with 1, the first item in the list has an
index value of 0. If you want to remove the 4th item, you'll be
targeting index number 3.
index number = n - 1
This is a simple formula for you to remember. This will help you
know exactly what index number you want whenever you are
aiming to delete or even access individual values. Once you delete
the value at index number three, it will replace it with the next
element. Therefore, if you were to try and find out what lies at index
number 3 after the above, you'll see the following:
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
del my_list[3]
print(my_list[3])
5
See what we mean?
Now, let's say you want to remove the value at index position 5, and
then you want the system to store it as a separate variable. How do
you do that? One way is to print the entire list, find out what value
lies at the given index number, and then create a unique variable
with that value. This will be time-consuming and somewhat
counterproductive as you must remove the value from the list
separately to avoid glitches. There's an easier way to do that. We do
that by using the pop() function.
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
my_num = my_list.pop(5)
print(my_num)
print(my_list)
6
[1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12]
Python could easily remove the value '6' and store it as a separate
variable. With that said, if there's a way to remove specific elements
at specific index values, shouldn't there be a way to add specific
values at specific positions, too? Well, there is. For that, we use the
insert() function.
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
my_num = my_list.pop(5)
print(my_num)
print(my_list) # print for comparison
my_list.insert(5, 6) # alternatively my_list.insert(5, my_num)
print(my_list) # includes 6 which was popped earlier
6
[1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Through insert(), we could add the value '6' on the 5th index
position. Remember, for insert() to work correctly, you must first
specify the index number followed by the value you wish to insert.
Let's create another list. This time, we will create a list with random
numbers.
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
The above list has a lot of elements, and we were not bothered to
count how many elements it has. We can ask Python to help us with
the len() function.
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
print(len(my_list))
This will print out 8, meaning that this list has eight values stored
in it. We can do more things with our list as well. For example, we
can ask Python to order this list in reverse. To do that, we use the
reverse() function.
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.reverse()
print(my_list)
This will generate the following results:
[75, 37, 28, 86, 19, 71, 103, 11]
We can also use the sort() function to sort a list in order.
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.sort()
print(my_list)
The list will now be sorted from lower to higher values. You can also
ask Python to sort the list out in reverse order by doing the
following:
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.sort(reverse=True)
print(my_list)
[103, 86, 75, 71, 37, 28, 19, 11]
Now, the list is sorted in reverse. This can often be very useful in
real-life scenarios and programming situations.
Let's say we want to split this list into two separate variables:
first_half and second_half. To do that, we will use the slicing method.
first_half = my_list[:4] #list[start:end] where we specify end as index 4
second_half = my_list[4:] #we specify starting after index 4
print(first_half)
print(second_half)
[11, 103, 71, 19]
[86, 28, 37, 75]
Let's say you now want to combine these two lists. How do you do
that? Well, there are a few ways you can do that:
The first one is straightforward to do. You simply add the two lists
as shown below:
my_list = first_half + second_half
This will add the two together. The second method is worth looking
into as it is a very clever way of adding the lists together using the
for loop:
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.sort(reverse=True)
print(my_list)
first_half = my_list[:4]
second_half = my_list[4:]
print(first_half)
print(second_half)
for x in second_half: #loop will iterate through all elements of second_half
first_half.append(x) #will add elements of second_half into first_half
print(first_half)
Now, your first_half list will be a complete singular list. However,
there is a third way to do this as well, and that is by using the
extend() function:
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.sort(reverse=True)
print(my_list)
first_half = my_list[:4]
second_half = my_list[4:]
print(first_half)
print(second_half)
first_half.extend(second_half)
print(first_half)
Once again, your first_half list will have all the elements from
second_half.
If you want to remove all the values from a list, you can use the
clear() function:
my_list = [11, 103, 71, 19, 86, 28, 37, 75]
my_list.clear()
print(my_list)
This will take away all the values from the list.
Diving Deeper Into Dictionaries
With the lists sorted, let's see how dictionaries can be accessed,
modified, cleared out, and used.
The first thing to note is that dictionaries use keys unlike lists. They
do not work with index numbers. Instead, they use keys to recall
values.
grade_key = {"A" : 90, "B" : 80, "C" : 70, "D" : 60}
min_for_A = grade_key["A"]
print(min_for_A)
We created a dictionary with pairs of keys with their values in the
above. Key "A" has a value of 90. Key B has a value of 80, and so on.
We then created a variable to determine what marks are required to
achieve grade A. We assigned this new variable the value of
grade_key["A"], which is 90. If you execute the program now, it will
show you 90 as the result.
To make it more interesting, let's add another key pair where grade
"F" has a value of 0. To do that, we will add the grade value and key
using the following method:
grade_key["F"] = 0
print(grade_key)
{'A': 90, 'B': 80, 'C': 70, 'D': 60, 'F': 0}
To access a particular value in the dictionary, we rely on keys.
Therefore, if you want to find out the value attached to the key pair
of C, we will do the following:
print(grade_key["C"])
This will fetch us the value attached to this key pair. Here, 'C' is the
key to access the value. You can also use the get() method to acquire
the value, as we did above.
print(grade_key.get("C"))
This will fetch you the value of the key pair C. You can also find out
what keys are stored in a given dictionary, in case you're not the
original programmer and wish to find out. To do that, you can use
the keys() method:
print(grade_key.keys())
This will fetch all the keys for you, as shown below:
dict_keys(['A', 'B', 'C', 'D', 'F'])
Similarly, you can also find all the values stored inside a dictionary.
To do that, use the values() method:
print(grade_key.values())
dict_values([90, 80, 70, 60, 0])
If you wish to see all the items inside a dictionary, use the items()
method:
print(grade_key.items())
dict_items([('A', 90), ('B', 80), ('C', 70), ('D', 60), ('F', 0)])
To remove an item from the dictionary, we use the same pop()
method as we did in the lists:
grade_key.pop("F")
This will remove the key pair of "F" and update the dictionary. To
clear the entire dictionary, you can use the clear() function:
grade_key.clear()
This will remove all the key pairs from the dictionary, leaving you
with an empty dictionary that you can populate again.
Exercises
Now, it's time to bring all that we have learned and put it to some
use. Below is a sample code that you can alter to your liking. The
goal is to create a program on your own that has at least one
working loop and at least one conditional statement.
# Import the random library to generate random numbers
import random
# Initialize variables
target_number = random.randint(1, 100) # Generate a random number
between 1 and 100
user_guess = 0
attempts = 0
# Welcome the user to the game
print(“Welcome to the Number Guessing Game!”)
# Use a while loop to allow multiple guesses
while user_guess != target_number:
# Capture the user’s guess using the input() function
user_guess = int(input(“Guess a number between 1 and 100: “))
# Increment the attempts counter
attempts += 1
# Use a conditional statement to check the guess
if user_guess < target_number:
print(“Too low! Try again.”)
elif user_guess > target_number:
print(“Too high! Try again.”)
else:
print(f”Congratulations! You’ve guessed the correct number
{target_number} in {attempts} attempts.”)
# End of the game
print(“Thank you for playing the Number Guessing Game!”)
With that said, let's move on to the next chapter and learn all about
functions and modular programming.
Chapter 4: Python Functions and Modular
Programming
"Don't repeat yourself. Every piece of
knowledge must have a single,
unambiguous, authoritative representation
within a system." –Anonymous
Writing code is fun but can quickly become annoying and
cumbersome. This is particularly true when you write large blocks
of code repeatedly. If only there were a way to somehow store all
that massive block of code into a single line you could recall
whenever you wanted. Fortunately for us, there is.
In this chapter, we will learn not only how we can store these blocks
of code but also how to use them properly, and to do that, we start
by understanding what functions are.
Introduction to Functions
A function is a large block of code designed to carry out a specific
job or function. As it turns out, Python has many built-in functions
that come pre-loaded. This means you already have hundreds, if not
thousands, of functions at your fingertips. What's more, Python
allows you to create custom-made functions to help you carry out
extensive operations through a single-line function recall.
Functions are reusable, meaning you can use them in a single
program as often as you like. These are created to serve particular
functions. For example, the print() function prints out information
on the console.
Functions also serve another essential purpose; they organize your
code correctly and make it more manageable. Yes, the first time you
define a function (create), you must type in a few lines, but after
that, you'll only use the function's name followed by the parenthesis
(). Let's say you have around 50 lines of code to define a custom
function you want to use in your program. The next time, you will
use only the name, such as:
my_func()
With that single line and a few characters, you will recall and
execute all the lines without ever having to copy and paste them
repeatedly. This helps you save time, energy, and resources.
Besides, functions are great for debugging, a process where you go
through code to find out what's not working.
The Syntax of a Function
When creating a function, we use the keyword def, which stands for
define. Whenever you define a function, all the code is
automatically indented. This is to ensure ease and to facilitate
debugging later on. Let's create a sample function to print "Hello
Everyone!"
def my_func():
print("Hello Everyone!")
my_func()
We first defined a new function in the above code and named it
my_func. Next, we coded what we wanted this function to do in the
indented code. Once that is done, we type in the name of the
function, and it carries out whatever we want it to do. It's that
simple.
Let's have a little fun with function by creating a simple game where
the computer tells you if your chosen number is odd or even.
def my_func():
var1 = int(input(“Enter a number: “))
if var1 % 2 == 0:
print(“You have chosen an even number”)
else:
print(“You have chosen an odd number”)
my_func()
We used a simple conditional statement where if the chosen
number is perfectly divisible by two and has 0 as a remainder, it is
an even number. Anything else is an odd number. Go ahead, try it
out!
Generally speaking, most applications and games start with several
functions well before the app is used. This is called pre-loading, and
this is usually done using functions. Programmers code in functions
and call these functions the moment the app is opened.
When you define a function, you can also pass something called
arguments. Arguments are additional information or directions for
the compiler to follow. The basic syntax to do that looks something
like this:
def new_func(arg1, arg2):
#code goes here
For example, you have a function where you want to add two
numbers together that you input when calling the function. To do
that, you first need to define the function in the following manner:
def addTwoNum(num1, num2):
print(num1 + num2)
This creates a function where it takes in two arguments, which are
two separate numbers. The function is coded to print out the sum of
the two numbers. Now, let's recall and see what's what:
addTwoNum(19, 22)
41
Do you see how that worked out? Every time you recall this
particular function, you must pass two values through for this
function to work. This is because we have set two arguments as
defaults. We can set as many arguments as we want.
Let's make another function and use what we call a return statement:
def multiNum(num1):
num1 * 10
res = multiNum(21)
print(res)
In the above, we defined a function called multiNum. We passed a
single argument. The function will take a value as an argument and
multiply that by 10. Next, we created a variable called res to store the
resulting number as its value. However, if you execute this code,
you end up with the following result:
None
Why is that? That is because we haven't defined whether it must
return a number or a value within the function. In the case of the
print() function we used earlier, it was an explicit instruction to
print. Sometimes, you may not want the function to print out
values. Instead, you'd want it to return a value and send it outside
the function. To do that, we'll need to use the return statement, as
shown here:
def multiNum(num1):
return num1 * 10
res = multiNum(21)
print(res)
Now, the function will return the value of num1 * 10. While it will
still not print it, it will store that value successfully in the variable
res. Since it exists outside the function block, res will be successfully
printed. Try it!
Parameters and Return Values
Functions have both arguments and parameters, and these terms
are often used interchangeably. While that isn't completely wrong,
they do technically vary from one another.
Arguments are variables passed within the parentheses after the
function's name when you are defining the function. There can be
as many arguments as you like, each separated by a comma.
#arg1 and arg2 are arguments
def sample_func(arg1, arg2)
Parameters, on the other hand, are almost identical. The major
difference is that these variables pass through a function when the
function is called. This is the key and probably the most noticeable
difference. Therefore, it is a good idea to familiarize yourself with
these two terms to avoid confusion in the future.
#par1 and par2 are parameters used during recall of function
sample_func(par1, par2)
You can also create functions with default parameter values. Doing
so will allow you to call up a function without an argument. In this
case, it will use a default value you've passed while defining the
function.
def my_func(city = "Austin"):
print("I hail from " + city)
my_func("New York")
my_func("Chicago")
my_func("Claymont")
my_func() #Here, the default value will be used
I hail from New York
I hail from Chicago
I hail from Claymont
I hail from Austin
Functions With No Parameter
You can also create functions with no parameters. To show this, let's
start by creating a dictionary of items for groceries. We will then
create a simple function to print out the list of items with their
quantities.
s_list = {"bread": 2,"eggs": 12,"coffee": 1,"bananas": 6,"sugar": 1}
def show_list():
for item, quantity in s_list.items():
print(f"{quantity} x {item}")
show_list()
Now, as soon as you execute the program, you will be presented
with a list that looks like this:
2 x bread
12 x eggs
1 x coffee
6 x bananas
1 x sugar
In such cases, you don't need to pass any parameters or arguments
to a function. Depending on what you aim to do with your function,
you can decide whether or not the function requires additional
input. To do that, it is recommended that you know exactly what
your function is meant to do. The more precise you are, the easier it
will be to create a function.
Scope and Variable Lifetime
You may have noticed earlier that we use some variables generally
while some are only limited to loops or conditional statements. This
is because every variable we create in Python has its scope.
When it comes to Python, the scope is the region of a program
where a given variable can be used and accessed. In the case of
Python, there are two types of scope variables. These are:
1. Global
2. Local
Global scoped variables are defined within the main program and
remain outside the function's body (not defined inside a function's
block of code). These variables will remain visible throughout the
program and can be accessed at any given time.
A global variable can also be accessed when you are defining a new
function, as shown below:
#Global variable
a = 20
#declaring a function with local variable
def showMe():
print("Local scope =", a)
showMe()
print("Global scope =", a)
Local scope = 20
Global scope = 20
A local scoped variable, however, is limited in terms of access and
reach. These are generally defined or created during the creation of
a function. This variable, being local, cannot be accessed outside a
function, meaning you cannot independently use it anywhere else
but within the function itself.
#local variable
def showMe():
a = "Morning time"
print("Local scope =", a)
showMe()
print(a)
Local scope = Morning time
Traceback (most recent call last):
print(a)
NameError: name 'a' is not defined
The error above shows that the variable 'a' is not defined. This is
because it was called outside the function's body and never existed
in the rest of the program.
There is also a third type of scope called non-local, which exists
inside a nested function. A nested function is one where you are
defining a function within a function. In such a case, the nested
function's variable will be termed a non-local variable.
Exercise
Using all that we have learned, create a simple function that
calculates the average of given numbers and returns the value that
can be stored in a variable.
To give you an example, here's a sample to seek inspiration from:
def average(numbers):
return sum(numbers) / len(numbers)
print(average([1, 2, 3, 4, 5])) # Output should be 3.0
Simple Calculator
This one is slightly challenging but quite fun. The goal is to create a
simple calculator using your coding knowledge. To help you get
started, here are the steps you need to take, followed by a sample
code:
1. Initialize variables.
2. Create functions for arithmetic operations (addition,
subtraction, multiplication, division).
3. Create a menu.
4. Capture the user's input.
5. Create a main program loop.
6. Complete the code.
# Initialize variables
first_number = 0
second_number = 0
result = 0
# Function for addition
def add(x, y):
return x + y
# Function for subtraction
def subtract(x, y):
return x - y
# Function for multiplication
def multiply(x, y):
return x * y
# Function for division
def divide(x, y):
if y == 0:
return "Cannot divide by zero."
return x / y
# Function to display the menu
def display_menu():
print("Simple Calculator Menu:")
print("1. Add")
print("2. Subtract")
print("3. Multiply")
print("4. Divide")
print("5. Exit")
# Function to capture user input
def get_numbers():
global first_number, second_number
first_number = float(input("Enter the first number: "))
second_number = float(input("Enter the second number: "))
# Main program loop
while True:
display_menu()
choice = input("Choose an option (1-5): ")
if choice in ['1', '2', '3', '4']:
get_numbers()
if choice == '1':
result = add(first_number, second_number)
elif choice == '2':
result = subtract(first_number, second_number)
elif choice == '3':
result = multiply(first_number, second_number)
elif choice == '4':
result = divide(first_number, second_number)
print(f"The result is: {result}\n")
elif choice == '5':
print("Goodbye!")
break
else:
print("Invalid choice. Please try again.\n")
With that, it's time to move on to the next chapter and learn all
about the advanced data structures we use in Python. They're
essential, and they are certainly going to come in handy.
Chapter 5: Advanced Data Structures in Python
"Data is the new oil." –Clive Humby
While we learned a little about tuples and sets, they are more
powerful and somewhat more advanced to cover in just a few
paragraphs. That is why we didn't dive too much into those in the
previous chapters. This ensured we built a solid foundation and
understood some core concepts before diving into these.
When you want to take Python programming up a notch, you must
use tuples and sets. Therefore, this chapter will walk you through
both, reinforce previously learned knowledge, establish new
concepts, and help you understand these better.
Tuples
Tuples, unlike lists, are immutable, meaning they can neither be
altered nor modified. Once you have created a tuple, the container is
sealed. What remains inside remains with no room for any
additional tampering or addition. You can still use the values stored
inside tuples, which is why these are handy when you want to use
specific values that you know must remain constant.
When you create a tuple, you need to remember that a tuple uses
round brackets, just like functions do. You will also need to ensure
that you create the tuples correctly as errors can lead to problems.
To highlight just how mistypes can cause issues, here's an example:
mytup = ("Cat",)
print(type(mytup)) #type() shows the data type of the variable
mytup = ("Cat")
print(type(mytup))
Before you execute the code above, what do you think the outcome
will be? Will both the variables be reflected as tuples? Well, try it
out and see what happens.
<class 'tuple'>
<class 'str'>
Surprised? Let me explain. Whenever you are creating a tuple, you
not only use the round brackets, but you also need to use a comma.
You do this even if you are storing a single value in it.
"Can't I just initialize a tuple and populate it later?"
Recall the critical difference between a tuple and a list: A tuple is
immutable, meaning once it is created, it cannot be altered,
modified, or changed in any way. We can use the tuple to check the
values it stores, use them, and call upon them, but we cannot
append, remove, or pop any values.
This is why it is imperative to think through all the scenarios
beforehand when creating a tuple. You don't want to create a tuple
to find out you need to add more variables or alter values later.
Once it is created, it cannot be altered.
Accessing Items Inside a Tuple
This works quite like the list. This means you must rely on the
index numbers to find and access individual items within a tuple.
There are two ways you can do this:
Let's create another tuple and add five elements to that. These are
five random numbers.
myTup = (15, 17, 9, 237, 44)
print(type(myTup)) #to verify that myTup is indeed a tuple
Let's see how we can print out individual elements at index
numbers 0, 2, and 4.
myTup = (15, 17, 9, 237, 44)
print(type(myTup))
print("Value in myTup[0] is ", myTup[0])
print("Value in myTup[2] is ", myTup[2])
print("Value in myTup[4] is ", myTup[4])
<class 'tuple'>
Value in myTup[0] is 15
Value in myTup[2] is 9
Value in myTup[4] is 44
That's done quickly through the use of positive index numbers.
However, what's the deal with negative index numbers? Do they
even exist? Let's find out.
For this example, we will use the same code above. However,
instead of the index values 0, 2, and 4, we will use -4, -2, and -1 to
see what happens. You can use other values, too, if you like.
myTup = (15, 17, 9, 237, 44)
print(type(myTup))
print("Value in myTup[-4] is ", myTup[-4])
print("Value in myTup[-2] is ", myTup[-2])
print("Value in myTup[-1] is ", myTup[-1])
<class 'tuple'>
Value in myTup[-4] is 17
Value in myTup[-2] is 237
Value in myTup[-1] is 44
Do you see what happened here? The order changed. Instead of
going from left to right, the system is now going from right to left.
This can often prove to be helpful if you have a larger tuple.
Tuples are great for yet another reason. They are extremely fast
when compared to lists. This is because tuples do not occupy a lot of
memory and are significantly faster in operation and recall. If you
know your variables and which ones will remain unchanged
throughout the program, store those in tuples where and when
possible.
Sets
We also looked at sets briefly at the start of the book. Lists are
ordered collections of items. Sets, however, are an unordered
collection of a variety of items. Unlike tuples, these can be created
and then modified. However, the elements, once created, remain
immutable. You can still add and remove from the sets, but the
stored values cannot be altered or modified.
That said, it is important to note that sets will not take in and store
any duplicate items. Therefore, if you try to store a value already in
a set, it will end up in an error.
You use the curly brackets, or the {}, to create sets. This does not
include any colon ":" symbols as you find in a dictionary. Like
tuples, sets are highly optimized and are much more efficient at
checking elements inside a set when compared to a list. These are
more efficient and do not take up many resources.
The significant difference between sets and lists is that list items
can be accessed using the index numbers. However, you cannot use
index numbers to access items inside a set. This is because sets are
unordered. Anything that is unordered cannot be accessed using
index values.
Let's create a sample set for ourselves and use that to see how
things work.
mySet = {"one", "two", "three", "four"}
print(type(mySet))
<class 'set'>
Modifying Sets
Let's start by looking at the add() method.
mySet = {"one", "two", "three", "four"}
print(type(mySet))
print(mySet)
mySet.add("five")
print(mySet)
<class 'set'>
{'two', 'one', 'four', 'three'}
{'three', 'two', 'one', 'five', 'four'}
Your values will continue to jump around every time you run the
code. As we mentioned earlier, this list has no specific order, hence
the unordered tag. Since the values keep hopping around, there is
no way to know which index number a particular value will be on
the next time, which is also why you cannot access items within a
set using index numbers.
To remove an element from the set, you use the discard() method:
mySet.discard("four")
This will discard the value of "four" and update the set accordingly.
Things are a little tricky to create an empty set. You see if you were
to do the following:
newSet = {}
That will create an empty dictionary, not a set. To create an empty
set, you use the set() function, as shown here:
newSet = set()
This will initialize a new and empty set that you can populate as you
go along.
List Comprehension in Python
We know how to manually create a list, but there's one more way.
You can create a list from an existing list or other iterables within
your code through a process called list comprehension.
Every list comprehension contains:
Polymorphism
Inheritance
Encapsulation
And more
Considering the scope of this book, we will only be covering the first
four aspects, as the latter two can be pretty advanced.
Classes and Objects
Let's first start by understanding objects. An object is nothing more
than a code entity that a programmer creates. Every object has
attributes and behaviors that allow it to function in a specific
manner.
A class, on the other hand, is the blueprint for objects. It is this
blueprint that then facilitates the creation of objects. As it stands, a
class is a logical entity and holds some methods and attributes.
Many classes may already exist in Python, but you also have the
power to create your own classes as you see fit. Let's take the
following example to give you an idea of how vital and helpful
classes are.
Let's say you want to find out the age and the breed of dogs.
Generally, you would create two lists. One will handle the breed,
and the other will hold their ages. However, if you were to deal with
over 500 dogs, how would you handle that? Creating lists after lists
is undoubtedly not how you want to do things, as that can be very
hectic and messy regarding clean code writing. Instead, you create
classes.
To create a class, there are four rules to remember:
With that said, let's look into the basic syntax of how a class is
created:
class SampleClass
#Your First statement goes here
.
.
.
.
.
.
#Your nth statement goes here
You can also create empty classes by using the pass statement:
class SampleClass:
pass
Objects
Now that you know the classes, we move on to the next step and
learn all about objects.
We know that objects are created thanks to classes. Their behavior
is linked to their parent classes. Everything we have learned about
thus far, such as variables, dictionaries, lists, integers, and strings,
are all objects.
Objects consist of a few things:
Let's create a class and call it Dog. We will need this class to create
objects to see how the state, behavior, and identity of the object
work:
class Dog:
# class default attribute
attr1 = "furry"
# Instance attribute
def __init__(self, name):
self.name = name
# Creation of object
Bruce = Dog("Bruce")
Tom = Dog("Tom")
# accessing attributes from the class
print("Bruce is very {}".format(Bruce.__class__.attr1))
print("Tom is also very {}".format(Tom.__class__.attr1))
# accessing instance attributes
print("This is {}".format(Bruce.name))
print("This is {}".format(Tom.name))
In the above code, we started by creating a class named Dog. First,
we set a default attribute or state, "furry." Next, we defined an
instance attribute. An instance attribute is an attribute that only
belongs to one object. This means that as long as the objects are
created using the same class, only they can access this attribute. Any
other object that isn't created using the same class will not be able
to access this attribute.
The __ init __ is called a constructor and is a special method used to
initialize an instance of a class. By default, it has one parameter
(self). Self is a reference to the instance being created. In our case,
we added one more parameter, name. This attribute will be applied to
every instance of the class.
Next, we created two objects using the following syntax:
object = class()
In our case, we created Bruce and Tom. We passed the names as
attributes while calling upon the class. That name will only apply to
individual objects and cannot be shared with others.
Finally, we printed the class attributes for each object followed by
their names (using the instance attributes).
"That's quite complicated."
Don't worry. We have a simpler way of doing this to get you into the
zone. Let's look at another example. For this, we will create a new
class named Cat. This time, we won't be using many complicated
ways. Instead, we'll use a far simpler approach:
class Cat:
# class attribute
name = ""
age = 0
# creating cat1 object
cat1 = Cat()
cat1.name = "Casper"
cat1.age = 2
# creating cat2 object
cat2 = Cat()
cat2.name = "Whiskers"
cat2.age = 5
# accessing attributes
print(f" {cat1.name} is {cat1.age} years old") #print(f"") is formatted
printing - easier to do
print(f" {cat2.name} is {cat2.age} years old")
"Yes. This seems simpler."
It really is. In this example, we created a class, gave it some empty
but straightforward attributes, and then headed straight to the code.
We created two objects and then defined their attributes further.
Finally, we printed information out using the attributes of each
object.
Creating Class Methods
Objects have attributes, but they also have methods. These are class
methods, and they are defined just as functions. The only difference
is that these are defined slightly differently:
# Adding a method to the Dog class
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print("Woof!")
# Using a method
my_dog = Dog("Buddy")
my_dog.bark()
Here, we created a class, defined it using the constructor, and then
defined a method. Since it was created in this class, this method will
now be exclusive to this class and its related objects only.
Inheritance and Polymorphism
Inheritance is precisely what it sounds like. It establishes a
relationship between any two given classes. One class is the
superclass, better known as the parent, while the other is the
subclass, better known as the child.
Every child keeps all the attributes and methods as inheritance from
its parent class. Furthermore, it can add new attributes and
methods, allowing it to evolve and grow more powerful. Where
required, a child class also can override methods of the parent's
class as well:
class Father(object):
def buy_pizza(self):
print("yummy")
class Son1(Father):
pass
class Son2(Father):
pass
Father().buy_pizza()
Son1().buy_pizza()
Son2().buy_pizza()
In the above, we created a parent class named Father and passed
object as its parameter. Next, we defined a simple method, buy_pizza
and asked it to print the word yummy.
Then, we created two more classes and passed Father as their
parameter. What we did there was tell Python to designate these
classes as child classes. As a result, these classes ended up
inheriting everything the parent class had. In this case, it was a
method.
Once we called the method for each class, they all printed the same
message. This is because the child classes inherited the same
method, values, and everything else. Besides, a father will always
buy enough pizzas for everyone!
P
When child classes are created, they inherit all the methods and
attributes from their parent class. Naturally, child classes can also
end up having their own unique attributes and methods. However, a
concept in Python allows child classes to change methods in their
parent classes. That process is called polymorphism.
Through polymorphism, you can use a subclass and alter the
method originally defined in the parent class. Sounds somewhat
impossible, right? Let's see how this works:
class Father(object):
def buy_pizza(self):
print("yummy")
class Son1(Father):
def buy_pizza(self):
print("I want more!")
class Son2(Father):
def buy_pizza(self):
print("I don't like pizzas!")
Father().buy_pizza()
Son1().buy_pizza()
Son2().buy_pizza()
yummy
I want more!
I don't like pizzas!
This is how polymorphism works. It is a great tool, especially when
you have a lot of child classes, and you'd like to change the behavior
of a given superclass from its subclass.
Extending Classes
Let's say you have a class with some methods and attributes you
know you need. However, as you continue with your program, you
feel like you want another class with all these features. Still, you
wish to further add functionality and modifications to the existing
methods. One might think, "Ah, yes! You need to create a child
class." However, a child class is not the answer here, not on its own.
A child class does inherit everything, but it won't let you add more
functionality to the already existing methods and attributes. A child
class can undoubtedly make use of polymorphism, but that's just
going to change the superclass-defined method. It won't add any
additional functionality. That's where you will need to rely on
extending your class.
Extending a class allows you to utilize all the existing methods and
add more features and functionalities. How do you do that? It's
quite easy. Follow these steps, and you'll be able to extend your
classes on the go:
Set up a parent class. Be sure to add all the methods and attributes
here.
Set up and define a child class. This child class will automatically
inherit all the methods and attributes from the parent class.
class Parent:
def __init__(self, name):
self.name = name
def greet(self):
print(f"Hello, my name is {self.name}")
class Child(Parent):
def __init__(self, name, age):
super().__init__(name)
self.age = age
def greet(self):
super().greet()
print(f"I am {self.age} years old")
child = Child("Alice", 10)
child.greet()
In the above code, we created a parent and a child class. The child
class inherited all the attributes and methods. However, notice how
we re-defined the "greet" method using the super() method. The
super() method is used to call the superclass's version of the method.
Not only did we retain the original method, but we also added extra
functionality. The results for this code will look like this:
Hello, my name is Alice
I am 10 years old
Method Overriding
Using your subclass, or child class, you can morph the original
method and override it completely. For this to happen, there are a
few things that are required:
With that out of the way, let's move on to the next chapter, where
we will learn about another important aspect of Python
programming—Error handling and debugging.
Chapter 7: Error Handling and Debugging in
Python
"The most effective debugging tool is still
careful thought, coupled with judiciously
placed print statements." –Brian Kernighan
Whenever you code a program, software, or application, one thing is
for certain—there are bound to be errors and crashes. This isn't
because you're a beginner, either. The fact is that even the most
experienced programmers go through these issues now and then.
What truly helps a professional programmer stand out is their
ability to spot these errors during the coding process and then
handle them accordingly.
Some errors occur due to some issues with the code. However, some
other errors emerge for some other reason completely. Either way,
programmers respond to these and conduct recovery procedures to
ensure the program doesn't crash.
Think about it this way. Whenever you are using your computer,
you often end up encountering errors. Does that mean your system
crashes completely? Not likely. Your system only crashes when
something terrible has happened. In most cases, these errors are
picked up and blocked off, and all that happens is a prompt
emerging, telling you what possibly went wrong.
Python is no exception to the rule. Whether you code for the first
time or the nth time, errors are bound to happen. What you can do,
however, is to handle these accordingly, and that is what we will
look into in this chapter.
What Is Error Handling in Programming?
Errors happen due to software or hardware. Sometimes, they can
happen because both issues emerge simultaneously. Error handling
is the art of understanding these errors and ensuring that
something's done to allow the application or the program to resume
function while jumping over the error. Since we aren't learning
about hardware, we won't be covering how to handle hardware-
related errors.
When it comes to software, a programmer can step in and do one of
two things:
1. Logical errors
2. Runtime errors
3. Compile-time errors
4. Generated errors
1. Syntax error
2. Exceptions
The syntax errors are quite straightforward. They happen when you
forget to complete the code, perhaps close the parenthesis, or even
mistype the name of a function. When such an instance happens,
Python throws in a syntax error. Here's a sample of such an issue.
See if you can spot the problem here:
# Scoring Software
name = input("Please Enter Your Name: ")
print("Hello, ", name + "! Welcome to Our Grading Software!")
marks = int(input("Enter your marks: "))
print("Fetching your grade. Please wait!")
grade = ""
if marks >= 90:
grade = "A"
print("Your grade is: ", grade)
elif marks >= 80:
grade = "B"
print("Your grade is: ", grade)
elif marks >= 70:
grade = "C"
print("Your grade is: ", grade)
elif marks >= 60:
grade = "D"
print("Your grade is: " grade)
else:
grade = "F"
print("Your grade is: ", grade)
print("Thank You for Using This Software!")
When you run this, you end up with the following error!
SyntaxError: invalid syntax.
If you weren't able to find the problem, look at this line:
elif marks >= 60:
grade = "D"
print("Your grade is: " grade)
Here, there is a comma missing. Just because of a simple comma,
the entire program failed to function and could not move ahead. It
can be frustrating when you are coding and forget something as
small as a comma. However, with most IDEs, you can find the issue,
and some IDEs even hint at what may be wrong. Here's another
example of a simple line of code that went wrong:
print("Hi. My name is" name)
SyntaxError: invalid syntax. Perhaps you forgot a comma?
In the above, we deliberately did not use a comma. As a result, the
syntax was wrong. IDLE could pick that up and suggest that we may
have forgotten to use a comma, which was precisely the problem.
While syntax errors are easy to fix, the following type of error
causes issues and needs a deeper understanding.
Exception errors occur when you have done everything correctly, as
per the syntax, but their functionality is incorrect. Let's take the
following code as an example:
name = input("What's your name?")
What's your name? Alex
print(Name)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
print(Name)
NameError: name 'Name' is not defined. Did you mean: 'name'?
In the code above, we called upon Name as opposed to name. Recall
that Python is a case-sensitive language. This means that name and
Name are two separate things. We did declare "name" but at no point
did we ever create a variable named "Name." As a result, an
exception was thrown our way.
In the above, we ended up with NameError. This generally happens
when we try to call upon a variable, function, or method that doesn't
exist. As a result, the error was recorded, and the rest of the
program was terminated. If this code had additional lines, they
wouldn't be executed.
There are quite a few types of Exceptions that exist in Python. Let's
go through each of them to understand what's going on. This will
help us with our debugging process.
Types of Exceptions
NameError
The first one is NameError. We just came across this above. It
happens when you try to call upon a variable that doesn't exist.
TypeError
TypeError occurs when trying to run an operation with an
inapplicable data type. Let's say you are trying to print the following:
print(2 + "2")
In the above, we can see clearly that one data type is an integer
value while the other one is a string. These cannot interact with
each other unless they are changed into strings or integers.
In such a case, you will be presented with the TypeError, as shown
below:
print(2 + "2")
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
print(2 + "2")
TypeError: unsupported operand type(s) for +: 'int' and 'str'
ValueError
A ValueError exception occurs when you are trying to use an invalid
value as an argument. Let's say you type in the following:
print(int("My name is Cole"))
The above shows that int() is called upon, which means the program
expects you to input a numerical value. Instead, we ended up
passing a string value. As a result, we will end up with the following
error:
print(int("My name is Cole"))
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
print(int("My name is Cole"))
ValueError: invalid literal for int() with base 10: 'My name is Cole'
IndexError
When you use index numbers and use the wrong ones, you get
IndexError, Python's way of saying, "Sorry, but that doesn't exist."
dog = [1, 2, 3]
print(dog[3])
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
print(dog[3])
IndexError: list index out of range
In the above, since index values start from 0, the last index number
is 2. We asked Python to print whatever is at index number 3. Since
that is out of the range of the list itself, we end up getting an
IndexError.
IndentationError
When you use the wrong indentations, you end up facing this error.
You may have noticed how conditional statements, for and while
loops, and definition sections are always indented. This isn't just to
make the code look nice, but it is also a requirement.
Sometimes, it may also be reflected as SyntaxError, but
the description will clarify what you are looking at:
SyntaxError: expected an indented block after 'for' statement on line
1
for x in range(1, 10):
print(x)
SyntaxError: expected an indented block after 'for' statement on line 1
The print(x) was meant to be indented in this code, yet it wasn't. In
some IDEs, this will be reflected as an IndentationError. Here's how
the very same code will generate an indentation error in a different
IDE (PyCharm, for this example):
File "/Users/PycharmProjects/PythonForBeginners/test.py", line 2
print(x)
^
IndentationError: expected an indented block after 'for' statement on line 1
ZeroDivisionError
This one should make sense right away. Sometimes, you may have
massive algorithms and complex code to work with. As you process
all of that and run it, you may end up with this error. What does it
mean? It simply means that there is some instance where
something is being divided by 0. Since that is impossible to do, the
system will throw an exception your way:
print(1/0)
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
print(1/0)
ZeroDivisionError: division by zero
Of course, the above is not complicated or complex, but it is a
perfect way to show when such an error might pop up.
ImportError / ModuleNotFoundError
You will have this error when you import something from the
wrong library. In the future, whenever you are importing specialized
libraries for machine learning, game development, or other projects,
you may come across this error if you're trying to import the wrong
module from the wrong library:
from numpy import pandas
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
from numpy import pandas
ModuleNotFoundError: No module named 'numpy'
AttributeError
When you are trying to use an inapplicable attribute for a given
Python object, you end up getting this error:
print('a'.sum())
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
print('a'.sum())
AttributeError: 'str' object has no attribute 'sum'
KeyError
Just like IndexError, KeyError happens when you are calling upon a
key that doesn't exist in a dictionary:
animals = {"koala": 1, "panda": 2}
print(animals["rabbit"])
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
print(animals["rabbit"])
KeyError: 'rabbit'
These are some of the most common ones you will come across.
You may come across many other exceptions, a detail of which can
be found under Python Documentation at www.python.org.
Python Debugging Techniques
Now that you know the errors and exceptions, let's learn how we
can overcome these. It is essential to learn all of these to have the
best chance at fixing the issues you may encounter during your
programming journey.
Using the Print Statements
This is the most basic way to find problems and then try to resolve
them. When you have multiple operations, try to print the variables
or results out to see if everything is working. If everything works
fine, you should get the result you are looking for.
In all the above examples, where we discussed a variety of
exceptions, we used print statements to see if the code was working.
Where it wasn't, it was responding with the type of error it
encountered and suggestions. It even highlighted the line number
to narrow our search down.
This is the very first kind of debugging method you use.
Using Python Debugger
Python comes built-in with a powerful debugging tool. It is called
the Python Debugger (pdb). Using pdb helps you greatly because it
goes through the code, checks for every value and variable, and then
tracks down any hard-to-find bugs. To use pdb, you must first
import it into your program and then call it into action. How? Here's
an example:
import pdb
def factorial(x):
if x == 0:
return 1
else:
return x * factorial(c-1)
pdb.set_trace()
print(factorial(4))
Once you execute this code, the Python debugger will start. It will
present you with the following:
-> print(factorial(4))
(Pdb)
After the parentheses, you can type one of the four values
Exercise
Right! It's time to get cracking at some debugging. Below, you will
find two sets of code. The goal is to find out the error, fix it, and run
the code:
print("Welcome to Python Programming!"
That's quite simple, isn't it? Well, let's see if you can solve this one.
numerator = 10
denominator = 0
result = numerator / denominator
print(f"The result is {result}")
With the above code, you are bound to get an error of some kind.
The goal is to handle this code exception so that the code does not
crash and instead handles the code exception somehow.
Here's an additional code if you're feeling up for the task:
numbers = [1, 2, 3, 4, 5]
average = sum(numbers) / len(numbers) - 1
print(f"The average is {average}")
There's something wrong with this code. Can you spot the issue and
fix it?
With that, it is time for us to move on to the book's next chapter,
where we will discuss Python file operations and data storage.
Chapter 8: Python File Operations and Data
Storage
"The goal is to turn data into information,
and information into insight." –Carly Fiorina,
Former CEO of Hewlett-Packard
Did you know you can use Python to write files like .csv, text files,
and more? Well, that is something Python can do and part of the
reason why Python is being taught in almost every leading business
and finance school.
This chapter, therefore, will be all about Python file operations and
how you can read, write, and store files easily.
Reading and Writing Files
Python is powerful enough for many reasons, and reading and
writing files is just one of them. Using Python, you can create, write,
and read files easily.
Regarding Python, there are two types of files that Python can
handle. These are standard text files and library files. The latter are
written in binary language, so we won't be going into those. Keeping
the scope of this book in view, we will only focus on text files.
File Access Modes on Python
When you access a file, you have different access modes. Since we
are dealing with coding, it isn't as simple as double-clicking and
opening a file. Here, we must specify in the code what kind of access
we want.
In Python, we have:
Opening Files
To open a file in Python, we use the following basic syntax:
file_object = open('file_name', 'mode')
The open() function always takes in two parameters. These are:
Below is a code that shows you various types of writing and reading
functions in use.
# Showing various ways to read and write
my_file = open("my_file.txt", "w")
L = ["This is Toronto \n", "This is New York \n", "This is LA \n"]
# \n is placed to indicate EOL (End of Line)
my_file.write("Hi there \n")
my_file.writelines(L)
my_file.close() # closing to change access mode
my_file = open("my_file.txt", "r+")
print("Output of Read ")
print(my_file.read())
print()
my_file.seek(0)
print( "Output of Readline ")
print(my_file.readline())
print()
my_file.seek(0)
# difference between read and readline
print("Output of Read(9) function is ")
print(my_file.read(9))
print()
my_file.seek(0)
print("Output of Readline(9) function is ")
print(my_file.readline(9))
my_file.seek(0)
# readlines function
print("Output of Readlines function is ")
print(my_file.readlines())
print()
my_file.close()
The output is as follows:
Output of Read
Hi there
This is Toronto
This is New York
This is LA
Output of Readline
Hi there
Output of Read(9) function is
Hi there
Output of Readline(9) function is
Hi there
Output of Readlines function is
['Hi there \n', 'This is Toronto \n', 'This is New York \n', 'This is LA \n']
While you
already
know it is
essential
to close
files you
are
working
with, you
should
always
double-
check
that you
are doing
so.
Failure to
do so can
lead to
file
corruption
, slowing
down of
the
program,
system
crashing,
and other
issues.
Appending
We know we must use 'a' or 'a+' to append items to the file.
However, let's see how that happens with another example.
# Append VS Write
my_file2 = open("file2.txt", "w")
L = ["Say Hello to Japan \n", "Hello Italy \n", "This is England \n"]
my_file2.writelines(L)
my_file2.close()
# Append-adds at last
my_file2 = open("file2.txt", "a") # append mode
my_file2.write("Today \n")
my_file2.close()
my_file2 = open("file2.txt", "r")
print("Readlines after appending")
print(my_file2.readlines())
print()
my_file2.close()
# Write-Overwrites
my_file2 = open("file2.txt", "w") # write mode
my_file2.write("Tomorrow \n")
my_file2.close()
my_file2 = open("file2.txt", "r")
print("Readlines after writing")
print(my_file2.readlines())
print()
my_file2.close()
The output is:
Readlines after appending
['Say Hello to Japan \n', 'Hello Italy \n', 'This is England \n', 'Today \n']
Readlines after writing
['Tomorrow \n']
Python JSON
dict object
list and tuple array
str string
int, float, and number
long s
True true
False false
None null
Here's how you can carry out simple serialization:
import json
my_var = {"Subjects": {"Spanish": 75, "Science": 91}}
with open("Test.json", "w") as a:
json.dump(my_var, a)
We first import JSON into Python. Then, we create a Python object
my_var. Next, we create a file named Test.json. We use the write
mode to access it. Next, we use the dump method. The json.dump()
method takes in two arguments. The first is the data object that we
want to serialize. The second is the object, which the program will
write in Byte format.
Deserialization
This is the opposite of serialization. Therefore, instead of dumping
data, it loads the data instead. As a result, the JSON objects are
converted into their corresponding Python objects. For this, we use
the load() method:
with open("Test.json", "r") as read_this:
my_data = json.load(read_this)
Let's look at another example where we create a JSON object and
then convert it into a Python object using the load() method:
import json
json_obj ="""
{"Country":
{"name": "Pakistan", "Languages_spoken": [
{"names":
["Urdu", "English", "Sindhi", "Punjabi"]}]}}
"""
python_obj = json.loads(json_obj)
Exercise
So far, you're doing great. Yes, it does take some time to get used to
it. However, do not be alarmed if you run into any issues. You can
always consult this book and find help from the wonderful
community. Alternatively, you can check out Python
Documentations to further enhance your knowledge and skills.
With that said, it is time to put your knowledge to the test. For this
chapter, create a program that reads and writes from a text file. It's
that simple!
Bonus Challenge
If you're up for the challenge, we have one for you.
Create a personal expense tracker. You will need to bring in all the
knowledge from this and previous chapters. Below are step-by-step
instructions and a completed code to inspire you.
The code must support JSON and CSV formats. The program should
include reading and writing expense data to a text file:
Travel
Transportation
Healthcare
Finance
Manufacturing
And that is just scratching the surface. There's a lot more that
Python web development can do for you. While there are many
other well-established platforms and frameworks people use for
web development, Python has certain advantages that most cannot
offer:
The list goes on and on. However, there are some cons to this as
well that you should know:
Now, for those who are eager to get started, we have some good
news. Python has a framework (a platform that provides you with
all the tools and functionalities you need to develop applications)
that makes your job a lot easier. In this case, that happens to be a
framework called Flask.
The Basics of Framework—Flask
A framework is essentially a platform that developers use to develop
software applications. These can be offline or web-based. A
framework makes the work easier as most fundamental elements
are pre-loaded and provided. This helps save time and energy. Not
just that, using frameworks helps keep things more organized, too.
Frameworks offer functionality and tools that are used explicitly for
application development. This means you won't have to go around
the internet to search for what to use to carry out a specific
operation. It's all there for you, and Flask is one such example.
Flask is Python's web development framework. It's not the only one,
but it is one that people mostly use. It is the most beginner-friendly
framework to learn and work with. The other alternative is Django,
which requires much time to master.
The good thing is that you don't have to start from scratch. Why?
Because by now, you know your way with Python. That helps you
save a lot of time and get straight into it.
Flask is based on the Werkzeg Web Server Gateway Interface
(WSGI) toolkit and Jinja2 engine. The Werkzeg toolkit is used as a
standard for Python web development. It is WSGI that interacts
between the server and the web app. Jinja2, on the other hand, is a
very popular template engine for Python. Using Jinja allows you to
pass Python variables through any HTML code or template easily.
Flask is a lot like Python, meaning you will not have any trouble
using it. To give you an example, here's a sample boilerplate code
for you to see:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
That makes sense, and it is very readable. Well, before you go on to
code anything in Flask, you first need to install something called a
virtual environment.
The virtual environment is used to manage your project during
development and production. A virtual environment is a group of
independent Python libraries for each project. You can have a set of
packages installed for one project, and they will not affect any other
project. To use Flask, we need to download a few things.
Here's a step-by-step guide on how to install Flask properly on your
system.
Step 1—Installing the Virtual Environment
First, you will need to install the virtual environment. Be sure to
follow the steps according to your operating system.
F L
If you are using Debian or Ubuntu, do the following:
1. Open Terminal.
2. Use the following apt command to install virtualenv:
sudo apt install python-virtualenv
For CentOS, Red Hat, or Fedora users, here are the steps:
1. Open Terminal.
2. Use the following yum command to install virtualenv:
sudo yum install python-virtualenv
F M OS
For Mac users, the installation is equally simple.
1. Launch Terminal
2. Use the following command to install virtualenv using pip.
sudo python3 -m pip install virtualenv
F W
To install a virtual environment on Windows, do the following:
L M OS
To create an environment in Linux or MacOS, use the following
code in Terminal (be sure you are in the directory of the project):
<name of environment>/bin/activate
W
Use the following line of code:
<name of environment>\Scripts\activate
In case you do not have Jinja2, all you need to use Jinja2 is to open
up your command prompt or terminal and use the following
command:
Cons
Slow when compared to other and better established game
development languages, such as C#.
Low compatibility with game engines.
Limited game libraries.
Not a great choice for mobile gaming.
Now that we know what Python can do and what it can't, let's move
on to the next step: Choosing the right game development
framework, library, or engine.
The Right Option
As it turns out, there are a few choices you have that you can choose
from.
Python Arcade
Panda3D
HARFANG
Ren'Py
Kivy
PyGame—We'll be using this one for our project
Ogre
Pyglet
Once you have made your mind up, or gone for the one we
recommend, there are two things to do:
1. xcode-select --install
2. pip3 install pygame
G L C
# Game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if not game_started:
# Check if the game hasn’t started and the player pressed the SPACE
key to start
if keys[pygame.K_SPACE]:
game_started = True
else:
if keys[pygame.K_LEFT] and player_x > 0:
# Move the player to the left when the LEFT arrow key is pressed
player_x -= 0.1
if keys[pygame.K_RIGHT] and player_x < screen_width -
player_width:
# Move the player to the right when the RIGHT arrow key is pressed
player_x += 0.1
screen.fill(white)
# Draw the Player rectangle and the Dropping Circle
pygame.draw.rect(screen, player_color, (player_x, player_y,
player_width, player_height))
pygame.draw.circle(screen, circle_color, (circle_x, circle_y),
circle_radius)
# Use speed variable to decrease verticle position of the circle
through every game loop
# Below, when the circle speed increases for every 10 points, this will
increase the amount
# that the circle drops on every pygame.display.update()
circle_y += circle_speed
if circle_y > screen_height:
# If the circle reaches the bottom of the screen, reset its position
circle_x = random.randint(0, screen_width - circle_radius * 2)
circle_y = 0
# Increase Score for every successful pass
score += 1
# Increase speed for every 10 points
if score % 10 == 0:
circle_speed += 0.05
if player_x < circle_x < player_x + player_width and player_y <
circle_y + circle_radius:
# Collision detected
game_started = False
circle_x = random.randint(0, screen_width - circle_radius * 2)
circle_y = 0
circle_speed = 0.1 # Reset circle speed
score = 0
# Update and display the score
display_score(screen, score)
pygame.display.update()
if not game_started:
# Display instructions to start the game
display_instructions(screen)
pygame.quit()
It’s simple. It’s elegant, and it’s still a classic for everyone. Work on
it, improve it, debug it, code it, and play it.
Conclusion
W3 school
Geeksforgeeks
Codeacademy
Coderslegacy
GitHub
Stack Overflow
Reddit
It’s simple and takes just a moment of your time. Click the link
below or scan the QR code to share your thoughts and experiences:
Your review is more than just words; it’s a beacon of
encouragement, a signpost of possibility. We deeply appreciate your
time and effort in helping to foster a community of learning and
growth.
Thank you for being an integral part of this journey. As you
continue to explore and grow in the world of Python programming,
remember that your journey can inspire countless others. Keep the
game alive, and let’s keep learning together!
With heartfelt thanks, Megabyte Publishing
P.S. - Sharing your journey not only inspires others but also
cements your own understanding. As you move forward, consider
mentoring or guiding a fellow beginner. Your journey can be the
start of someone else’s great adventure in Python programming!
R
Dyouri, A. (2022, March 9). How to use Flask-SQLAlchemy to
interact with databases in a Flask application | DigitalOcean.
DigitalOcean.
https://www.digitalocean.com/community/tutorials/how-to-use-
flask-sqlalchemy-to-interact-with-databases-in-a-flask-application
Gupta, S. (2022, September 14). What is Python used for? 9 use
cases [Overview Guide]. Springboard.
https://www.springboard.com/blog/data-science/what-is-python-
used-for/
Introduction to Python. (2019). W3Schools.
https://www.w3schools.com/python/python_intro.asp
Karim. (2017, November 10). Python lists (For absolute
beginners). Afternerd. https://www.afternerd.com/blog/python-
lists-for-absolute-beginners/
Krishna, R. (2020, August 31). How to format strings using
print() in Python? Numpy Ninja.
https://www.numpyninja.com/post/how-to-format-strings-using-
print-in-python
Novotny, J. (2023, March 9). A programmers’ guide to Python:
Advantages & disadvantages. Linode Guides & Tutorials.
https://www.linode.com/docs/guides/pros-and-cons-of-python/
Python pygame - The full tutorial. (n.d.). CodersLegacy.
https://coderslegacy.com/python/python-pygame-tutorial/
Python Software Foundation. (2019). What is Python?
Executive summary. Python.
https://www.python.org/doc/essays/blurb/
Python vs other programming languages. (n.d.). StxNext.
https://www.stxnext.com/python-vs-other-programming-
languages/
Sarkar, P. (2023, September 4). How to concatenate strings
using Python. KnowledgeHut.
https://www.knowledgehut.com/blog/programming/concatenate-
strings-python
Send data to Flask template (Jinja2) - Python Tutorial. (n.d.).
PythonBasics. https://pythonbasics.org/flask-template-data/
7 ways to concatenate strings into a string in Python. (n.d.).
Python Tutorial. https://www.pythontutorial.net/python-string-
methods/python-string-concatenation/
Taff Inc. (2021, August 23). Top 12 Python use cases &
applications with examples | Python Trends 2023. TAFF.
https://www.taffinc.com/blog/top-python-use-cases-and-
applications/
TechBootCamps. (2021, September 16). Why learn Python?
Five reasons to start programming with Python in 2022. UT
Austin Boot Camps. https://techbootcamps.utexas.edu/blog/why-
learn-python-get-started-programming/
Yegulalp, S. (2023, January 18). How to install Python the
smart way. InfoWorld.
https://www.infoworld.com/article/3530140/how-to-install-
python-the-smart-way.html