Ok, so from my last post, you might have figured that I'm making a coder/decoder package. Anyways, say I've got a string of letters that i want to decode, such as:


AAAGGGCCC

Which should produce:

ACB

Because a=aaa c=ggg and b=ccc

Currently with my program, you have to input one three letter string at a time, then it translates it to the one letter string. How could I get python to read every three letters in the string in order, then output the result? For instance, with my program as is you have to do the following:

AAA <enter>
GGG <enter>
CCC <enter>

Then it outputs ACB.

How could i do this?

AAAGGGCCC <enter>

Then outputs ACB.

So yeah, how do I do that?

Member Avatar for Mouche

Would you mind posting your code so we can see how you did it and change it from there?

Here's a little program I made to do the same thing:

d = {'a':'a','g':'c','c':'b'} # key is actually talking about a triple 'aaa':'a'

while True:
    stuff = raw_input("string: ").lower()
    if stuff == "exit":
        break
    s = ""
    for triple in range(0,len(stuff),3):
        decoded_str = d.get(stuff[triple],"error")
        if decoded_str == "error":
            s = "error"
            break
        s += decoded_str
    if s != "error":
        print s.upper()
    else:
        print "One of the triples in your code could not be decoded."

My dictionary keys are the letters in the triple (so "AAA" has a key of "a") and then the values are the decoded values ("GGG" has a value of "c", so the dictionary item is "g":"c"). You can add stuff to the dictionary obviously and get a more advanced translator.

Is that what you were looking for?

