In [1]:
# Review of lists
# Define a new list
list1 = [3,2,4,5]
In [2]:
# access an element
list1
Out[2]:
[3, 2, 4, 5]
In [5]:
list1[3]
Out[5]:
5
In [6]:
list1[3]=17
In [7]:
list1
Out[7]:
[3, 2, 4, 17]
In [8]:
# Get length of list
len(list1) # returns length of list
Out[8]:
4
In [9]:
list1.append(81)
In [10]:
list1
Out[10]:
[3, 2, 4, 17, 81]
In [13]:
# get last elt of list
list1[len(list1)-1]
Out[13]:
81
In [14]:
list1[-1] #shorthand for last element
Out[14]:
81
In [15]:
l# get 2nd to last
ist1[-2]
Out[15]:
17
In [22]:
# code to compute the list corresponding to fibonacci seq:
# 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(5):
    fib_list.append(fib_list[-1]+fib_list[-2])
In [23]:
fib_list
Out[23]:
[1, 1, 2, 3, 5, 8, 13]
In [24]:
# CHALLENGE: generate a list of squares of integers 1,4,9,16,...
sq_list = []
for n in range(1,10):
    sq_list.append(n^2)
In [25]:
sq_list
Out[25]:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
In [26]:
# shorthand for above
[n^2 for n in range(1,10)]
Out[26]:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
In [27]:
# Strings are similar to lists of characters
st = "hello"
In [28]:
# can have space, numbers (also special characters)
st2="Hello World 31332"
In [31]:
# can access individual elts
st[-1]
Out[31]:
'o'
In [32]:
# can access individual elts
st2[5]
Out[32]:
' '
In [33]:
# difference between "c" and c (latter is variable, but it hasn't been defined)
st3="c"
In [35]:
st4 = c
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-35-65352af8b680> in <module>()
----> 1 st4 = c

NameError: name 'c' is not defined
In [36]:
c="g"
In [37]:
st5 = c
In [38]:
st5
Out[38]:
'g'
In [39]:
# Difference between 3 and '3'
h = 3
In [40]:
h+4
Out[40]:
7
In [41]:
h="3"
In [42]:
h
Out[42]:
'3'
In [43]:
# Can't add character '3' to number 4
h+4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-8cb32c24e301> in <module>()
----> 1 h+Integer(4)

/opt/sagemath-8.9/local/lib/python2.7/site-packages/sage/rings/integer.pyx in sage.rings.integer.Integer.__add__ (build/cythonized/sage/rings/integer.c:12197)()
   1790             return y
   1791 
-> 1792         return coercion_model.bin_op(left, right, operator.add)
   1793 
   1794     cpdef _add_(self, right):

/opt/sagemath-8.9/local/lib/python2.7/site-packages/sage/structure/coerce.pyx in sage.structure.coerce.CoercionModel.bin_op (build/cythonized/sage/structure/coerce.c:10896)()
   1205         # We should really include the underlying error.
   1206         # This causes so much headache.
-> 1207         raise bin_op_exception(op, x, y)
   1208 
   1209     cpdef canonical_coercion(self, x, y):

TypeError: unsupported operand parent(s) for +: '<type 'str'>' and 'Integer Ring'
In [45]:
# Can't change individual elts of a string
st[0] = "s"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-5b6fb987e686> in <module>()
      1 # Can't change individual elts of a string
----> 2 st[Integer(0)] = "s"

TypeError: 'str' object does not support item assignment
In [46]:
st = "this is a string"
In [47]:
st
Out[47]:
'this is a string'
In [48]:
# can have a list that contains similar info to string
st = ['h','e','l','l','o']
In [49]:
st
Out[49]:
['h', 'e', 'l', 'l', 'o']
In [50]:
# can change individual elt of list
st[0]='s'
In [51]:
st
Out[51]:
['s', 'e', 'l', 'l', 'o']
In [52]:
# Start of Cryptography unit
# "Keyboard cryptosystem"
alpha =      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
code_alpha = "QWERTYUIOPASDFGHJKLZXCVBNM" 
In [54]:
len(code_alpha) # check
Out[54]:
26
In [58]:
alpha.find("C") # function that gives index of c in alpha
Out[58]:
2
In [59]:
# function to "keyboard" encipher, sub A->Q, B->W, C->E, etc
def keyboard_encipher(plaintext):
    ciphertext = []
    for c in plaintext:
        # convert character c into a number, index of c in alpha
        numc = alpha.find(c)
        codedc = code_alpha[numc]
        ciphertext.append(codedc)
    return ciphertext
In [60]:
keyboard_encipher("CAB")
Out[60]:
['E', 'Q', 'W']
In [62]:
keyboard_encipher("ATTACKATDAWN")
Out[62]:
['Q', 'Z', 'Z', 'Q', 'E', 'A', 'Q', 'Z', 'R', 'Q', 'V', 'F']
In [63]:
# CHALLENGE: write a deciphering function
# code to decipher, switch roles of alpha, code_alpha
# switch roles of ciphertext, plaintext
def keyboard_decipher(ciphertext):
    plaintext = []
    for c in ciphertext:
        # convert character c into a number, index of c in code_alpha
        numc = code_alpha.find(c)
        decodedc = alpha[numc]
        plaintext.append(decodedc)
    return plaintext
In [64]:
keyboard_decipher("EQW")
Out[64]:
['C', 'A', 'B']
In [65]:
keyboard_decipher(['Q', 'Z', 'Z', 'Q', 'E', 'A', 'Q', 'Z', 'R', 'Q', 'V', 'F'])
Out[65]:
['A', 'T', 'T', 'A', 'C', 'K', 'A', 'T', 'D', 'A', 'W', 'N']
In [83]:
# convert list into string (easier to read)
":".join(keyboard_decipher("EQW"))
Out[83]:
'C:A:B'
In [75]:
# Shift/Caesar cipher
# shift by 3 (wrapping around at 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 character c into a number, index of c in alpha
        numc = alpha.find(c)
        shiftednumc = (numc + 3) % 26 # mod 26, since wrap around alphabet
        codedc = alpha[shiftednumc]
        ciphertext.append(codedc)
    return ciphertext
In [71]:
shift3_cipher("CAB")
Out[71]:
['F', 'D', 'E']
In [72]:
shift3_cipher("ATTACKATDAWN")
Out[72]:
['D', 'W', 'W', 'D', 'F', 'N', 'D', 'W', 'G', 'D', 'Z', 'Q']
In [74]:
# Shift/Caesar cipher
# shift by amount given by shift parameter
def shift_cipher(plaintext, shift):
    ciphertext = []
    for c in plaintext:
        # convert character c into a number, index of c in alpha
        numc = alpha.find(c)
        shiftednumc = (numc + shift) % 26 # mod 26, since wrap around alphabet
        codedc = alpha[shiftednumc]
        ciphertext.append(codedc)
    return ciphertext
In [79]:
shift_cipher("CAB", 3)
Out[79]:
['F', 'D', 'E']
In [80]:
(-3) % 26 # gives number between 0 and 25
Out[80]:
23
In [81]:
# to decipher use -shift
shift_cipher(['F', 'D', 'E'], -3)
Out[81]:
['C', 'A', 'B']
In [82]:
shift_cipher(['D', 'W', 'W', 'D', 'F', 'N', 'D', 'W', 'G', 'D', 'Z', 'Q'],-3)
Out[82]:
['A', 'T', 'T', 'A', 'C', 'K', 'A', 'T', 'D', 'A', 'W', 'N']