Impractical Python Projects

Impractical Python Projects

Playful Programming Activities to Make You Smarter
by Lee Vaughan
November 2018, 424 pp.
ISBN-13: 
9781593278908

"Python is a programming language, but it is also fun to play with. This book recognises that."
—Geek Tech Stuff

"Rather than being an introductory text, Vaughan’s book pushes you in interesting directions for solving a diverse set of problems. Most of these “impractical” projects, while themselves being not so useless after all, will have parallels to real life projects." Greg Laden, Greg Laden's Blog


Download Chapter 3: Solving Anagrams
Download the code files and solutions to the book's programs at its GitHub page

Impractical Python Projects picks up where the complete beginner books leave off, expanding on existing concepts and introducing new tools that you’ll use every day. And to keep things interesting, each project includes a zany twist featuring historical incidents, pop culture references, and literary allusions.

You’ll flex your problem-solving skills and employ Python’s many useful libraries to do things like:

  • Help James Bond crack a high-tech safe with a hill-climbing algorithm
  • Write haiku poems using Markov Chain Analysis
  • Use genetic algorithms to breed a race of gigantic rats
  • Crack the world’s most successful military cipher using cryptanalysis
  • Foil corporate security with invisible electronic ink
  • Derive the anagram, “I am Lord Voldemort” using linguistical sieves
  • Plan your parents’ secure retirement with Monte Carlo simulation
  • Save the sorceress Zatanna from a stabby death using palingrams
  • Model the Milky Way and calculate our odds of detecting alien civilizations
  • Help the world’s smartest woman win the Monty Hall problem argument
  • Reveal Jupiter’s Great Red Spot using optical stacking
  • Save the head of Mary, Queen of Scots with steganography

Simulate volcanoes, map Mars, and more, all while gaining valuable experience using free modules like Tkinter, matplotlib, Cprofile, Pylint, Pygame, Pillow, and Python-Docx.

Whether you’re looking to pick up some new Python skills or just need a pick-me-up, you’ll find endless educational, geeky fun with Impractical Python Projects.

Author Bio 

Lee Vaughan is a geologist with over 30 years' experience in the petroleum industry. As the Senior Technical Professional for Geological Modeling at a major international oil company, he was involved in the construction and review of computer models, the development, testing, and commercialization of software, and the training of geoscientists and engineers. An advocate for nonprogrammers who must use programming in their careers, he wrote Impractical Python Projects to help self-learners hone their skills with the Python language.

Table of contents 

Introduction
Chapter 1: Silly Name Generator
Chapter 2: Finding Palingram Spells
Chapter 3: Solving Anagrams
Chapter 4: Decoding American Civil War Ciphers
Chapter 5: Encoding English Civil War Ciphers
Chapter 6: Writing in Invisible Ink
Chapter 7: Breeding Giant Rats with Genetic Algorithms
Chapter 8: Counting Syllables for Haiku Poetry
Chapter 9: Writing Haiku with Markov Chain Analysis
Chapter 10: Are We Alone? Exploring the Fermi Paradox
Chapter 11: The Monty Hall Problem
Chapter 12: Securing your Nest Egg
Chapter 13: Simulating an Alien Volcano
Chapter 14: Mapping Mars with the Mars Orbiter
Chapter 15: Improving Your Astrophotography with Planet Stacking
Chapter 16: Finding Frauds with Benford's Law
Appendix: Practice Project Solutions

View the detailed Table of Contents
View the Index

Reviews 

"Python is programming language, but it is also fun to play with and this book recognises that."
—Geek Tech Stuff

"Rather than being an introductory text, Vaughan’s book pushes you in interesting directions for solving a diverse set of problems. Most of these “impractical” projects, while themselves being not so useless after all, will have parallels to real life projects." Greg Laden, Greg Laden's Blog

Updates 

Page 79: code output at bottom of page is based on Figure 4-3, not Figure 4-2.

Page 85: In Listing 4-9, the code at wingding 5 and the following line that read:

    row1 = (message[:row_1_len])
    row2 = (message[row_1_len:])