possibly, im going to need to look into using and manipulating dictionaries, but I can't paste my code here, because of the noobish nature of the program, it's over 600 lines long, the program can decode up to 10 triplets or code up to 10 letters, because I have 26 if/elif/else statements to decode each letter, with 10 of them outputting different variables, I know its noobish, and proboably uneccasery, but that was all I know how to do =(

Member Avatar for Mouche

I have 26 if/elif/else statements to decode each letter, with 10 of them outputting different variables

Yeah, ouch. That's a lot less efficient. Look up dictionaries. ;)

Do you need me to explain mine, or do you understand?

I don;t understand yours but I'm going to have a crack at deciphering it later, after I've learned dictionaries.

Actually, if you could explain your entire code step by step, that would be appreciated, as long it's ok with you.

Member Avatar for Mouche

Okay.

Code:

d = {'a':'a','g':'c','c':'b'} # key is actually talking about a triple 'aaa':'a'

while True:
    stuff = raw_input("string: ").lower()
    if stuff == "exit":
        break
    s = ""
    for triple in range(0,len(stuff),3):
        decoded_str = d.get(stuff[triple],"error")
        if decoded_str == "error":
            s = "error"
            break
        s += decoded_str
    if s != "error":
        print s.upper()
    else:
        print "One of the triples in your code could not be decoded."

Line 1 makes d, a new dictionary. This dictionary has three keys: a, g, and c. Their values are a, c, b, respectively. They're all strings. The keys are the code letters, and the values are the decoded letters.

Line 3 is the start of the infinite loop.

Line 4 gets the code (let's take "AAAGGGCCC") and the .lower() on the end there stores the string in all lowercase. So now "stuff" contains "aaagggccc."

Lines 5 and 6 contain a check. If you type in "exit," it ends the program.

Line 7 creates an empty string 's'. This will be the result of the decoding.

The for loop on lines 8-13 decodes your message. So here was my thought process:

- The code is going to have triples of letters, so we only need to check every third letter.

So the for loop starts at 0 and goes to the len of stuff by threes. I used this number as the index of the string "stuff."

Line 9 is simple. The get() command for dictionaries retrieves the value, otherwise it sets the variable at a default value. So here, we get stuff[triple] (triple is the number assigned by the for loop) from the dictionary (we're retrieving key stuff[triple]). If stuff[triple] is not in the dictionary, it returns the default value, which I have set to "error." This is the syntax for get(): var = dictionary.get(key,default). The next several lines end the while loop if there was an error. If there is no error, the decoded value is added to the s string.

This is what happens for stuff = aaagggccc.

First time through the loop, triple = 0.

stuff[0] now equals a

Line 9 retrieves the value of key 'a' in dictionary d. That value is 'a'. (In the dictionary, 'a':'a')

No error... decoded_str ('a' right now) is added to s.

Next time around the loop... the for loop goes by 3, so now triple = 3

stuff[3] now equals g... it gets key 'g' from dictionary d. The value is 'c'.

No error... 'c' is added to s.

Now s equals "ac"

Third time around... triple = 6

stuff[6] = c

After going through the loop, the loops is done.

s = "acb"

There was never an error, so Line 15 runs and prints s in uppercase (that's what .upper() does)

So we get "ACB"

Let's say we put in "HHHAAABBB."

When it the for loop runs for the first time, triple set to 0, so stuff[0] = h. When it looks for key 'h' and finds none, "decoded_str" is set to "error". The condition on Line 10 is True, so s is set to "error" and the for loop ends with the break statement. The condition on Line 14 is false because s IS "error", so Line 17 prints.

I hope that helped. Sorry my explanation is so lengthy.

commented: Explains a lot, and apparently knows a lot about python ;) +2

The for loop on lines 8-13 decodes your message. So here was my thought process:

- The code is going to have triples of letters, so we only need to check every third letter.

One little problem, and its my fault for not telling you, the worksheet that i got this idea from, had triplets like:

AGT = g

or CTC = o

So what do I do then, just make the keys three letters and eliminate the 0, len(stuff), 3?

oh and what does the += and the != mean?

Member Avatar for Mouche

Oh. I was unaware of that. I'll have to rework the loop. Gimme a minute.

edit:
x += 1 is equivalent to x = x + 1. It's a shorter method of incrementing the variable.
!= means "does not equal." "1 != 2" is true.

edit2:

d = {'aaa':'a','ggg':'c','ccc':'b','agt':'g'}

while True:
    stuff = raw_input("string: ").lower()
    if stuff == "exit":
        break
    s = ""
    code_str = ""
    for letter in stuff:
        code_str += letter
        if len(code_str) == 3:     
            decoded_str = d.get(code_str,"error")
            if decoded_str == "error":
                s = "error"
                break
            s += decoded_str
            code_str = ""
    if s != "error":
        print s.upper()
    else:
        print "One of the triples in your code could not be decoded."

For this for loop, it goes through the letters of the string. Each time through the loop, "letter" equals the next letter in the string. The loop goes through three times, adding the letters to code_str. Once it has three letters, it decodes the triple into a character, and adds it to s (as long as there is no error). Then code_str is set to an empty string so that it can fill up with another three (which will then be decoded)...etc.

AWSOME!!! Thank you soo much, ok wow, lol I basically, (i think) was on the same track as you, but I kept getting a syntax error, heres the code n/e ways.

decoderdict = {"aaa": "a", "bbb": "b", "ccc": "c", "tcg": "d"}

while True:
    dna = raw_input("Please enter the DNA string:   ").lower()
    if dna == "exit":
        break
    output = ""
    for triplet in range(0,1,3):
        decoderdict.get(dna[triple], "error") += finals
        if finals == "error":
            break
    if finals != "error":
            print "The decoded string is:   ", finals.upper()
    else:
            print "One of the triples in your code could not be decoded."
Member Avatar for Mouche

Several syntax problems:

- You have "for triplet in range(0,1,3):" but later reference "triple", which is not a variable

- You create output as an empty string, and then never reference it. Either change that to finals or all of the instances of "finals" to "output".

Now that the program works... there are some semantic errors:

- Do you know what "range(0,1,3)" does? It starts with 0 and goes by threes from 0 to 1. So basically it is [0] (list). You want to approach this problem a little different. You don't want to do it by indexes because you are getting a string of THREE letters. I guess you could figure out how to do it by slicing, but I didn't choose to approach it that way.

Note:

The range function works like this:

Range(max) generates the list [0, 1, ... , (max-1)].

Range(min,max) generates the list [min, (min+1), ... , (max-1)].

Range(min,max,step) does the same as the previous except goes by the increment step. step cannot be 0. If step is negative, then the role of min and max are reversed.

ok gotcha, lol i read the range thing wrong, I thought that i was saying go up 3 in increments of 1 from 0 lol oops

EDIT: Well, thank you for the help, Ill let you know when the decoder is fininshed, I'm also making a coder too, I have the beta versions out, but they are very cumbersome, so yeah, ttyl and thank you soo much for you help!

Member Avatar for Mouche

Cool. It was fun to help. I'd love to see the finished products. When you finish them, post in a new post because it won't be about "scanning a string?" ...

Later.

Another way:

def group( lst, n ):
    ''' splits an iterable in parts with length n, e.g.
            group( [1,2,3,4], 2 ) ==> [ (1,2), (3,4) ]
    '''
    return zip( *[ lst[i::n] for i in range(n) ] )

aa_dict = { "AAA": "A", "GGG": "C", "CCC": "B" }

s = "AAAGGGCCC"

g = [ "".join(t) for t in group(s, 3) ]

for triplet in g:
    print aa_dict[triplet],

Regards, mawe

simplified version of an Encryptor/Decryptor i did a while ago
the parts with the pointy

l='' # a place to attach the results of <i in dictionary> to#
for i in <NameOfInput/TheThingYouWantToEncrypt>: 
    if i in <NameOfdictionary>:
        L=L+<NameOfdictionary>[<NameOfInputInsideBrackets>] 
        #attach the value of the dictionary to each letter to the empty string#
         # can be written as L+= instead of L=L+, and is another way to join/append to a list/tuple 
    else:
        pass
        # you can also insert<print i> if u want it to print a char unknown to the dictionary!#
        #the pass just tells him to ingore that letter# 
print l
#print the final output, if i would put it under the if/else idention, it would have print each step of the encryption on a different line#

Hope that helps,
Regard,
{Anonamemoose}

A no-name-moose, rather than writing template looking code with <NameOfDictionary> things, whihc are not in the syntax of python, you should better write a python function with local variables, like this

def crypt(input_sequence, dictionary):
    L = ''
    for i in input_sequence:
        if i in dictionary:
            L += dictionary[i]
    return L

The advantage is that your code is immediately usable by others !

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.