Object-Oriented Python: Master OOP by Building Games and GUIs
By Irv Kalb
()
About this ebook
Object-Oriented Python is an intuitive and thorough guide to mastering object-oriented programming from the ground up. You’ll cover the basics of building classes and creating objects, and put theory into practice using the pygame package with clear examples that help visualize the object-oriented style. You’ll explore the key concepts of object-oriented programming — encapsulation, polymorphism, and inheritance — and learn not just how to code with objects, but the absolute best practices for doing so. Finally, you’ll bring it all together by building a complex video game, complete with full animations and sounds. The book covers two fully functional Python code packages that will speed up development of graphical user interface (GUI) programs in Python.
Related to Object-Oriented Python
Related ebooks
Machine Learning for iOS Developers Rating: 0 out of 5 stars0 ratingsIvor Horton's Beginning Visual C++ 2013 Rating: 0 out of 5 stars0 ratingsPython for Finance Rating: 3 out of 5 stars3/5Job Ready Go Rating: 0 out of 5 stars0 ratingsObjective-C Programming For Dummies Rating: 4 out of 5 stars4/5Learning Java by Building Android Games: Learn Java and Android from scratch by building six exciting games Rating: 0 out of 5 stars0 ratingsJavaScript Bible Rating: 4 out of 5 stars4/5Machine Learning in the AWS Cloud: Add Intelligence to Applications with Amazon SageMaker and Amazon Rekognition Rating: 0 out of 5 stars0 ratingsThe TypeScript Workshop: A practical guide to confident, effective TypeScript programming Rating: 0 out of 5 stars0 ratingsCryENGINE Game Programming with C++, C#, and Lua Rating: 0 out of 5 stars0 ratingsJavaScript and AJAX For Dummies Rating: 4 out of 5 stars4/5Android Programming for Beginners Rating: 3 out of 5 stars3/5Android Programming for Beginners: Build in-depth, full-featured Android apps starting from zero programming experience Rating: 0 out of 5 stars0 ratingsiPad Application Development For Dummies Rating: 3 out of 5 stars3/5Keras to Kubernetes: The Journey of a Machine Learning Model to Production Rating: 0 out of 5 stars0 ratingsLearning Java by Building Android Games: Learn Java and Android from scratch by building five exciting games Rating: 0 out of 5 stars0 ratingsProfessional C# 4.0 and .NET 4 Rating: 0 out of 5 stars0 ratingsMCSD Certification Toolkit (Exam 70-483): Programming in C# Rating: 3 out of 5 stars3/5Programming Concepts in C++ Rating: 0 out of 5 stars0 ratingsGraphic Guide to Python with Processing.py 3: Graphic Guide to Programming Rating: 0 out of 5 stars0 ratingsJob Ready Python Rating: 0 out of 5 stars0 ratingsiOS 5 Programming Pushing the Limits: Developing Extraordinary Mobile Apps for Apple iPhone, iPad, and iPod Touch Rating: 0 out of 5 stars0 ratingsMachine Learning: Hands-On for Developers and Technical Professionals Rating: 0 out of 5 stars0 ratingsPython for Data Science For Dummies Rating: 0 out of 5 stars0 ratingsBeginning Programming with C++ For Dummies Rating: 4 out of 5 stars4/53ds Max 2011 Bible Rating: 5 out of 5 stars5/5
Programming For You
Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5SQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Linux: Learn in 24 Hours Rating: 5 out of 5 stars5/5Excel 101: A Beginner's & Intermediate's Guide for Mastering the Quintessence of Microsoft Excel (2010-2019 & 365) in no time! Rating: 0 out of 5 stars0 ratingsC# Programming from Zero to Proficiency (Beginner): C# from Zero to Proficiency, #2 Rating: 0 out of 5 stars0 ratingsCoding with JavaScript For Dummies Rating: 0 out of 5 stars0 ratingsPYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5JavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/5Learn PowerShell in a Month of Lunches, Fourth Edition: Covers Windows, Linux, and macOS Rating: 5 out of 5 stars5/5HTML & CSS: Learn the Fundaments in 7 Days Rating: 4 out of 5 stars4/5Python QuickStart Guide: The Simplified Beginner's Guide to Python Programming Using Hands-On Projects and Real-World Applications Rating: 0 out of 5 stars0 ratingsSpies, Lies, and Algorithms: The History and Future of American Intelligence Rating: 4 out of 5 stars4/5Beginning Programming with C++ For Dummies Rating: 4 out of 5 stars4/5Grokking Algorithms: An illustrated guide for programmers and other curious people Rating: 4 out of 5 stars4/5SQL: For Beginners: Your Guide To Easily Learn SQL Programming in 7 Days Rating: 5 out of 5 stars5/5Python: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5Python Data Structures and Algorithms Rating: 5 out of 5 stars5/5
Reviews for Object-Oriented Python
0 ratings0 reviews
Book preview
Object-Oriented Python - Irv Kalb
Object-Oriented Python
Master OOP by Building Games and GUIs
by Irv Kalb
nsp_logo_black_rkObject-Oriented Python. Copyright © 2022 by Irv Kalb.
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher.
Fourth printing
28 27 26 25 24 4 5 6 7 8
ISBN-13: 978-1-7185-0206-2 (print)
ISBN-13: 978-1-7185-0207-9 (ebook)
NSPPublisher: William Pollock
Managing Editor: Jill Franklin
Production Manager: Rachel Monaghan
Production Editor: Kate Kaminski
Developmental Editor: Liz Chadwick
Cover Illustrator: James L. Barry
Interior Design: Octopod Studios
Technical Reviewer: Monte Davidoff
Copyeditor: Rachel Head
Compositor: Maureen Forys, Happenstance Type-O-Rama
Proofreader: Paula L. Fleming
Indexer: Valerie Haynes Perry
The following images are reproduced with permission:
Figure 2-1, photo by David Benbennick, printed under the Creative Commons Attribution-Share Alike 3.0 Unported license, https://creativecommons.org/licenses/by-sa/3.0/deed.en.
Library of Congress Cataloging-in-Publication Data
Names: Kalb, Irv, author.
Title: Object-oriented Python: master OOP by building games and GUIs / Irv Kalb.
Description: San Francisco : No Starch Press, [2021] | Includes index. |
Identifiers: LCCN 2021044174 (print) | LCCN 2021044175 (ebook) | ISBN
9781718502062 (print) | ISBN 9781718502079 (ebook)
Subjects: LCSH: Object-oriented programming (Computer science) | Python
(Computer program language)
Classification: LCC QA76.64 .K3563 2021 (print) | LCC QA76.64 (ebook) |
DDC 005.1/17--dc23
LC record available at https://lccn.loc.gov/2021044174
LC ebook record available at https://lccn.loc.gov/2021044175
No Starch Press and the No Starch Press iron logo are registered trademarks of No Starch Press, Inc. Other product and company names mentioned herein may be the trademarks of their respective owners. Rather than use a trademark symbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark.
The information in this book is distributed on an As Is
basis, without warranty. While every precaution has been taken in the preparation of this work, neither the author nor No Starch Press, Inc. shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the information contained in it.
For customer service inquiries, please contact [email protected]. For information on distribution, bulk sales, corporate sales, or translations: [email protected]. For permission to translate this work: [email protected]. To report counterfeit copies or piracy: [email protected].
To my wonderful wife, Doreen.
You are the glue that keeps our family together.
Many years ago, I said, I do,
but what I meant was, I will.
About the Author
Irv Kalb is an adjunct professor at UCSC Silicon Valley Extension and the University of Silicon Valley (formerly Cogswell Polytechnical College), where he teaches introductory and object-oriented programming courses in Python. Irv has a bachelor’s and a master’s degree in computer science, has been using object-oriented programming for over 30 years in a number of different computer languages, and has been teaching for over 10 years. He has decades of experience developing software, with a focus on educational software. As Furry Pants Productions, he and his wife created and shipped two edutainment CD-ROMs based on the character Darby the Dalmatian. Irv is also the author of Learn to Program with Python 3: A Step-by-Step Guide to Programming (Apress).
Irv was heavily involved in the early development of the sport of Ultimate Frisbee®. He led the effort of writing many versions of the official rule book and co-authored and self-published the first book on the sport, Ultimate: Fundamentals of the Sport.
About the Technical Reviewer
Monte Davidoff is an independent software development consultant. His areas of expertise include DevOps and Linux. Monte has been programming in Python for over 20 years. He has used Python to develop a variety of software, including business-critical applications and embedded software.
Acknowledgments
I would like to thank the following people, who helped make this book possible:
Al Sweigart, for getting me started in the use of pygame (especially with his Pygbutton
code) and for allowing me to use the concept of his Dodger
game.
Monte Davidoff, who was instrumental in helping me get the source code and documentation of that code to build correctly through the use of GitHub, Sphinx, and ReadTheDocs. He worked miracles using a myriad of tools to wrestle the appropriate files into submission.
Monte Davidoff (yes, the same guy), for being an outstanding technical reviewer. Monte made excellent technical and writing suggestions throughout the book, and many of the code examples are more Pythonic and more OOP-ish because of his comments.
Tep Sathya Khieu, who did a stellar job of drawing all the original diagrams for this book. I am not an artist (I don’t even play one on TV). Tep was able to take my primitive pencil sketches and turn them into clear, consistent pieces of art.
Harrison Yung, Kevin Ly, and Emily Allis, for their contributions of artwork in some of the game art.
The early reviewers, Illya Katsyuk, Jamie Kalb, Gergana Angelova, and Joe Langmuir, who found and corrected many typos and made excellent suggestions for modifications and clarifications.
All the editors who worked on this book: Liz Chadwick (developmental editor), Rachel Head (copyeditor), and Kate Kaminski (production editor). They all made huge contributions by questioning and often rewording and reorganizing some of my explanations of concepts. They were also extremely helpful in adding and removing commas [do I need one here?] and lengthening my sentences as I am doing here to make sure that the point comes across cleanly (OK, I’ll stop!). I’m afraid that I’ll never understand when to use which
versus that,
or when to use a comma and when to use a dash, but I’m glad that they know! Thanks also to Maureen Forys (compositor) for her valuable contributions to the finished product.
All the students who have been in my classes over the years at the UCSC Silicon Valley Extension and at the University of Silicon Valley (formerly Cogswell Polytechnical College). Their feedback, suggestions, smiles, frowns, light-bulb moments, frustrations, knowing head nods, and even thumbs-up (in Zoom classes during the COVID era) were extremely helpful in shaping the content of this book and my overall teaching style.
Finally, my family, who supported me through the long process of writing, testing, editing, rewriting, editing, debugging, editing, rewriting, editing (and so on) this book and the associated code. I couldn’t have done it without them. I wasn’t sure if we had enough books in our library, so I wrote another one!
Introduction
This book is about a software development technique called object-oriented programming (OOP) and how it can be used with Python. Before OOP, programmers used an approach known as procedural programming, also called structured programming, which involves building a set of functions (procedures) and passing data around through calls to those functions. The OOP paradigm gives programmers an efficient way to combine code and data into cohesive units that are often highly reusable.
In preparation for writing this book, I extensively researched existing literature and videos, looking specifically at the approaches taken to explain this important and wide-ranging topic. I found that instructors and writers typically start by defining certain key terms: class, instance variable, method, encapsulation, inheritance, polymorphism, and so on.
While these are all important concepts, and I’ll cover all of them in depth in this book, I’ll begin in a different way: by considering the question, What problem are we solving?
That is, if OOP is the solution, then what is the problem? To answer this question, I’ll start by presenting a few examples of programs built using procedural programming and identifying complications inherent in this style. Then I’ll show you how an object-oriented approach can make the construction of such programs much easier and the programs themselves more maintainable.
Who Is This Book For?
This book is intended for people who already have some familiarity with Python and with using basic functions from the Python Standard Library. I will assume that you understand the fundamental syntax of the language and can write small- to medium-sized programs using variables, assignment statements, if/elif/else statements, while and for loops, functions and function calls, lists, dictionaries, and so on. If you aren’t comfortable with all of these concepts, then I suggest that you get a copy of my earlier book, Learn to Program with Python 3 (Apress), and read that first.
This is an intermediate-level text, so there are a number of more advanced topics that I will not address. For example, to keep the book practical, I will not often go into detail on the internal implementation of Python. For simplicity and clarity, and to keep the focus on mastering OOP techniques, the examples are written using a limited subset of the language. There are more advanced and concise ways to code in Python that are beyond the scope of this book.
I will cover the underlying details of OOP in a mostly language-independent way, but will point out areas where there are differences between Python and other OOP languages. Having learned the basics of OOP-style coding through this book, if you wish, you should be able to easily apply these techniques to other OOP languages.
Python Version(s) and Installation
All the example code in this book was written and tested using Python version 3.9. All the examples should work fine with version 3.9 or newer.
Python is available for free at https://www.python.org. If you don’t have Python installed, or you want to upgrade to the latest version, go to that site, find the Downloads tab, and click the Download button. This will download an installable file onto your computer. Double-click the file that was downloaded to install Python.
Windows Installation
If you’re installing on a Windows system, there is one important option that you need to set correctly. When running through the installation steps, you should see a screen like this:
f01001At the bottom of the dialog is a checkbox labeled Add Python 3.x to PATH.
Please be sure to check this box (it defaults to unchecked). This setting will make the installation of the pygame package (which is introduced later in the book) work correctly.
Note
I am aware of the PEP 8 – Style Guide for Python Code
and its specific recommendation to use the snake case convention (snake_case) for variable and function names. However, the document starts by saying that the convention is for the Python code comprising the standard library.
I fully applaud this consistency. I have been using the camel case naming convention (camelCase) for many years before the PEP 8 document was written and have become comfortable with it during my career. Therefore, all variable and function names in this book are consistently written using camel case.
How Will I Explain OOP?
The examples in the first few chapters use text-based Python; these sample programs get input from the user and output information to the user purely in the form of text. I’ll introduce OOP by showing you how to develop text-based simulations of physical objects in code. We’ll start by creating representations of light switches, dimmer switches, and TV remote controls as objects. I’ll then show you how we can use OOP to simulate bank accounts and a bank that controls many accounts.
Once we’ve covered the basics of OOP, I’ll introduce the pygame module, which allows programmers to write games and applications that use a graphical user interface (GUI). With GUI-based programs, the user intuitively interacts with buttons, checkboxes, text input and output fields, and other user-friendly widgets.
I chose to use pygame with Python because this combination allows me to demonstrate OOP concepts in a highly visual way using elements on the screen. Pygame is extremely portable and runs on nearly every platform and operating system. All the sample programs that use the pygame package have been tested with the recently released pygame version 2.0.
I’ve created a package called pygwidgets that works with pygame and implements a number of basic widgets, all of which are built using an OOP approach. I’ll introduce this package later in the book, providing sample code you can run and experiment with. This approach will allow you to see real, practical examples of key object-oriented concepts, while incorporating these techniques to produce fun, playable games. I’ll also introduce my pyghelpers package, which provides code to help write more complicated games and applications.
All the example code shown in the book is available as a single download from the No Starch website: https://www.nostarch.com/object-oriented-python/.
The code is also available on a chapter-by-chapter basis from my GitHub repository: https://github.com/IrvKalb/Object-Oriented-Python-Code/.
What’s in the Book
This book is divided into four parts. Part I introduces object-oriented programming:
Chapter 1 provides a review of coding using procedural programming. I’ll show you how to implement a text-based card game and simulate a bank performing operations on one or more accounts. Along the way, I discuss common problems with the procedural approach.
Chapter 2 introduces classes and objects and shows how you can represent real-world objects like light switches or a TV remote in Python using classes. You’ll see how an object-oriented approach solves the problems highlighted in the first chapter.
Chapter 3 presents two mental models that you can use to think about what’s going on behind the scenes when you create objects in Python. We’ll use Python Tutor to step through code and see how objects are created.
Chapter 4 demonstrates a standard way to handle multiple objects of the same type by introducing the concept of an object manager object. We’ll expand the bank account simulation using classes, and I’ll show you how to handle errors using exceptions.
Part II focuses on building GUIs with pygame:
Chapter 5 introduces the pygame package and the event-driven model of programming. We’ll build a few simple programs to get you started with placing graphics in a window and handling keyboard and mouse input, then develop a more complicated ball-bouncing program.
Chapter 6 goes into much more detail on using OOP with pygame programs. We’ll rewrite the ball-bouncing program in an OOP style and develop some simple GUI elements.
Chapter 7 introduces the pygwidgets module, which contains full implementations of many standard GUI elements (buttons, checkboxes, and so on), each developed as a class.
Part III delves into the main tenets of OOP:
Chapter 8 discusses encapsulation, which involves hiding implementation details from external code and placing all related methods in one place: a class.
Chapter 9 introduces polymorphism—the idea that multiple classes can have methods with the same names—and shows how it enables you to make calls to methods in multiple objects, without having to know the type of each object. We’ll build a Shapes program to demonstrate this concept.
Chapter 10 covers inheritance, which allows you to create a set of subclasses that all use common code built into a base class, rather than having to reinvent the wheel with similar classes. We’ll look at a few real-world examples where inheritance comes in handy, such as implementing an input field that only accepts numbers, then rewrite our Shapes example program to use this feature.
Chapter 11 wraps up this part of the book by discussing some additional important OOP topics, mostly related to memory management. We’ll look at the lifetime of an object, and as an example we’ll build a small balloon-popping game.
Part IV explores several topics related to using OOP in game development:
Chapter 12 demonstrates how we can rebuild the card game developed in Chapter 1 as a pygame-based GUI program. I also show you how to build reusable Deck and Card classes that you can use in other card games you create.
Chapter 13 covers timing. We’ll develop different timer classes that allow a program to keep running while concurrently checking for a given time limit.
Chapter 14 explains animation classes you can use to show sequences of images. We’ll look at two animation techniques: building animations from a collection of separate image files and extracting and using multiple images from a single sprite sheet file.
Chapter 15 explains the concept of a state machine, which represents and controls the flow of your programs, and a scene manager, which you can use to build a program with multiple scenes. To demonstrate the use of each of these, we’ll build two versions of a Rock, Paper, Scissors game.
Chapter 16 discusses different types of modal dialogs, another important user interaction feature. We then walk through building a full-featured OOP-based video game called Dodger that demonstrates many of the techniques described in the book.
Chapter 17 introduces the concept of design patterns, focusing on the Model View Controller pattern, then presents a dice-rolling program that uses this pattern to allow the user to visualize data in numerous different ways. It concludes with a short wrap-up for the book.
Development Environments
In this book, you’ll need to use the command line only minimally for installing software. All installation instructions will be clearly written out, so you won’t need to learn any additional command line syntax.
Rather than using the command line for development, I believe strongly in using an interactive development environment (IDE). An IDE handles many of the details of the underlying operating system for you, and it allows you to write, edit, and run your code using a single program. IDEs are typically cross-platform, allowing programmers to easily move from a Mac to a Windows computer or vice versa.
The short example programs in the book can be run in the IDLE development environment that is installed when you install Python. IDLE is very simple to use and works well for programs that can be written in a single file. When we get into more complicated programs that use multiple Python files, I encourage you to use a more sophisticated environment instead; I use the JetBrains PyCharm development environment, which handles multiple-file projects more easily. The Community Edition is available for free from https://www.jetbrains.com/, and I highly recommend it. PyCharm also has a fully integrated debugger that can be extremely useful when writing larger programs. For more information on how to use the debugger, please see my YouTube video Debugging Python 3 with PyCharm
at https://www.youtube.com/watch?v=cxAOSQQwDJ4&t=43s/.
Widgets and Example Games
The book introduces and makes available two Python packages: pygwidgets and pyghelpers. Using these packages, you should be able to build full GUI programs—but more importantly, you should gain an understanding of how each of the widgets is coded as a class and used as an object.
Incorporating various widgets, the example games in the book start out relatively simple and get progressively more complicated. Chapter 16 walks you through the development and implementation of a full-featured video game, complete with a high-scores table that is saved to a file.
By the end of this book, you should be able to code your own games—card games, or video games in the style of Pong, Hangman, Breakout, Space Invaders, and so on. Object-oriented programming gives you the ability to write programs that can easily display and control multiple items of the same type, which is often required when building user interfaces and is frequently necessary in game play.
Object-oriented programming is a general style that can be used in all aspects of programming, well beyond the game examples I use to demonstrate OOP techniques here. I hope you find this approach to learning OOP enjoyable.
Let’s get started!
Part I
Introducing Object-oriented Programming
This part of the book introduces you to object-oriented programming. We’ll discuss problems inherent in procedural code, then see how object-oriented programming addresses those concerns. Thinking in objects (with state and behavior) will give you a new perspective about how to write code.
Chapter 1 provides a review of procedural Python. I start by presenting a text-based card game named Higher or Lower, then work through a few progressively more complex implementations of a bank account in Python to help you better understand common problems with coding in a procedural style.
Chapter 2 shows how we might represent real-world objects in Python using classes. We’ll write a program to simulate a light switch, modify it to include dimming capabilities, then move on to a more complicated TV remote simulation.
Chapter 3 gives you two different ways to think about what is going on behind the scenes when you create objects in Python.
Chapter 4 then demonstrates a standard way to handle multiple objects of the same type (for example, consider a simple game like checkers where you have to keep track of many similar game pieces). We’ll expand the bank account programs from Chapter 1, and explore how to handle errors.
1
Procedural Python Examples
Introductory courses and books typically teach software development using the procedural programming style, which involves splitting a program into a number of functions (also known as procedures or subroutines). You pass data into functions, each of which performs one or more computations and, typically, passes back results. This book is about a different paradigm of programming known as object-oriented programming (OOP) that allows programmers to think differently about how to build software. Object-oriented programming gives programmers a way to combine code and data together into cohesive units, thereby avoiding some complications inherent in procedural programming.
In this chapter, I’ll review a number of concepts in basic Python by building two small programs that incorporate various Python constructs. The first will be a small card game called Higher or Lower; the second will be a simulation of a bank, performing operations on one, two, and multiple accounts. Both will be built using procedural programming—that is, using the standard techniques of data and functions. Later, I’ll rewrite these programs using OOP techniques. The purpose of this chapter is to demonstrate some key problems inherent in procedural programming. With that understanding, the chapters that follow will explain how OOP solves those problems.
Higher or Lower Card Game
My first example is a simple card game called Higher or Lower. In this game, eight cards are randomly chosen from a deck. The first card is shown face up. The game asks the player to predict whether the next card in the selection will have a higher or lower value than the currently showing card. For example, say the card that’s shown is a 3. The player chooses higher,
and the next card is shown. If that card has a higher value, the player is correct. In this example, if the player had chosen lower,
they would have been incorrect.
If the player guesses correctly, they get 20 points. If they choose incorrectly, they lose 15 points. If the next card to be turned over has the same value as the previous card, the player is incorrect.
Representing the Data
The program needs to represent a deck of 52 cards, which I’ll build as a list. Each of the 52 elements in the list will be a dictionary (a set of key/value pairs). To represent any card, each dictionary will contain three key/value pairs: 'rank', 'suit', and 'value'. The rank is the name of the card (Ace, 2, 3, … 10, Jack, Queen, King), but the value is an integer used for comparing cards (1, 2, 3, … 10, 11, 12, 13). For example, the Jack of Clubs would be represented as the following dictionary:
{'rank': 'Jack', 'suit': 'Clubs', 'value': 11}
Before the player plays a round, the list representing the deck is created and shuffled to randomize the order of the cards. I have no graphical representation of the cards, so each time the user chooses higher
or lower,
the program gets a card dictionary from the deck and prints the rank and the suit for the user. The program then compares the value of the new card to that of the previous card and gives feedback based on the correctness of the user’s answer.
Implementation
Listing 1-1 shows the code of the Higher or Lower game.
NOTE
As a reminder, the code associated with all the major listings in this book is available for download at https://www.nostarch.com/object-oriented-python/ and https://github.com/IrvKalb/Object-Oriented-Python-Code/. You can either download and run the code or type it in yourself.
File: HigherOrLowerProcedural.py
# HigherOrLower
import random
# Card constants
SUIT_TUPLE = ('Spades', 'Hearts', 'Clubs', 'Diamonds')
RANK_TUPLE = ('Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King')
NCARDS = 8
# Pass in a deck and this function returns a random card from the deck
def getCard(deckListIn):
thisCard = deckListIn.pop()
# pop one off the top of the deck and return
return thisCard
# Pass in a deck and this function returns a shuffled copy of the deck
def shuffle(deckListIn):
deckListOut = deckListIn.copy()
# make a copy of the starting deck
random.shuffle(deckListOut)
return deckListOut
# Main code
print('Welcome to Higher or Lower.')
print('You have to choose whether the next card to be shown will be higher or lower than the current card.')
print('Getting it right adds 20 points; get it wrong and you lose 15 points.')
print('You have 50 points to start.')
print()
startingDeckList = []
1
for suit in SUIT_TUPLE:
for thisValue, rank in enumerate(RANK_TUPLE):
cardDict = {'rank':rank, 'suit':suit, 'value':thisValue + 1}
startingDeckList.append(cardDict)
score = 50
while True:
# play multiple games
print()
gameDeckList = shuffle(startingDeckList)
2
currentCardDict = getCard(gameDeckList)
currentCardRank = currentCardDict['rank']
currentCardValue = currentCardDict['value']
currentCardSuit = currentCardDict['suit']
print('Starting card is:', currentCardRank + ' of ' + currentCardSuit)
print()
3 for cardNumber in range(0, NCARDS): # play one game of this many cards
answer = input('Will the next card be higher or lower than the ' +
currentCardRank + ' of ' +
currentCardSuit + '? (enter h or l): ')
answer = answer.casefold() # force lowercase
4
nextCardDict = getCard(gameDeckList)
nextCardRank = nextCardDict['rank']
nextCardSuit = nextCardDict['suit']
nextCardValue = nextCardDict['value']
print('Next card is:', nextCardRank + ' of ' + nextCardSuit)
5
if answer == 'h':
if nextCardValue > currentCardValue:
print('You got it right, it was higher')
score = score + 20
else:
print('Sorry, it was not higher')
score = score - 15
elif answer == 'l':
if nextCardValue < currentCardValue:
score = score + 20
print('You got it right, it was lower')
else:
score = score - 15
print('Sorry, it was not lower')
print('Your score is:', score)
print()
currentCardRank = nextCardRank
currentCardValue = nextCardValue
currentCardSuit = nextCardSuit
6
goAgain = input('To play again, press ENTER, or q
to quit: ')
if goAgain == 'q':
break
print('OK bye')
Listing 1-1: A Higher or Lower game using procedural Python
The program starts by creating a deck as a list 1. Each card is a dictionary made up of a rank, a suit, and a value. For each round of the game, I retrieve the first card from the deck and save the components in variables 2. For the next seven cards, the user is asked to predict whether the next card will be higher or lower than the most recently showing card 3. The next card is retrieved from the deck, and its components are saved in a second set of variables 4. The game compares the user’s answer to the card drawn and gives the user feedback and points based on the outcome 5. When the user has made predictions for all seven cards in the selection, we ask if they want to play again 6.
This program demonstrates many elements of programming in general and Python in particular: variables, assignment statements, functions and function calls, if/else statements, print statements, while loops, lists, strings, and dictionaries. This book will assume you're already familiar with everything shown in this example. If there is anything in this program that is unfamiliar or not clear to you, it would probably be worth your time to review the appropriate material before moving on.
Reusable Code
Since this is a playing card–based game, the code obviously creates and manipulates a simulated deck of cards. If we wanted to write another card-based game, it would be great to be able to reuse the code for the deck and cards.
In a procedural program, it can often be difficult to identify all the pieces of code associated with one portion of the program, such as the deck and cards in this example. In Listing 1-1, the code for the deck consists of two tuple constants, two functions, some main code to build a global list that represents the starting deck of 52 cards, and another global list that represents the deck that is used while the game is being played. Further, notice that even in a small program like this, the data and the code that manipulates the data might not be closely grouped together.
Therefore, reusing the deck and card code in another program is not that easy or straightforward. In Chapter 12, we will revisit this program and show how an OOP solution makes reusing code like this much easier.
Bank Account Simulations
In this second example of procedural coding, I’ll present a number of variations of a program that simulates running a bank. In each new version of the program, I’ll add more functionality. Note that these programs are not production-ready; invalid user entries or misuse will lead to errors. The intent is to have you focus on how the code interacts with the data associated with one or more bank accounts.
To start, consider what operations a client would want to do with a bank account and what data would be needed to represent an account.
Analysis of Required Operations and Data
A list of operations a person would want to do with a bank account would include:
Create (an account)
Deposit
Withdraw
Check balance
Next, here is a minimal list of the data we would need to represent a bank account:
Customer name
Password
Balance
Notice that all the operations are action words (verbs) and all the data items are things (nouns). A real bank account would certainly be capable of many more operations and would contain additional pieces of data (such as the account holder’s address, phone number, and Social Security number), but to keep the discussion clear, I’ll start with just these four actions and three pieces of data. Further, to keep things simple and focused, I’ll make all amounts an integer number of dollars. I should also point out that in a real bank application, passwords would not be kept in cleartext (unencrypted) as it is in these examples.
Implementation 1—Single Account Without Functions
In the starting version in Listing 1-2, there is only a single account.
File: Bank1_OneAccount.py
# Non-OOP # Bank Version 1 # Single account
1
accountName = 'Joe'
accountBalance = 100
accountPassword = 'soup'
while True:
2
print()
print('Press b to get the balance')
print('Press d to make a deposit')
print('Press w to make a withdrawal')
print('Press s to show the account')
print('Press q to quit')
print()
action = input('What do you want to do? ')
action = action.lower()
# force lowercase
action = action[0]
# just use first letter
print()
if action == 'b':
print('Get Balance:')
userPassword = input('Please enter the password: ')
if userPassword != accountPassword:
print('Incorrect password')
else:
print('Your balance is:', accountBalance)
elif action == 'd':
print('Deposit:')
userDepositAmount = input('Please enter amount to deposit: ')
userDepositAmount = int(userDepositAmount)
userPassword = input('Please enter the password: ')
if userDepositAmount < 0:
print('You cannot deposit a negative amount!')
elif userPassword != accountPassword:
print('Incorrect password')
else:
# OK
accountBalance = accountBalance + userDepositAmount
print('Your new balance is:', accountBalance)
elif action == 's':
# show
print('Show:')
print(' Name', accountName)
print(' Balance:', accountBalance)
print(' Password:', accountPassword)
print()
elif action == 'q':
break
elif action == 'w':
print('Withdraw:')
userWithdrawAmount = input('Please enter the amount to withdraw: ')
userWithdrawAmount = int(userWithdrawAmount)
userPassword = input('Please enter the password: ')
if userWithdrawAmount < 0:
print('You cannot withdraw a negative amount')
elif userPassword != accountPassword:
print('Incorrect password for this account')
elif userWithdrawAmount > accountBalance:
print('You cannot withdraw more than you have in your account')
else:
#OK
accountBalance = accountBalance - userWithdrawAmount
print('Your new balance is:', accountBalance)
print('Done')
Listing 1-2: Bank simulation for a single account
The program starts off by initializing three variables to represent the data of one account 1. Then it displays a menu that allows a choice of operations 2. The main code of the program acts directly on the global account variables.
In this example, all the actions are at the main level; there are no functions in the code. The program works fine, but it may seem a little long. A typical approach to make longer programs clearer is to move related code into functions and make calls to those functions. We’ll explore that in the next implementation of the banking program.
Implementation 2—Single Account with Functions
In the version of the program in Listing 1-3, the code is broken up into separate functions, one for each action. Again, this simulation is for a single account.
File: Bank2_OneAccountWithFunctions.py
# Non-OOP # Bank 2 # Single account
accountName = ''
accountBalance = 0
accountPassword = ''
1
def newAccount(name, balance, password):
global accountName, accountBalance, accountPassword
accountName = name
accountBalance = balance
accountPassword = password
def show():
global accountName, accountBalance, accountPassword
print(' Name', accountName)
print(' Balance:', accountBalance)
print(' Password:', accountPassword)
print()
2
def getBalance(password):
global accountName, accountBalance, accountPassword
if password != accountPassword:
print('Incorrect password')
return None
return accountBalance
3
def deposit(amountToDeposit, password):
global accountName, accountBalance, accountPassword
if amountToDeposit < 0:
print('You cannot deposit a negative amount!')
return None
if password != accountPassword:
print('Incorrect password')
return None
accountBalance = accountBalance + amountToDeposit
return accountBalance
4
def withdraw(amountToWithdraw, password):
5
global accountName, accountBalance, accountPassword
if amountToWithdraw < 0:
print('You cannot withdraw a negative amount')
return None
if password != accountPassword:
print('Incorrect password for this account')
return None
if amountToWithdraw > accountBalance:
print('You cannot withdraw more than you have in your account')
return None
6
accountBalance = accountBalance - amountToWithdraw
return accountBalance
newAccount(Joe
, 100, 'soup')
# create an account
while True:
print()
print('Press b to get the balance')
print('Press d to make a deposit')
print('Press w to make a withdrawal')
print('Press s to show the account')
print('Press q to quit')
print()
action = input('What do you want to do? ')
action = action.lower()
# force lowercase
action = action[0]
# just use first letter
print()
if action == 'b':
print('Get Balance:')
userPassword = input('Please enter the password: ')
theBalance = getBalance(userPassword)
if theBalance is not None:
print('Your balance is:', theBalance)
7
elif action == 'd':
print('Deposit:')
userDepositAmount = input('Please enter amount to deposit: ')
userDepositAmount = int(userDepositAmount)
userPassword = input('Please enter the password: ')
8
newBalance = deposit(userDepositAmount, userPassword)
if newBalance is not None:
print('Your new balance is:', newBalance)
--- snip calls to appropriate functions ---
print('Done')
Listing 1-3: Bank simulation for one account with functions
In this version, I’ve