I am new to python and programming this is my first time using the code (first assignment). I need help with writing a program to convert the code message entered by the user into ascii numbers, then find which number occurs 12% of the time, and have it represent the letter E (also t is the second most occuring letter at 9% and i'm not sure if I should use that to check), then once I know which letter E is, I have to find out how many letters E is from the letter used in the code to find the shift count.

I did this in lab with help from a TA to get started but I dont understand how to put the logic into code.

This program asked the user for a sentence and changes it into code by a shift of 13. I am completely lost.

import string

def main():

    user = raw_input("Enter the message you want coded: ")

    user = string.upper(user)


    for i in user:
        if i != ' ':
            i = ord(i)
            i += 13
            if i > ord('Z'):
                i-= 26
            i = chr(i)
            print i,

main()

Recommended Answers

All 11 Replies

You may want to store your result in a string, so you can work with it ...

import string

def main():
    user = raw_input("Enter the message you want coded: ")
    user = string.upper(user)

    encoded = ""
    for i in user:
        if i != ' ':
            i = ord(i)
            i += 13
            if i > ord('Z'):
                i-= 26
            i = chr(i)
            print i,     # test
            encoded += i
    print
    print encoded  # QVAAREVFNGRVTUG (what did I enter?)

main()

To assume that the letter E will have a 12% relative frequency is a little naive. It is better to assume that the relative frequency order in the English language is:
'ETAOIN SHRDLU'

so encoded = " " will result in what, the problem is I dont completely understand everything in this language and my teacher just expects us to know everything which i do not (i've talked to alot of people in the lecture and they feel the same way i do, but this doesnt matter, anyway).

#
i-= 26 ---so this is taking whatever i is and saying subtract 26 from the value and then assign i to that number? right?
#
i = chr(i) ---converts i from the ord num back to chr letter
#
print i, # test
#
encoded += i ----so this is saying encoded " " which is a space add that between each value for i???

where does this become involved at 'ETAOIN SHRDLU' and how do I incorporate this?

Thanks so much for the help, I'm more worried about learning the process than just copying things and not learning why I need to do certain things and exactly what things mean.

encoded = "" is an empty string
encoded += i adds (concatenates) the character in i to the empty string

encoded += i is a shorter form of encoded = encoded + i
Just an example ...

encoded = ""
print(encoded)  #    (nothing shown, empty)

encoded += 'A'
print(encoded)  # A

encoded += 'B'
print(encoded)  # AB

Note:
rather than print encoded I use print(encoded) since that works with Python2 and Python3, just a habit.

The next thing to do is to let Python count the character frequency of encoded (like the value in my secret message 'QVAAREVFNGRVTUG') and find the highest frequencies. Substitute those characters in order with let's say E, T, A and O. Still, I didn't make it too easy, hint R-->E, G-->T and the most frequent V-->I

how do I get python to count the frequency? The assignment is to figure out the shift then encode from the shift (if that makes sense).

First of all, let's find a better message to encode that follows the rule that E is tops in frequency ...

# use a rotation of 13 to encode an all
# upper case text message

# regular English text message
text = "Just a normal English sentence to encode"
# convert to all upper case
text = text.upper()

encoded = ""
for i in text:
    if i != ' ':
        i = ord(i)
        i += 13
        if i > ord('Z'):
            i-= 26
        i = chr(i)
        #print i,     # test
        encoded += i
print
print encoded  # WHFGNABEZNYRATYVFUFRAGRAPRGBRAPBQR

Now we got the encoded message, so let's find out which is the most frequent letter in it. You can use a pencil and paper, but Pythonians want to use Python code for such a thing ...

# count the frequency of letters in the encoded message

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

encoded = "WHFGNABEZNYRATYVFUFRAGRAPRGBRAPBQR"

# create a list of (freq_count, letter) tuples
# start with an empty list
tup_list = []
# iterate through all letters A to Z
for letter in letters:
    # check if the letter is in encoded
    if letter in encoded:
        # if True create (freq_count, letter) and append to list
        tup_list.append((encoded.count(letter), letter))

# max() gives the highest freq count tuple
print(max(tup_list))     # (6, 'R')  letter R is 6 times in encoded

This should be at your level. A little bit hairy, as we have used list, tuple and count. It does spit out the letter 'R', now you assume that 'R' really stands for 'E'. So take the letters and count the distance between E and R, 13 is the count. You can do that with letters.find('E') and so on.

To get the message back from the encoded string you simply send it through the same for loop rot 13 algorithm again, but you have to reassign some of the variable names, as text becomes encoded and encoded becomes text. Well, at least that what an NSA snoop would do.

I am completely lost. Literally I only know the very basic of things because it's all we have been taught through class she goes over the most simplest of things then just throws this assignment at us and expects us to know how to do it.

I understand the code until the point of encoded =+ i, what does it mean when encoded = " " is an empty string, as in its a string but we are going to change it from empty to encoded = encoded + i?

I ran the program at the top and noticed the shift is 12, and when i > ord('Z') i = i - 26, but why it is subtracted by 26, is it because Z is that last value of ascII we want so after adding the value we need to subtract the 26 to get back to value we intended for?

And the second code block entered is mind blowing, I have no idea what is going on, we haven't been taught tup, list or count.

I apologize for the childish explanation, but simple concepts should be explained simply.

An empty string is a string with no characters in it. Imagine we have a basket of 3 apples. If I take away 2 apples we have 1 apple in the basket. If I take away 1 more apple, then we have an empty basket. Add that apple back to the basket, and we have 1 apple in the basket.

"encoded += i" means that we will add i onto the end of encoded. So if the string encoded said "Apple " and i said "Pie", then encoded would equal "Apple Pie" after that line. Now with encoded being an empty string "" and i being the string "Apple Pies are delicious", after the line encoded += i, encoded would equal "Apple Pies are delicious".

Make sense?

As for that second code block, don't worry about it. If it's above your level, then you definitely won't be expected to use it in your first program.

...
I did this in lab with help from a TA to get started but I dont understand how to put the logic into code.

This program asked the user for a sentence and changes it into code by a shift of 13. I am completely lost.

import string

def main():

    user = raw_input("Enter the message you want coded: ")

    user = string.upper(user)


    for i in user:
        if i != ' ':
            i = ord(i)
            i += 13
            if i > ord('Z'):
                i-= 26
            i = chr(i)
            print i,

main()

The thing that sticks out in the for loop that does the rot 13 is the absolute idiotic use of i. I assumed you must have gotten it from the TA, and may be stuck with it.

To understand what is going on in the code, good variable names together with comments are important ...

# use a rotation of 13 to encode an all
# upper case text
# improved the use of variable names

# test text all upper case 
text = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

encoded = ""
for letter in text:
    if letter != ' ':
        # get the numeric ascii value of the letter
        asc = ord(letter)
        # increase the ascii value by 13 (=>rot13)
        asc += 13
        # should this ascii value exceed that of the end letter 'Z'
        # it would be a letter outside of A to Z
        # so wrap it back by 26 to the beginning of 'A' to 'Z'
        if asc > ord('Z'):
            asc -= 26
        # convert the altered ascii value to the encoded letter
        encoded_letter = chr(asc)
        #print encoded_letter,     # test
        encoded += encoded_letter
print
print encoded  # NOPQRSTUVWXYZABCDEFGHIJKLM  (check the center)

thanks for explaining it so well, I completely understand now that you changed the variables to something that makes sense. So now I need to figure out, what the shift is based on the frequency. How would I code that? Could I get all the ascII numbers converted into a list, and then have a list function that counts them by frequency then from there set the shift, and print the message.

Somehow you have to keep the letter and its frequency count together, that's why we used the (freq_count, letter) tuple in the code I gave you.

If I understand what you are saying you want to find the frequency in the regular sentence and then use that number as the number to shift by. If I'm understanding correctly, this may help or at least give you a few new tools to understand and work with.

# count the frequency of letters in the encoded message

letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

string = "BLAH BLAH BLAH"

# create a list of (freq_count, letter) tuples
# start with an empty list
tup_list = []
# iterate through all letters A to Z
for letter in letters:
    # check if the letter is in encoded
    if letter in string:
        # if True create (freq_count, letter) and append to list
        tup_list.append((string.count(letter), letter))

# max() gives the highest freq count tuple
print((tup_list))     # your list of frequencies

#now modify the original script to match the frequency with the charecter

count = 0    #use to keep track of the spot needed in the list
for letter in string:     #for every letter in the string
    if count == len(tup_list):   #if count is equal to the length of the list
        count = 0                #set it back to the beggining of the list
    for line in tup_list:        #for every item in the list
        if letter in line:       #if the letter from the string is in item of the list
            letter = ord(letter) #we understand this part
            letter += tup_list[count][0]  #instead of the set number of 13 we use the list item
                                          #[count] is the index number where it is located in the list
                                          #[0] is the index number where it is located in the tuple
                                          #so [0] is string.count from above
                                          #and [1] is the letter
            if letter > ord("Z"):    #we understand the rest of this
                letter -= 26
            letter = chr(letter)
            print(letter)
    count += 1
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.