Should instead read:

    row1 = (message[:row_1_len]).lower()
    row2 = (message[row_1_len:]).lower()

Also in Listing 4-9, the code immediately below wingding 8 that reads:

        plaintext.append(r1.lower())
        plaintext.append(r2.lower())

Should instead read:

        plaintext.append(r1)
        plaintext.append(r2)

Page 100: The output printout near the bottom of page that reads:
Panel at east end of chapel slides
Should instead read:
Panelateastendofchapelslides

Page 103: The cipher example that reads:
The cold tea didn’t please the old finicky woman.
Should instead read:
So, the cold tea didn’t please the old finicky woman.

Page 141: Wingding 7 and the preceding line in Listing 7-10 that read:

lock_wheel = int(randrange(0, len(combo)))
next_try[lock_wheel] = randint(0, len(combo)-1)

Should instead read:

lock_wheel = randrange(0, len(combo))
next_try[lock_wheel] = randint(0, 9)

Page 205: The line and following equation that read:
The transformation to generate points over a unit disc is as follows:
x= √r*cos
Should instead read as:
The transformation to generate points evenly over a unit disc is:
x= √r*cosθ

And the line that reads:
The equations yield (x, y) values between 0 and 1.
Should instead read as:
The equations yield (x, y) values between -1 and 1.

Page 218: Indentation for the listing on the page should be as follows:

>>> from random import randint
>>> trials = 100000
>>> success = 0
>>> for trial in range(trials):
           faces = set()
           for rolls in range(6):
               roll = randint(1, 6)
               faces.add(roll)
           if len(faces) == 6:
               success += 1
>>> print("probability of success = {}".format(success/trials))
probability of success = 0.01528

Page 250: Listing 12-1 should read as:

import sys
import random
import matplotlib.pyplot as plt
 
def read_to_list(file_name):   
    """Open a file of data in percent, convert to decimal & return a list."""
    with open(file_name) as in_file: 
        lines = [float(line.strip()) for line in in_file] 
        decimal = [round(line / 100, 5) for line in lines]
        return decimal
 
def default_input(prompt, default=None):    
    """Allow use of default values in input"""
    prompt = '{} [{}]: '.format(prompt, default)
    response = input(prompt)
    if not response and default:        
        return default    
    else:        
        return response

Page 252: The last line on page that reads:
Set the default to 'sbc_blend', since this is theoretically the most stable mix of the four choices.
Should instead read as:
Set the default to 'bonds', in order to see how this supposedly “safe” choice performs.

Page 259: The first line in last paragraph that reads:
Let’s work an example that assumes a starting value of $2,000,000, a “safe and secure” bond portfolio, a 4 percent withdrawal rate (equal to $80,000 per year), a 30-year retirement, and 50,000 cases.

Should instead read as:
Let’s work an example that assumes a starting value of $2,000,000, a “safe and secure” bond portfolio, a 4 percent withdrawal rate (equal to $80,000 per year), a 29-30-31 retirement range, and 50,000 cases.

Page 261: The last two lines in Listing 12-9 that read:

    investments -= withdraw_infl_adj
          investments = int(investments * (1 + i))          

Should instead read as:

            investments -= withdraw_infl_adj
            investments = int(investments * (1 + i))            

Page 305: In the last paragraph, transform_rotate() should be transform.rotate()

Page 356: Between wingdings 5 and 6, Listing 16-2 should read as:

    # check for missing digits
    keys = [str(digit) for digit in range(1, 10)]
    for key in keys:
        if key not in first_digits:
            first_digits[key] = 0          

Page 368: The code for Dictionary Cleanup should read as:

"""Remove single-letter words from list if not 'a' or 'i'."""
word_list = ['a', 'nurses', 'i', 'stack', 'b', 'c', 'cat']
word_list_clean = []
 
permissible = ('a', 'i')
 
# remove single-letter words if not "a" or "I"
for word in word_list:
    if len(word) > 1:
        word_list_clean.append(word)
    elif len(word) == 1 and word in permissible:
        word_list_clean.append(word)
    else:
        continue
 
print("{}".