Table of Contents
Preface xiii
Chapter 1: Developing Simple Applications 1
Important housekeeping notes 2
Installation prerequisites 2
Installing Python 3
Option 1 – offcial distribution 3
Option 2 – bundled distribution 4
Python install location 5
Verifying Python installation 6
Installing pip 7
Installing IPython 7
Choosing an IDE 8
The theme of the book 9
Meet the characters 10
Simple script – Attack of the Orcs v0.0.1 11
The game – Attack of the Orcs v0.0.1 11
Problem statement 12
Pseudo code – version 0.0.1 12
Reviewing the code 13
Running Attack of the Orcs v0.0.1 17
Using functions – Attack of the Orcs v0.0.5 18
Revisiting the previous version 19
Pseudo code with attack feature – Version 0.0.5 22
Reviewing the code 24
Running Attack of the Orcs v0.0.5 28
Using OOP – Attack of the Orcs v1.0.0 29
Prioritize the feature requests 30
Problem statement 31
Redesigning the code 31
Painting the big picture 32
Pseudo UML representation 33
Understanding the pseudo UML diagram 34
Reviewing the code 35
Running Attack of the Orcs v1.0.0 40
Abstract base classes in Python 40
Exercise 42
Summary 43
Very important note for e-book readers 44
Chapter 2: Dealing with Exceptions 45
Revisiting Attack of the Orcs v1.0.0 45
Debugging the problem 46
Fixing the bugs… 48
Exceptions 49
What is an exception? 49
Most common exceptions 49
Exception handling 51
Raising and re-raising an exception 52
The else block of try…except 54
fnally...clean it up! 55
Back to the game – Attack of the Orcs v1.1.0 58
Preparatory work 58
Adding the exception handling code 59
Running Attack of the Orcs v1.1.0 60
Defning custom exceptions 61
Preparatory work 61
Custom exception – The problem 61
Writing a new exception class 63
Expanding the exception class 65
Inheriting from the exception class 68
Exercise 71
Summary 71
Chapter 3: Modularize, Package, Deploy! 73
Selecting a versioning convention 74
Serial increments 74
Using a date format 76
Semantic versioning scheme 76
Modularizing the code 77
Attack of the Orcs v2.0.0 77
Creating a package 80
Importing from the package 80
Releasing the package on PyPI 82
Prepare the distribution 82
Step 1 – Setting up the package directory 83
Step 2 – Writing the setup.py fle 84
Step 3 – Updating the README and LICENSE.txt fles 85
Step 4 – Updating the MANIFEST.in fle 86
Step 5 – Build a deployment-ready distribution 86
Uploading the distribution 88
Step 1 – Creating an account on PyPI test website 88
Step 2 – Creating a .pypirc fle 88
Step 3 – Register your project 89
Step 4 – Uploading the package 90
A single command to do it all 92
Installing your own distribution 92
Using a private PyPI repository 94
Step 1 – Installing pypiserver 94
Step 2 – Building a new source distribution 94
Step 3 – Starting a local server 95
Step 4 – Installing the private distribution 96
Making an incremental release 97
Packaging and uploading the new version 97
Upgrading the installed version 97
Version controlling the code 98
Git resources 98
Installing Git 98
Confguring your identity 99
Basic Git terminology 99
Creating and using a Git repository 100
Creating a bare remote repository 101
Clone the repository 101
Copying the code to the cloned repository 102
Staging the code and committing 102
Pushing the changes to the central repository 103
Using GUI clients for Git 104
Exercise 104
Summary 105
Chapter 4: Documentation and Best Practices 107
Documenting the code 109
Docstrings 110
Introduction to reStructuredText 111
Section headings 111
Paragraphs 112
Text styles 113
Code snippets 113
Mathematical equations 113
Bullets and numbering 114
Dosctrings using RST 114
Docstring formatting styles 117
Automatically creating docstring stubs 118
Generating documentation with Sphinx 120
Step 1 – Installing Sphinx using pip 121
Step 2 – cd to the source directory 121
Step 3 – Running sphinx-quickstart 122
Step 4 – Updating conf.py 123
Step 5 – Running sphinx-apidoc 124
Step 6 – Building the documentation 125
Python coding standards 127
Code analysis – How well are we doing? 130
Code analysis using IDE 131
Pylint 132
Pylint in action 132
PEP8 and AutoPEP8 136
Exercise 137
Summary 137
Chapter 5: Unit Testing and Refactoring 139
This is how the chapter is organized 140
Important housekeeping notes 140
Why test? 140
A new feature was requested 141
You implemented this feature 141
But something wasn't right... 142
It required thorough testing 144
Unit testing 144
Python unittest framework 145
Basic terminology 145
Creating tests with unittest.TestCase 146
Controlling test execution 148
Using unittest.TestSuite 150
Writing unit tests for the application 153
Setting up a test package 154
Creating a new class for unit testing 154
First unit test – Injured unit selection 156
Running the frst unit test 156
Second unit test – Acquiring the hut 157
Running only the second test 160
Creating individual test modules 160
Batch executing unit tests 161
Unit tests using mock library 162
Quick introduction to mock 162
Let's mock! 164
Using Mock objects in a unit test 166
Working with patches 168
Using patch in a unit test 169
Third unit test – The play method 171
Is your code covered? 175
Resolving import errors, if any 177
Other unit testing tools 177
Doctest 178
Nose 178
Pytest 179
Refactoring preamble 180
Take a detour – Refactor for testability 181
Refactoring 181
What is refactoring? 182
Why refactor? 182
When to refactor? 182
How to refactor? 184
Renaming 184
Extracting 184
Moving 186
Pushing down 186
Pulling up 188
Refactoring tools for Python 188
Unit testing revisited 189
Refactoring for testability 189
Fourth unit test – setup_game_scenario 191
Exercise 192
Refactoring and redesign exercise 192
Summary 192
Chapter 6: Design Patterns 193
Introduction to design patterns 194
Classifcation of patterns 194
Behavioral patterns 195
Creational patterns 195
Structural patterns 195
Concurrency patterns 195
Python language and design patterns 196
First-class functions 196
Classes as frst-class objects 197
Closures 197
Miscellaneous features 199
Class method 199
Abstract method 199
The __getattr__ method 199
Duck typing 200
Structure of the rest of the chapter 201
Fast forward – Attack of the Orcs v6.0.0 202
Strategy pattern 205
Strategy scenario – The jump feature 205
Strategy – The problem 207
Strategy – Attempted solution 209
Strategy – Rethinking the design 211
Strategy solution 1 – Traditional approach 212
Strategy solution 2 – Pythonic approach 218
Simple factory 220
Simple factory scenario – The recruit feature 220
Simple factory – The problem 221
Simple factory – Rethinking the design 222
Simple factory solution 1 – Traditional approach 224
Simple factory solution 2 – Pythonic approach 225
Abstract factory pattern 228
Abstract factory scenario – An accessory store 229
Abstract factory – The problem 233
Abstract factory – Rethinking the design 234
Simplifying the design further 235
Abstract factory solution – Pythonic approach 236
Advanced topic – enforcing an interface 238
Adapter pattern 239
Adapter scenario – Elf's distant cousin 240
Adapter – The problem 240
Adapter – Attempted solution 242
Adapter solution – Pythonic approach 244
Adapter – Multiple adapter methods 246
Summary 247
Chapter 7: Performance – Identifying Bottlenecks 249
Overview of three performance chapters 249
More focus on the runtime performance 250
The frst performance chapter 250
The second performance chapter 251
The third performance chapter 251
Sneak peek at the upcoming application speedup 251
Scenario – The Gold Hunt 253
High-level algorithm 255
Reviewing the initial code 256
Running the code 260
The problem 260
Identifying the bottlenecks 262
Measuring the execution time 262
Measuring the runtime of small code snippets 263
Code profling 263
The cProfle module 263
The pstats module 266
The line_profler package 269
Memory profling 271
The memory_profler package 271
Algorithm effciency and complexity 272
Algorithm effciency 272
Algorithm complexity 273
Big O notation 273
Big O complexity classes 274
O(1) – constant time 275
O(log n) – logarithmic 275
O(n) – Linear time 276
O(n log n) – Log linear 276
O(n2) – Quadratic 277
O(n3) – cubic 277
Upper bound of the complexity 278
Complexity for common data structures and algorithms 279
Wrapping up the big O discussion 280
Summary 281
Chapter 8: Improving Performance – Part One 283
Prerequisite for the chapter 284
This is how the chapter is organized 284
Revisiting the Gold Hunt scenario 285
Selecting a problem size 285
Profling the initial code 286
Optimizing Gold Hunt – Part one 287
Tweaking the algorithm – The square root 287
Gold Hunt optimization – Pass one 290
Skipping the dots 291
Gold Hunt optimization – Pass two 292
Using local scope 294
Gold Hunt optimization – Pass three 294
Performance improvement goodies 297
List comprehension 297
Recording execution time 299
Dictionary comprehension 300
Swapping conditional block and for loops 300
'try' it out in a loop 302
Choosing the right data structures 303
The collections module 304
The deque class 304
The defaultdict class 305
Generators and generator expressions 307
Generator expressions 309
Comparing the memory effciency 309
Generator expressions or list comprehensions? 311
The itertools module 312
The itertools.chain iterator 312
Exercises 315
Summary 315
Chapter 9: Improving Performance – Part Two, NumPy
and Parallelization 317
Prerequisites for this chapter 317
This is how the chapter is organized 318
Introduction to NumPy 319
Installing NumPy 319
Creating array objects 320
Simple array operations 321
Array slicing and indexing 322
Indexing 322
Slicing 323
Broadcasting 325
Miscellaneous functions 325
numpy.ndarray.tolist 326
numpy.reshape 326
numpy.random 326
numpy.dstack 327
numpy.einsum 328
Computing distance square with einsum 331
Where to get more information on NumPy? 333
Optimizing Gold Hunt – Part two 333
Gold Hunt optimization – pass four 334
Gold Hunt optimization – pass fve 336
Parallelization with the multiprocessing module 341
Introduction to parallelization 341
Shared memory parallelization 341
Distributed memory parallelization 342
Global interpreter lock 342
The multiprocessing module 342
The Pool class 342
Parallelizing the Gold Hunt program 346
Revisiting the gold feld 347
Gold Hunt optimization – Pass six, parallelization 349
Other methods for parallelization 354
Further reading 355
JIT compilers 355
GPU accelerated computing 356
Summary 356
Chapter 10: Simple GUI Applications 359
Overview of GUI frameworks 360
Tkinter 360
PyQt 360
PySide 361
Kivy 361
wxPython 361
Table of Contents
GUI programming design considerations 362
Understanding user requirements 362
Developing a user story 362
Simplicity and accessibility 362
Consistency 363
Predictability and familiarity 363
Miscellaneous design considerations 363
Event-driven programming 364
Event 364
Event handling 364
Event loop 365
GUI programming with Tkinter 365
Tkinter documentation links 365
The mainloop() in Tkinter 366
Simple GUI application – Take 1 367
Simple GUI application – Take 2 369
GUI Widgets in Tkinter 371
Geometry management 374
Grid geometry manager 374
Pack geometry manager 375
Place geometry manager 375
Events in Tkinter 376
Event types 376
Event descriptors 376
Event object attributes 377
Event handling in Tkinter 377
Command callback (Button widget) 378
The bind() method 378
The bind_class() method 379
The bind_all() method 380
Project-1 – Attack of the Orcs V10.0.0 380
Background scenario 381
Problem statement 381
Writing the code 382
Overview of the class HutGame 383
The __init__ method 384
The occupy_huts method 384
The create_widgets method 385
The setup_layout method 387
The radio_btn_pressed and enter_hut methods 389
The announce_winner method 390
Running the application 390
MVC architecture 392
Model 392
View 393
Controller 393
Advantages of MVC 394
Project 2 – Attack of the Orcs v10.1.0 394
Revisiting the HutGame class 395
Creating MVC classes 395
Communication between MVC objects 396
Controller to Model or View communication 397
Model to Controller communication 397
View to Controller communication 400
Communication between View and Model 400
Reviewing the code 401
The Controller class 402
The Model class 403
The View class 404
Running the application 405
Testing GUI applications 405
Testing considerations 405
Unit testing and MVC 406
Manual testing 406
Automated GUI testing 406
Exercises 407
Further reading 408
Summary 410
Index 413
- Log in to post comments