Replace method and for loops - python-3.x

Im trying to do reverse transcription of a DNA sequence by reversing a string then find its corresponding pair ( if an 'A' appears then switch with a 'T') and return a new string that is 'reverse transcribed'. The loop seems to work only partially and not go through to the elif statements. I've tried two ways and have the same problem:
def structures(seq):
revlist = seq[::-1]
for item in revlist:
if item == 'A':
return revlist.replace('A','T',1000)
elif item == 'T':
return revlist.replace('T','A',1000)
elif item == 'G':
return revlist.replace('G','C',1000)
elif item == 'C':
return revlist.replace('C','G',1000)
else:
pass
structures('ATTTGCCCTA')
# below is the second way I'm trying to code it
def structures(seq):
revlist = seq[::-1]
old = ['A','T','G','C']
new = ['T','A','C','G']
for item in revlist:
if item == 'A':
return revlist.replace(old[0],new[0])
elif item == 'T':
return revlist.replace(old[1],new[1])
elif item == 'G':
return revlist.replace(old[2],new[2])
elif item == 'C':
return revlist.replace(old[3],new[3])
else:
pass
structures('ATTTGCCCTA')

The method str.replace is meant to replace a single substring by another substring. Keep in mind that having multiple str.replace calls is inefficient since it means traversing your string many times while one would suffice.
To translate characters, you should use str.translate.
def dna_complement(dna):
translation = str.maketrans({'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C'})
return dna.translate(translation)[::-1]
print(dna_complement('AGTC'))
Output
GACT

def structures(dna):
revlist = ''
for item in dna:
if item == 'A':
revlist = 'T' + revlist
elif item == 'C':
revlist = 'G' + revlist
elif item == 'G':
revlist = 'C' + revlist
elif item == 'T':
revlist = 'A' + revlist
return revlist
This code seems to work good. Instead of reversing the list, I researched another way of adding the information in reverse order which equates to the same thing. Credit to github

Related

Is there a way i can avoid getting "None" when i print out my function?

