String Exercises

 
# -------------------------- String Exercises -----------------------

# Problem 1a.
def ToUpper(s):
    low = 'abcdefghijklmnopqrstuvwxyz'
    up  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    answer = ''
    for i in range(len(s)):
        c = s[i]
        pos = low.find(c)
        if pos >= 0:
            answer += up[pos]
        else:
            answer += c
    return answer

# Problem 1b.
def Encrypt(s):
    Julius_before='defghijklmnopqrstuvwxyzabcDEFGHIJKLMNOPQRSTUVWXYZABC'
    Julius_after ='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    answer = ''
    for i in range(len(s)):
        c = s[i]
        pos = Julius_before.find(c)
        if pos >= 0:
            answer += Julius_after[pos]
        else:
            answer += c
    return answer

def Decrypt(s):
    Julius_before='defghijklmnopqrstuvwxyzabcDEFGHIJKLMNOPQRSTUVWXYZABC'
    Julius_after ='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    answer = ''
    for i in range(len(s)):
        c = s[i]
        pos = Julius_after.find(c)
        if pos >= 0:
            answer += Julius_before[pos]
        else:
            answer += c
    return answer
   
# But look, we can generalize from Encrypt and Decryt and ToUpper....
# All we need, in general, is a "before-alphabet" and an "after-alphabet", which we can give to a general encryption/decryption function:

def EncryptDecryptGeneral(alpha_before, alpha_after, s):
    answer = ''
    for i in range(len(s)):
        c = s[i]
        pos = alpha_before.find(c)
        if pos >= 0:
            answer += alpha_after[pos]
        else:
            answer += c
    return answer

# So, here's the way to use this for ToUpper():
def ToUpper2(s):
    return EncryptDecryptGeneral('abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ',s)

def ToLower2(s):
    return EncryptDecryptGeneral('ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz',s)
  
# --------------------------------------------
# Problem 2a.
def IsSameName(name1,name2):
    if ToUpper(name1) == ToUpper(name2):
        return True
    return False

# Problem 2b.
def CapWord(s):
    return ToUpper(s[0]) + ToLower2(s[1:])

# Problem 2c.
def CapName(name):
    pos = name.find(' ')  # find the position of the space character
    first = name[:pos]
    last = name[pos+1:]
    return CapWord(first) + ' ' + CapWord(last)

# -----------------------------------
# The FirstLast Exercises...
# A way to approach these is to think about entire chunks, or slices, of the string.

#Problem 3a.
def FirstLast(name):
    # we know that there is a comma followed by a space...
    pos_comma = name.find(',')
    #... and the last name is everything, from the beginning of the string...
    #  ..."up to but not including" the position of the comma
    last = name[:pos_comma]
    # everything from pos_comma+2 to the end is the first name:
    first = name[pos_comma+2:]
    return first+" "+last

# For the FirstLastSequence, take the incoming string, chop off the first full name,
#   convert it, add it to the answer, then chop off the next full name, until you
#   have nothing left

# Problem 3b.
def FirstLastSequence(names):
    answer = ''
    while len(names) > 0: # go until you have no names left
        pos_semi = names.find(';')
        unconverted = names[:pos_semi]
        converted = FirstLast(unconverted)
        # add it to the answer
        answer += converted+';'
        # remove it from names
        names = names[pos_semi+1:]
    return answer

# --------------------------------------
# Problem 4.
def FileClassifier(filename):
    # find the last position of a period...
    pos = filename.rfind('.')
    suffix = filename[pos+1:].lower()
    if suffix == 'jpg' or suffix == 'jpeg':
        return 'picture'
    if suffix == 'mp3':
        return 'music'
    if suffix == 'nlogo':
        return 'Netlogo'
    if suffix == 'py':
        return 'Python'
    return 'Who knows?'

# ----------------------------------------------------
# The Triple Challenge Problem
# Here's a small listing of some of NY's sports teams... let's assume that we'll find one of the in the plaintext of the
# message given.


Teams = 'METS;YANKEES;KNICKS;GIANTS;RANGERS;JETS'
Low = 'abcdefghijklmnopqrstuvwxyz'
Up  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

# Here's the strategy:
# create a function that will shift all upper- or lower-case letters by n positions (0 <= n <= 25) called ShiftByN(c,n)

def ShiftByN(s,n):
    answer = ''
    for i in range(len(s)):
        c = s[i]
        # if it's an upper-case letter, shift it
        pos = Up.find(c)
        if pos >= 0:
            answer += Up[(pos+n)%26]
        else:
            # if it's a lower-case letter, shift it
            pos = Low.find(c)
            if pos >= 0:
                answer += Low[(pos+n)%26]
            else:
                # otherwise don't modify it
                answer += c
    return answer

def TCP(crypt_text,teams):
    # get and try each team name from teams, and then remove that team name, until there's nothing left to remove
    while len(teams) > 0:
        pos = teams.find(';')
        ateam = teams[:pos]
        # now try every shift from 0 to 25
        for i in range(26):
            crypt_shift = ShiftByN(crypt_text,i)
            if crypt_shift.upper().find(ateam) >= 0:
                #  all right, we found it!
                return crypt_shift
        # remove this team from the listing
        teams = teams[pos+1:]
    return 'Sadness'