# Review of lists
# Define a new list
list1 = [2, 3, 7, 11]
# access an element
list1[2]
list1[2]=13
list1
# Get length of list
len(list1)
list1[3]
# get last elt of list
list1[len(list1)-1]
# shorthand for the above (get last element)
list1[-1]
# get 2nd to last
list1[-2]
# Add new elt to end of list
list1.append(20)
list1
# code to make a list out of fibonacci sequence:
# 1, 1, 2, 3, 5, 8, 11
# first two elts are 1, then each after is sum of previous two
fib_list = [1,1] # initial condition
for n in range(4):
fib_list.append(fib_list[-1] + fib_list[-2])
fib_list
# CHALLENGE: create a list of squares 1,4,9,16,...
sq_list = []
for n in range(1,10):
sq_list.append(n^2)
sq_list
# shorthand for the above
[n^2 for n in range(1,10)]
# strings, similar to a list of characters
st = "hello"
# can have space, numbers (also special characters)
st2 = "this is a string1231"
# can access individual elts
st[1]
# this contains similar info to string above
list2 = ['h', 'e', 'l', 'l', 'o']
list2[0]
# difference between "h" and h (latter is variable, but it hasn't been defined)
list2 = [h, e]
h = 3
e = 7
list2 = [h, e]
list2
# Difference between 2 and '2'
n = 2
n+3
m ='2'
# Can't add character '2' to number 3
m+3
# strings: can't change individual elts, unlike with lists
st="hello"
st[0]='s'
# can't append to end of string
st.append("s")
st = "this is a string"
st
# Start of Cryptography unit
# "Keyboard" cryptosystem
alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
code_alpha = "QWERTYUIOPASDFGHJKLZXCVBNM"
len(alpha) #checks
len(code_alpha)
alpha.find('C') # returns index of the argument
# For sub_encipher, want to substitue A->Q, B->W, C-> E etc
def sub_encipher(plaintext):
ciphertext = []
for c in plaintext:
# convert character to c to a number, index of c in alpha
numc = alpha.find(c)
# convert numc to character in code_alpha
codedc = code_alpha[numc]
ciphertext.append(codedc)
return ciphertext
sub_encipher("ATTACKATDAWN")
# code to decipher, switch roles of alpha, code_alpha
# switch roles of ciphertext, plaintext
def sub_decipher(ciphertext):
plaintext = []
for c in ciphertext:
# convert character to c to a number, index of c in alpha
numc = code_alpha.find(c)
# convert numc to character in code_alpha
decodedc = alpha[numc]
plaintext.append(decodedc)
return plaintext
sub_decipher(['Q', 'Z', 'Z', 'Q', 'E', 'A', 'Q', 'Z', 'R', 'Q', 'V', 'F'])
# convert list of characters to string (easier to read)
"".join(sub_encipher("ATTACKATDAWN"))
# shift (Caesar) cipher
# shift place in alphabet by 3 spaces (wrap around end of alphabet)
# A->D, B->E, C->F, ..., X->A, Y->B, Z->C
def shift3_cipher(plaintext):
ciphertext = []
for c in plaintext:
# convert char to index in alpha
numc = alpha.find(c)
# shift by 3; use mod 26 to wrap around end of alphabet
shiftnumc = (numc + 3) % 26
# convert back to char in alpha
codedc = alpha[shiftnumc]
ciphertext.append(codedc)
return ciphertext
shift3_cipher("ATTACKATDAWNZ")
# shift (Caesar) cipher
# shift by amount given by shift parameter
def shift_cipher(plaintext, shift):
ciphertext = []
for c in plaintext:
# convert char to index in alpha
numc = alpha.find(c)
# shift
shiftnumc = (numc + shift) % 26
# convert back to char in alpha
codedc = alpha[shiftnumc]
ciphertext.append(codedc)
return ciphertext
shift_cipher("ATTACKATDAWNZ",3)
(-3)% 26 # modular arithmetic
# To decipher, use -shift
shift_cipher(['D', 'W', 'W', 'D', 'F', 'N', 'D', 'W', 'G', 'D', 'Z', 'Q', 'C'],-3)
# this cipher has weaknesses : preserves frequencies of letters
#"key" for shift cipher is the amount of shifting (shift)