I am trying to calculate the avarage grade of a subject. but when i print the function i get printed None.
And i do not know how to fix it.
Ive tried returning the value instead then printing the function, but it wont work.
def karakterKonversjon(bokstav):
if bokstav == 'A':
return 6
if bokstav == 'B':
return 5
if bokstav == 'C':
return 4
if bokstav == 'D':
return 3
if bokstav == 'E':
return 2
if bokstav == 'F':
return 1
def konversjonTilBokstav(tall):
if tall == 6:
return 'A'
if tall == 5:
return 'B'
if tall == 4:
return 'C'
if tall == 3:
return 'D'
if tall == 2:
return 'E'
if tall == 1:
return 'F'
def beregnSnitt():
nummer_karakter = 0
suM = 0
for i in emner:
if emner[i] != "":
tall_karakter = eksamen.karakterKonversjon(emner[i])
suM += (tall_karakter * studiepoeng)
suM /= totalPoeng
rundetSvar = eksamen.normal_round(suM)
eksamen.konversjonTilBokstav(rundetSvar)
print(rundetSvar)
def normal_round(suM):
if (float (suM) < 5):
print(math.floor(suM))
else:
print(math.ceil(suM))
THe result i am expecting is
4
C
But i am getting
4
None
I made a few modifications to your code:
(I assume you are importing math in the eksamen file)
def karakterKonversjon(bokstav): # make this function more efficient
atof = ['A','B','C','D','E','F']
for i in range(len(atof)):
if bokstav.upper() == atof[i]:
return len(atof) - i
def konversjonTilBokstav(tall): # make this function more efficient
atof = ['A','B','C','D','E','F']
for i in range(1,7):
if tall == i:
return atof[len(atof)-i]
def beregnSnitt():
nummer_karakter = 0
suM = 0
for i in range(len(emner)): # if enmer == "enmer"(for example) you cannot reference enmer['e'] without raising an error
if emner[i] != "":
tall_karakter = eksamen.karakterKonversjon(emner[i])
suM += (tall_karakter * studiepoeng)
suM /= totalPoeng
rundetSvar = eksamen.normal_round(suM)
eksamen.konversjonTilBokstav(rundetSvar)
print(rundetSvar)
def normal_round(suM):
if (float (suM) < 5):
print(math.floor(suM))
else:
print(math.ceil(suM))
apart from the differences i made, your code should work well however i cannot test without knowing what enmer is (i assume it's a string) or what studiepoeng is.
the function konversjonTilBokstav did work fine for me. But what I have included in the code snippet should be less spaghetti code

Homework with strings

Hello guys i got a homework where i get a string and basically i should change the letters in it then return it backward:
A --> T
T --> A
G --> C
C --> G
Here is my code :
def dnaComplement(s):
newWord = ""
for x in s:
if x == "T":
newWord.join('A')
elif x == "A":
newWord.join('T')
elif x == "C":
newWord.join('G')
elif x == "G":
newWord.join('C')
return newWord[::-1]
the input is: ACCGGGTTTT
Your effort so far has got a minor issue with it.
You are using newWord.join('X') in an attempt to add the new character to the string. This doesn't work in the way you are attempting to use it. Read again how join functions in the official documentation.
Instead, you can use the += operator to append the characters to the end of your newWord string:
newWord += 'X'
Your code then becomes:
def dnaComplement(s):
newWord = ""
for x in s:
if x == "T":
newWord += 'A'
elif x == "A":
newWord += 'T'
elif x == "C":
newWord += 'G'
elif x == "G":
newWord += 'C'
return newWord[::-1]
print(dnaComplement('ACCGGGTTTT'))
Output:
AAAACCCGGT
This is the reverse of TGGCCCAAA which is stored in newWord until you return it from dnaComplement.
newWord.join(...) doesn't change the value of network, but rather returns a new string.
So to begin with, you would need to do something like network = newWord.join(...).
That being said, here is a cleaner way IMO:
d = {'T': 'A',
'A': 'T',
'C': 'G',
'G': 'C'
}
def dnaComplement(s):
return ''.join(d[x] for x in s[::-1])

Strange behaviour when adding values to elements of a python list

I'm trying to create a game which randomly chooses a "room" layout from a set and then puts it in 1 of 4 positions on the screen. My code to achieve this is:
room_spawns = [[randint(0, 5)] for a in range(4)]
for i in range(0, 4):
these_segments = []
these_shapes = []
if i == 1:
modifier = [800, 0]
elif i == 2:
modifier = [0, 448]
elif i == 3:
modifier = [800, 448]
else:
modifier = [0, 0]
if room_spawns[i] == 0:
these_segments = room_1_segments
these_shapes = room_1_shapes
elif room_spawns[i] == 1:
these_segments = room_2_segments
these_shapes = room_2_shapes
elif room_spawns[i] == 2:
these_segments = room_3_segments
these_shapes = room_3_shapes
elif room_spawns[i] == 3:
these_segments = room_4_segments
these_shapes = room_4_shapes
elif room_spawns[i] == 4:
these_segments = room_5_segments
these_shapes = room_5_shapes
elif room_spawns[i] == 5:
these_segments = room_6_segments
these_shapes = room_6_shapes
for z in range(0, len(these_segments)):
these_segments[z][0] += modifier[0]
these_segments[z][1] += modifier[1]
for x in range(0, len(these_shapes)):
these_shapes[x][0][0] += modifier[0]
these_shapes[x][0][1] += modifier[1]
these_shapes[x][1][0] += modifier[0]
these_shapes[x][1][1] += modifier[1]
segments.append(these_segments)
shapes.extend(these_shapes)
However, whenever a room which is the same as one chosen previously is chosen, its value is increased by the modifier value more than once and as such doesn't appear on screen. Can anybody please explain why this happens, and how it could be fixed.
Edit: After further research and debugging, for some reason, when adding the modifier value to these_segments and these_shapes, that same value is also added to the identical values already in segments and shapes, as seen here. It appears as though the values of room_2_segments themselves have been modified. Does anybody know why this is and how it could be prevented?
Notice that room_spawns is a list with length of one (it contains one boolean). Thus, room_spawns[0] will return that boolean, but for i>0 you get an IndexError.
Also, note that [randint(0, 5)] in range(4) will always return False because [randint(0,5)] is not an integer, it's a list with only one element. And since room_spawns is a list with this boolean, it will always be equal to [False].
Maybe you want room_spawns to be a list with more than one element?

Building a dictionary with lists using recursion

I was trying to build a dictionary with recursion for a school project. Right now I think I have the general structure figured out, but I can't figure out how to get the return statement to concatenate pieces of the dictionary together.
I realize this would probably be easier by constructing an empty dictionary then adding to it, but I wanted to see if there were any tricks I could use.
The output I was looking for is:
print(recur_join([1,2,3], ['a', 'b', 'c']))
>>> {1: 'a', 2 : 'b', 3 : 'c'}
I have tried .update() and something of the form dict(basket_one, **basket_two) from another answer. I may have used them wrong. I am using python 3.
Here is my code as of now:
def recur_join(list1, list2):
if len(list1) == len(list2):
if len(list1) == 1:
return {list1[0]: list2[0]}
elif len(list1) > 1:
# dict(basket_one, **basket_two)
#return dict({list1[0]: list2[0]}, **recur_join(list1[1:],
list2[1:]))
return {list1[0]: list2[0]}.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return 0
Any help would be appreciated, sorry if this was answered before.
Thanks!
I suggest you don't use recursion and use dict comprehensions instead:
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
else: return {list1[i]:list2[i] for i in range(len(list1))}
For the recursive route (warning: very ugly):
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
elif list1 == [] and list2 == []:
return {}
else:
return dict(list({list1[0]: list2[0]}.items()) + list(recur_join(list1[1:], list2[1:]).items()))
"Cleanish" recursive solution. I would personally use Primusa's dictionary
comprehension solution.
def recur_join(list1, list2):
cur = {}
if len(list1) == len(list2) and len(list1) > 0:
cur = {list1[0]: list2[0]}
if len(list1) > 1:
cur.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return cur

