How to test if an input has only specific characters - python-3.x

Im trying to make a script that tests id there are characters in the input that are not A, T, C, G and if there are than the input is false.
I dont have any clue how to start. I would love if someone could help.
Thanks!

The following function can check a string to find out if it only contains the characters A, T, C, and G.
def check_string(code):
return all(character in {'A', 'T', 'C', 'G'} for character in code)

Expressed using sets:
The list function takes a string and returns a list of its characters. The set function takes a list and returns a set (with duplicates discarded).
>>> def check_string(code):
... return set(list('ACTG')).issuperset(set(list(code)))
...
>>> check_string('IT')
False
>>> check_string('ACTG')
True
>>> check_string('')
True
>>> check_string('ACT')
True

output = True
nucl_dict = {'A':'T', 'T':'A', 'C':'G', 'G':'C'}
n = input("Insert DNA seqence: ").upper()
for c in n:
if(c in ("A", "T", "C", "G")):
output = False
if(output == False):
print('Issue detected please try again')
print(n)
print(''.join(nucl_dict.get(nucl, nucl) for nucl in n))
else:
print("All good")

Related

Check if element is occurring very first time in python list

I have a list with values occurring multiple times. I want to loop over the list and check if value is occurring very first time.
For eg: Let's say I have a one list like ,
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
Now, at every first occurrence of element, I want to perform some set of tasks.
How to get the first occurrence of element?
Thanks in Advance!!
Use a set to check if you had processed that item already:
visited = set()
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
for e in L:
if e not in visited:
visited.add(e)
# process first time tasks
else:
# process not first time tasks
You can use unique_everseen from itertools recipes.
This function returns a generator which yield only the first occurence of an element.
Code
from itertools import filterfalse
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
Example
lst = ['a', 'a', 'b', 'c', 'b']
for x in unique_everseen(lst):
print(x) # Do something with the element
Output
a
b
c
The function unique_everseen also allows to pass a key for comparison of elements. This is useful in many cases, by example if you also need to know the position of each first occurence.
Example
lst = ['a', 'a', 'b', 'c', 'b']
for i, x in unique_everseen(enumerate(lst), key=lambda x: x[1]):
print(i, x)
Output
0 a
2 b
3 c
Why not using that?
L = ['a','a','a','b','b','b','b','b','e','e','e'.......]
for idxL, L_idx in enumerate(L):
if (L.index(L_idx) == idxL):
print("This is first occurence")
For very long lists, it is less efficient than building a set prior to the loop, but seems more direct to write.

Reordering character triplets in Python

