# Python Shortcuts

There are a few operations that you use (or will use) that we should revisit to ensure we're approaching them in the most efficient way possible.

## Assignment Operators

You've probably seen that cryptography and loops have required us to frequently use a variable as a running total, to which you repeatedly add or append values. We may have seen something like:

counter = counter + 1

or

ciphertext = ciphertext + char

To simplify this syntax, you could instead have used the following commands, which are called assignment operators:

counter += 1

or

ciphertext += char

The += command, perhaps not surprisingly, adds the value of the object on the right of the symbol to the value of the object on the left of the symbol and then sets it equal to the new value. This operator works like addition for integers and floats, and like concatenation for strings. For integers and floats there are similar commands for subtraction (-=), multiplication (*=), and division (/=). Since there are no equivalent operations for strings, these operators do not work with strings. Here's a table of valid assignment operators in Python.

Operator Example Same as
+= x += 2 x = x + 2
-= x -= 2 x = x - 2
*= x *= 2 x = x * 2
/= x /= 2 x = x / 2
%= x %= 2 x = x % 2
//= x //= 2 x = x // 2
**= x **= 2 x = x ** 2

While these operators don't add any new functionality, they will save you some keystrokes when you don't have to type your variable names repeatedly.

## Text Cleaning

As we've seen, once we have a message stored to plaintext often the first thing we want to do is "clean" that text so it is formatted in a predictable way. For our classical ciphers, that means it should all be in the same case, contain no spaces, and contain no punctuation. It may be tempting to attempt a black-list approach the replaces characters you don't like using the replace() command, like how we've done so far for spaces.

plaintext = 'ThiS is. Fi//ed with J3nk'
plaintext = plaintext.replace(' ','').replace('/','').replace('.','').replace('3','').upper()
print(plaintext)

THISISFIEDWITHJNK


But it's almost impossible to predict what special characters your plaintext message may include. The previous example code would fail if the plaintext string contained any other special character besides the ones explicitly checked for. Never underestimate the ability of your end user finding ways to break your code! A safer approach would be to utilize a white-listing system that only lets the characters you want through.

plaintext = 'ThiS is. Fi//ed with J3nk'
plaintext = plaintext.upper()
cleaned = ''
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

for char in plaintext:
if char in LETTERS:
cleaned += char

print( cleaned )

THISISFIEDWITHJNK


This code starts by using the upper() method to change all the letters in the string plaintext to uppercase, and then store it back to plaintext. Then, it creates a new empty string cleaned where it will add characters that are in the string LETTERS. The string LETTERS contains all the letters we have deemed valid for our alphabet.

For simplicity sake we will keep only using the 26 uppercase letters (it's also historically more accurate), but there's no reason why you couldn't also include the 26 lowercase letters, and 10 single digit numbers in your LETTERS string (LETTERS = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789). In fact, there's a whole text system called Base64 that essentially does just that. However, if you did this you would need to account for it in all your ciphers, since you have effectively increased the size of your alphabet to 62 characters. As a result, modding by 26 would no longer be valid, and you would also need to ensure that whatever keys you're using are still valid in the new size alphabet.