The last element (bitstring.BitArray) in list is incorrect after XORing python

I have snippet of code:
#!/usr/bin/python3
from bitstring import BitArray
import itertools
# Helper functions
def get_bitset_by_letter(letter, encoding):
return encoding[letter] if letter in encoding else None
def get_letter_by_bitset(bitset, encoding):
for letter, encoding_bitset in encoding.items():
if bitset == encoding_bitset:
return letter
return None
class Word():
def __init__(self, word, encoding):
self.encoding = encoding
self.as_word = ''
self.as_bits = []
if isinstance(word, str):
self.as_word = word
self._encode_to_bits()
elif all(isinstance(i, BitArray) for i in word):
self.as_bits = word
self._decode_to_word()
else:
raise('class Word: Unexpected type of word arg')
def __ixor__(self, other):
for index, bitset in enumerate(other.as_bits):
print('In XOR: %d-%s-%s' % (index, self.as_bits[index], bitset))
self.as_bits[index] ^= bitset
return self
def as_bits(self):
return self.as_bits
def as_word(self):
return self.as_word
def _encode_to_bits(self):
for letter in self.as_word:
bitset = get_bitset_by_letter(letter, self.encoding)
if bitset is None:
raise('Can not find bitset by given letter %s in encoding.' % str(letter))
else:
self.as_bits.append(bitset)
def _decode_to_word(self):
for bitset in self.as_bits:
letter = get_letter_by_bitset(bitset, self.encoding)
if letter is None:
raise('Can not find letter by given bitset %s in encoding.' % str(bitset))
else:
self.as_word += letter
def main():
encoding = {
'A': BitArray(bin='000'),
'B': BitArray(bin='001'),
'C': BitArray(bin='010'),
'D': BitArray(bin='011'),
'E': BitArray(bin='100'),
'F': BitArray(bin='101'),
'G': BitArray(bin='110'),
'H': BitArray(bin='111'),
}
print(encoding)
print()
word_1 = Word('ABCHE', encoding)
print('word_1 = %s' % word_1.as_bits)
word_2 = Word('FGDEA', encoding)
print('word_2 = %s' % word_2.as_bits)
word_1 ^= word_2
print(word_1.as_bits)
if __name__ == '__main__':
main()
Details: I use bitstring.BitArray class to represent letter as set of three bits and code words this way (some kind of hometask). Also, my code should be able to do XOR for this words.
Problem: Every last element for other.as_bits list has incorrect value, when it arrives to function. If I comment the line
#self.as_bits[index] ^= bitset
the last value of the other.as_bits is correct. What am I doing wrong?
Here is the output (python 3.5.2):
{'C': BitArray('0b010'), 'B': BitArray('0b001'), 'G': BitArray('0b110'),
'F': BitArray('0b101'), 'A': BitArray('0b000'), 'H': BitArray('0b111'),
'D': BitArray('0b011'), 'E': BitArray('0b100')}
word_1 = [BitArray('0b000'), BitArray('0b001'), BitArray('0b010'), BitArray('0b111'), BitArray('0b100')]
word_2 = [BitArray('0b101'), BitArray('0b110'), BitArray('0b011'), BitArray('0b100'), BitArray('0b000')]
In XOR: 0-0b000-0b101
In XOR: 1-0b001-0b110
In XOR: 2-0b010-0b011
In XOR: 3-0b111-0b100
In XOR: 4-0b100-0b101
[BitArray('0b101'), BitArray('0b111'), BitArray('0b001'), BitArray('0b011'), BitArray('0b001')]
From this you can see, that the last 4th element of word_2 in __ixor__ is 0b101, should be 0b000
Thank you!
I solved this using __xor__ instead of __ixor__.

Resources