I've been trying to solve this homework problem for days, but can't seem to fix it. I started my study halfway through the first semester, so I can't ask the teacher yet and I hope you guys can help me. It's not for grades, I just want to know how.
I need to write a program that reads a string and converts the triplets abc into bca. Per group of three you need to do this. For examplekatzonbecomesatkonz`.
The closest I've gotten is this:
string=(input("Give a string: "))
for i in range(0, len(string)-2):
a = string[i]
b = string[i + 1]
c = string[i + 2]
new_string= b, c, a
i+=3
print(new_string)
The output is:
('a', 't', 'k')
('t', 'z', 'a')
('z', 'o', 't')
('o', 'n', 'z')
The code below converts for example "abc" to "bca". It works for any string containing triplets. Now, if input is "abcd", it is converted to "bcad". If you input "katzon", it is converted to "atkonz". This is what I understood from your question.
stringX = input()
# create list of words in the string
listX = stringX.split(" ")
listY = []
# create list of triplets and non-triplets
for word in listX:
listY += [[word[i:i+3] for i in range(0, len(word), 3)]]
# convert triplets, for example: "abc" -> "bca"
for listZ in listY:
for item in listZ:
if len(item)==3:
listZ[listZ.index(item)] = listZ[listZ.index(item)][1:] + listZ[listZ.index(item)][0]
listY[listY.index(listZ)] = "".join(listZ)
# create final string
stringY = " ".join(listY)
print(stringY)

Python string duplicates

I have a list
a=['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
I am trying to find largest element in the list with no duplicates.
For example script should return "country" as it doesn't have any duplicates.
Please help
You could also use collections.Counter for this:
from collections import Counter
a = ['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
a = set(a)
no_dups = []
for word in a:
counts = Counter(word)
if all(v == 1 for v in counts.values()):
no_dups.append(word)
print(max(no_dups, key = len))
Which follows this procedure:
Converts a to a set, since we only need to look at a word once, just in case a contains duplicates.
Creates a Counter() object of each word.
Only appends words that have a count of 1 for each letter, using all().
Get longest word from this resultant list, using max().
Note: This does not handle ties, you may need to do further work to handle this.
def has_dup(x):
unique = set(x) # pick unique letters
return any([x.count(e) != 1 for e in unique]) # find if any letter appear more than once
def main():
a = ['apple', 'elephant', 'ball', 'country', 'lotus', 'potato']
a = [e for e in a if not has_dup(e)] # filter out duplicates
chosen = max(a, key=len) # choose with max length
print(chosen)
if __name__ == '__main__':
main()

Which character comes first?

So the input is word and I want to know if a or b comes first.
I can use a_index = word.find('a') and compare this to b_index = word.find('b') and if a is first, a is first is returned. But if b isn't in word, .find() will return -1, so simply comparing b_index < a_index would return b is first. This could be accomplished by adding more if-statements, but is there a cleaner way?
function description:
input: word, [list of characters]
output: the character in the list that appears first in the word
Example: first_instance("butterfly", ['a', 'u', 'e'] returns u
You can create a function that takes word and a list of chars - convert those chars into a set for fast lookup and looping over word take the first letter found, eg:
# Chars can be any iterable whose elements are characters
def first_of(word, chars):
# Remove duplicates and get O(1) lookup time
lookup = set(chars)
# Use optional default argument to next to return `None` if no matches found
return next((ch for ch in word if ch in lookup), None)
Example:
>>> first_of('bob', 'a')
>>> first_of('bob', 'b')
'b'
>>> first_of('abob', 'ab')
'a'
>>> first_of("butterfly", ['a', 'u', 'e'])
'u'
This way you're only ever iterating over word once and short-circuit on the first letter found instead of running multiple finds, storing the results and then computing the lowest index.
Make a list without the missing chars and then sort it by positions.
def first_found(word, chars):
places = [x for x in ((word.find(c), c) for c in chars) if x[0] != -1]
if not places:
# no char was found
return None
else:
return min(places)[1]
In any case you need to check the type of the input:
if isinstance(your_input, str):
a_index = your_input.find('a')
b_index = your_input.find('b')
# Compare the a and b indexes
elif isinstance(your_input, list):
a_index = your_input.index('a')
b_index = your_input.index('b')
# Compare the a and b indexes
else:
# Do something else
EDIT:
def first_instance(word, lst):
indexes = {}
for c in lst:
if c not in indexes:
indexes[c] = word.find(c)
else:
pass
return min(indexes, key=indexes.get)
It will return the character from list lst which comes first in the word.
If you need to return the index of this letter then replace the return statement with this:
return min_value = indexes[min(indexes, key=indexes.get)]

issue with equating dictionaries and global issue

Trying to figure best way to union of two dictionaries. Here is the code that I have. Counter is one of the options that I found.
def __add__(self,right):
mergedbag = Bag()
mergedbag.bag_value = copy.copy(self.bag_value)
for item in right.bag_value.keys():
mergedbag.bag_value[item] += right.bag_value[item]
return mergedbag
To test if two dictionaries have the same contents, simply use an equality test:
self.bag_items == bag_equal.bag_items
Python does this comparison test efficiently; keys and values have to match exactly and difference in length means the dictionaries are not equal:
>>> a = {'a': 'b'}
>>> b = {'a': 'b'}
>>> a == b
True
>>> b['b'] = 'c'
>>> a == b
False
>>> del b['b']
>>> b['a'] = 'c'
>>> a == b
False
>>> b['a'] = 'b'
>>> a == b
True
Note that rather than raise a TypeError, __eq__ should return the NotImplemented sentinel object to signal that equality testing is not supported:
def __eq__(self, other):
if not isinstance(other, Bag):
return NotImplemented
return self.bag_items == other.bag_items
As a side-note, the in membership operator already returns either True or False, there is no need to use a conditional expression in __contains__; the following is enough:
def __contains__(self, include):
return include in self.bag_items
Your code never actually does anything with the items passed in however, nor are you ever counting the items. Your count() method should just look up the element in self.bag_items and return the count once you properly track counts.

Resources