make python utilize any symbol's input - python

I'm making a code that can translate numbers to piano keys,
***Sorry for the confusion, I meant the ideal output for "3.14159ABC265" is "E1 _ C1 F1 C1 G1 D2 _ _ _ D1 A2 G1", however python will give an error when the input has #, \, or something
the codes:
numbers = str(input('This code will convert numbers to piano keys, \nnow input any numbers here'))
keys = str('')
while len(numbers) == str(0):
G = str('_ ')
if numbers[0] == str(0): G='B1 '
if numbers[0] == str(1): G='C1 '
if numbers[0] == str(2): G='D1 '
if numbers[0] == str(3): G='E1 '
if numbers[0] == str(4): G='F1 '
if numbers[0] == str(5): G='G1 '
if numbers[0] == str(6): G='A2 '
if numbers[0] == str(7): G='B2 '
if numbers[0] == str(8): G='C2 '
if numbers[0] == str(9): G='D2 '
keys += G
numbers = numbers[1:len(numbers)]
print(keys)
This code is already working, but not when the input has \, # or something. I've searched for a while but didn't found an answer.
By the way I think python should have an option to disable the differences between numbers and strings in a short code like this XD

You can use ord to turn any characters into numbers (based on ASCII values), then use division and remainder to map the numbers into piano key numbers and scales, and then use chr to turn key numbers into alphabets. Here's a one-line example:
>>> ' '.join(map(lambda c: chr(ord('A') + int((ord(c) - ord(' ')) % 7)) + str(int((ord(c) - ord(' ')) / 7)), input()))
3.14159ABC265
'F2 A2 D2 G2 D2 A3 E3 F4 G4 A5 E2 B3 A3'
>>>

Related

How to get Count of discrepancy values from two given string?

I have two Strings Paula and Pole. If we check Paula with Pole then we will get three discrepancy a,u,a is present in Paula but not present in Pole so it should return a value 3.
Input:
enter string1: Paula
enter string2: Pole
Expected Output:
3
String 1 is always correct here for a row of names.
I have tried something like below so far
import itertools
def compare(string1, string2, no_match_c=' ', match_c='|'):
if len(string2) < len(string1):
string1, string2 = string2, string1
result = ''
n_diff = 0
for c1, c2 in itertools.izip(string1, string2):
if c1 == c2:
result += match_c
else:
result += no_match_c
n_diff += 1
delta = len(string2) - len(string1)
result += delta * no_match_c
n_diff += delta
return (result, n_diff)
def main():
string1 = 'paula'
string2 = 'pole'
result, n_diff = compare(string1, string2, no_match_c='_')
print(n_diff)
main()
Answer should be in a function
Example of other string
string1 = Michelle
string2 = Michele
Output : 1
This is a simple approach to do what you want, assuming you always want to find the number of chars in string 1 not in string 2.
def compare(str1, str2):
#Return count of chars in str1 not in str2
s1 = set([x for x in str1])
s2 = set([x for x in str2])
ms = s1 ^ s2 & s1 #Finds the chars in string 1 not in str2
rslt = 0
for v in ms:
rslt += str1.count(v)
return rslt
You may try Counter, it can use to count the number of each character in both strings and support subtraction between counts.
from collections import Counter
def diff(s1, s2):
c1 = Counter(s1)
c2 = Counter(s2)
return sum((c1 - c2).values())
print(diff("Paula", "Pole")) # Output: 3
print(diff("Pole", "Paula")) # Output: 2
print(diff("Michelle", "Michele")) # Output: 1
print(diff("Michele", "Michelle")) # Output: 0
You can try that, using a list of zeors in the size of 256 (number of ASCII characters) which represents a counter for all characters.
def compare(string1, string2):
chars_counter = [0]*256
for c1 in string1:
chars_counter[ord(c1)] += 1
for c2 in string2:
if chars_counter[ord(c2)] != 0:
chars_counter[ord(c2)] -= 1
return sum(chars_counter)

Binary addition program in python

I am writing a binary addition program but am unsure as to why when the inputs start with a zero the output is incorect.The output is also incorrect when the program has to add zeros to the start of one of the inputs to make them the same length.
a = input('Enter first binary number\t')
b = input('Enter second binary number\t')
carry = 0
answer = ""
length = (max(len(a),len(b))) - min(len(a),len(b))
if b > a:
a = length * '0' + a
elif a > b:
b = length * '0' + b
print(a)
print(b)
for i in range(len(a)-1, -1, -1):
x = carry
if a[i] == '1': x += 1
else: x = 0
if b[i] == '1': x += 1
else: x = 0
if x % 2 == 1: answer = '1' + answer
else: answer = '0' + answer
if x < 2: carry = 0
else: carry = 1
if carry == 1: answer = '1' + answer
print(answer)
What an excellent opportunity to explore some Boolean Logic.
Adding binary like this can be done with two "half adders" and an "or"
First of all the "Half Adder" which is a XOR to give you a summed output and an AND to give you a carry.
[EDIT as per comments: python does have an XOR implemented as ^ but not as a "word" like and not or. I am leaving the answer as is, due to the fact it is explaining the Boolean logic behind a binary add]
As python doesn't come with a XOR, we will have to code one.
XOR itself is two AND's (with reversed inputs) and an OR, as demonstrated by this:
This would result is a simple function, like this:
def xor(bit_a, bit_b):
A1 = bit_a and (not bit_b)
A2 = (not bit_a) and bit_b
return int(A1 or A2)
Others may want to write this as follows:
def xor(bit_a, bit_b):
return int(bit_a != bit_b)
which is very valid, but I am using the Boolean example here.
Then we code the "Half Adder" which has 2 inputs (bit_a, bit_b) and gives two outputs the XOR for sum and the AND for carry:
def half_adder(bit_a, bit_b):
return (xor(bit_a, bit_b), bit_a and bit_b)
so two "Half Adders" and an "OR" will make a "Full Adder" like this:
As you can see, it will have 3 inputs (bit_a, bit_b, carry) and two outputs (sum and carry). This will look like this in python:
def full_adder(bit_a, bit_b, carry=0):
sum1, carry1 = half_adder(bit_a, bit_b)
sum2, carry2 = half_adder(sum1, carry)
return (sum2, carry1 or carry2)
If you like to look at the Full Adder as one logic diagram, it would look like this:
Then we need to call this full adder, starting at the Least Significant Bit (LSB), with 0 as carry, and work our way to the Most Significant Bit (MSB) where we carry the carry as input to the next step, as indicated here for 4 bits:
This will result is something like this:
def binary_string_adder(bits_a, bits_b):
carry = 0
result = ''
for i in range(len(bits_a)-1 , -1, -1):
summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
result += str(summ)
result += str(carry)
return result[::-1]
As you see we need to reverse the result string, as we built it up "the wrong way".
Putting it all together as full working code:
# boolean binary string adder
def rjust_lenght(s1, s2, fill='0'):
l1, l2 = len(s1), len(s2)
if l1 > l2:
s2 = s2.rjust(l1, fill)
elif l2 > l1:
s1 = s1.rjust(l2, fill)
return (s1, s2)
def get_input():
bits_a = input('input your first binary string ')
bits_b = input('input your second binary string ')
return rjust_lenght(bits_a, bits_b)
def xor(bit_a, bit_b):
A1 = bit_a and (not bit_b)
A2 = (not bit_a) and bit_b
return int(A1 or A2)
def half_adder(bit_a, bit_b):
return (xor(bit_a, bit_b), bit_a and bit_b)
def full_adder(bit_a, bit_b, carry=0):
sum1, carry1 = half_adder(bit_a, bit_b)
sum2, carry2 = half_adder(sum1, carry)
return (sum2, carry1 or carry2)
def binary_string_adder(bits_a, bits_b):
carry = 0
result = ''
for i in range(len(bits_a)-1 , -1, -1):
summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
result += str(summ)
result += str(carry)
return result[::-1]
def main():
bits_a, bits_b = get_input()
print('1st string of bits is : {}, ({})'.format(bits_a, int(bits_a, 2)))
print('2nd string of bits is : {}, ({})'.format(bits_b, int(bits_b, 2)))
result = binary_string_adder(bits_a, bits_b)
print('summarized is : {}, ({})'.format(result, int(result, 2)))
if __name__ == '__main__':
main()
two internet sources used for the pictures:
https://www.electronics-tutorials.ws/combination/comb_7.html
https://www.allaboutcircuits.com/textbook/digital/chpt-7/the-exclusive-or-function-xor/
For fun, you can do this in three lines, of which two is actually getting the input:
bits_a = input('input your first binary string ')
bits_b = input('input your second binary string ')
print('{0:b}'.format(int(bits_a, 2) + int(bits_b, 2)))
And in your own code, you are throwing away a carry if on second/subsequent iteration one of the bits are 0, then you set x = 0 which contains the carry of the previous itteration.
this is how i managed to complete this, hope you find this useful.
#Binary multiplication program.
def binaryAddition(bin0, bin1):
c = 0
answer = ''
if len(bin0) > len(bin1):
bin1 = (len(bin0) - len(bin1))*"0" + bin1
elif len(bin1) > len(bin0):
bin0 = (len(bin1) - len(bin0))*"0" + bin0
#Goes through the binary strings and tells the computer what the anser should be.
for i in range(len(bin0)-1,-1,-1):
j = bin0[i]
k = bin1[i]
j, k = int(j), int(k)
if k + j + c == 0:
c = 0
answer = '0' + answer
elif k + j + c == 1:
c = 0
answer = '1' + answer
elif k + j + c == 2:
c = 1
answer = '0' + answer
elif k + j + c == 3:
c = 1
answer = '1' + answer
else:
print("There is something wrong. Make sure all the numbers are a '1' or a '0'. Try again.") #One of the numbers is not a 1 or a 0.
main()
return answer
def binaryMultiplication(bin0,bin1):
answer = '0'*8
if len(bin0) > len(bin1):
bin1 = (len(bin0) - len(bin1))*"0" + bin1
elif len(bin1) > len(bin0):
bin0 = (len(bin1) - len(bin0))*"0" + bin0
for i in range(len(bin0)-1,-1,-1):
if bin1[i] == '0':
num = '0'*len(answer)
elif bin1[i] == '1':
num = bin0 + '0'*((len(bin0)-1)-i)
answer = binaryAddition(num, answer)
print(answer)
def main():
try:
bin0, bin1 = input("Input both binary inputs separated by a space.\n").split(" ")
except:
print("Something went wrong. Perhaps there was not a space between you numbers.")
main()
binaryMultiplication(bin0,bin1)
choice = input("Do you want to go again?y/n\n").upper()
if choice == 'Y':
main()
else: input()
main()
The following adds integers i1 and i2 using bitwise logical operators (i1 and i2 are overwritten). It computes the bitwise sum by i1 xor i2 and the carry bit by (i1 & i2)<<1. It iterates until the shift register is empty. In general this will be a lot faster than bit-by-bit
while i2: # check shift register != 0
i1, i2 = i1^i2, (i1&i2) << 1 # update registers

Rosalind Consensus and Profile

I am trying to solve the question from here http://rosalind.info/problems/cons/
My script fills the counter lists and outputs a consensus string of equal length. I don't think there are math or index errors going on and have run into a wall. My code:
with open('C:/users/steph/downloads/rosalind_cons (3).txt') as f:
seqs = f.read().splitlines()
#remove all objects that are not sequences of interest
for s in seqs:
if s[0] == '>':
seqs.remove(s)
n = range(len(seqs[0])+1)
#lists to store counts for each nucleotide
A, C, G, T = [0 for i in n], [0 for i in n], [0 for i in n], [0 for i in n]
#see what nucleotide is at each index and augment the
#same index of the respective list
def counter(Q):
for q in Q:
for k in range(len(q)):
if q[k] == 'A':
A[k] += 1
elif q[k] == 'C':
C[k] += 1
elif q[k] == 'G':
G[k] += 1
elif q[k] == 'T':
T[k] += 1
counter(seqs)
#find the max of all the counter lists at every index
#and add the respective nucleotide to the consensus sequence
def consensus(a,t,c,g):
consensus = ''
for k in range(len(a)):
if (a[k] > t[k]) and (a[k]>c[k]) and (a[k]>g[k]):
consensus = consensus+"A"
elif (t[k] > a[k]) and (t[k]>c[k]) and (t[k]>g[k]):
consensus = consensus+ 'T'
elif (c[k] > t[k]) and (c[k]>a[k]) and (c[k]>g[k]):
consensus = consensus+ 'C'
elif (g[k] > t[k]) and (g[k]>c[k]) and (g[k]>a[k]):
consensus = consensus+ 'G'
#ensure a nucleotide is added to consensus sequence
#when more than one index has the max value
else:
if max(a[k],c[k],t[k],g[k]) in a:
consensus = consensus + 'A'
elif max(a[k],c[k],t[k],g[k]) in c:
consensus = consensus + 'C'
elif max(a[k],c[k],t[k],g[k]) in t:
consensus = consensus + 'T'
elif max(a[k],c[k],t[k],g[k]) in g:
consensus = consensus + 'G'
print(consensus)
#debugging, ignore this --> print('len(consensus)',len(consensus))
consensus(A,T,C,G)
#debugging, ignore this --> print('len(A)',len(A))
print('A: ',*A, sep=' ')
print('C: ',*C, sep=' ')
print('G: ',*G, sep=' ')
print('T: ',*T, sep=' ')
Thank you for your time
There is a mistake in the following line:
n = range(len(seqs[0])+1)
which results in a sequence which is too long (filled with an extra A and 4 times 0). Remove +1 and it should work.
In addition you have two spaces in your output, remove the space after : in your print statements.
If you fix those two lines, it will work for the example but will fail for sequences longer than one line (like in it the real example).
Try merging the lines with something like the snipped below:
new_seqs = list()
for s in seqs:
if s.startswith('>'):
new_seqs.append('')
else:
new_seqs[-1]+=s
seqs = new_seqs
and try it again.

count the matching characters between two inputs given by user

How do i get this python output? counting matches and mismatches
String1: aaabbbccc #aaabbbccc is user input
String2: aabbbcccc #aabbbcccc is user input
Matches: ?
MisMatches: ?
String1: aaAbbBccc #mismatches are capitalize
String2: aaBbbCccc
import itertools
s1 = 'aaabbbccc'
s2 = 'aabbbcccc'
print "Matches:", sum( c1==c2 for c1, c2 in itertools.izip(s1, s2) )
print "Mismatches:", sum( c1!=c2 for c1, c2 in itertools.izip(s1, s2) )
print "String 1:", ''.join( c1 if c1==c2 else c1.upper() for c1, c2 in itertools.izip(s1, s2) )
print "String 2:", ''.join( c2 if c1==c2 else c2.upper() for c1, c2 in itertools.izip(s1, s2) )
This produces:
Matches: 7
Mismatches: 2
String 1: aaAbbBccc
String 2: aaBbbCccc
Assuming you have gotten the string from a file or user input, what about:
import itertools
s1 = 'aaabbbccc'
s2 = 'aabbbcccc'
# This will only consider n characters, where n = min(len(s1), len(s2))
match_indices = [i for (i,(c1, c2)) in enumerate(itertools.izip(s1, s2)) if c1 == c2]
num_matches = len(match_indices)
num_misses = min(len(s1), len(s2)) - num_matches
print("Matches: %d" % num_matches)
print("Mismatches: %d" % num_misses)
print("String 1: %s" % ''.join(c if i in match_indices else c.upper() for (i,c) in enumerate(s1)))
print("String 2: %s" % ''.join(c if i in match_indices else c.upper() for (i,c) in enumerate(s2)))
Output:
Matches: 7
Mismatches: 2
String 1: aaAbbBccc
String 1: aaBbbCccc
If you wanted to count strings of uneven length (where extra characters counted as misses), you could change:
num_misses = min(len(s1), len(s2)) - num_matches
# to
num_misses = max(len(s1), len(s2)) - num_matches
You can try:
index = 0
for letter in String1:
if String1[index] != String2[index]:
mismatches +=1
index += 1
print "Matches:" + (len(String1)-mismatches)
print "Mismatches:" + mismatches
You could try the below.
>>> s1 = 'aaabbbccc'
>>> s2 = 'aabbbcccc'
>>> match = 0
>>> mismatch = 0
>>> for i,j in itertools.izip_longest(s1,s2):
if i == j:
match += 1
else:
mismatch +=1
In python3 use itertools.zip_longest instead of itertools.izip_longest.
If you want to consider a and A as a match, then change the if condition to,
if i.lower() == j.lower():
Finally get the match and mismatch count from the variables match and mismatch .
>>>s= list('aaabbbccc')
>>>s1=list('aabbbcccc')
>>>match=0
>>>mismatch=0
>>>for i in range(0,len(s)):
... if(s[i]==s1[i]):
... match+=1
... else:
... mismatch+=1
... s[i]=s[i].upper()
... s1[i]=s1[i].upper()
>>>print 'Matches:'+ str(match)
>>>print 'MisMatches:'+str(mismatch)
>>>print 'String 1:' +''.join(s)
>>>print 'String 2:' +''.join(s1)

How can I get the next string, in alphanumeric ordering, in Python?

I need a simple program that given a string, returns to me the next one in the alphanumeric ordering (or just the alphabetic ordering).
f("aaa")="aab"
f("aaZ")="aba"
And so on.
Is there a function for this in one of the modules already?
I don't think there's a built-in function to do this. The following should work:
def next_string(s):
strip_zs = s.rstrip('z')
if strip_zs:
return strip_zs[:-1] + chr(ord(strip_zs[-1]) + 1) + 'a' * (len(s) - len(strip_zs))
else:
return 'a' * (len(s) + 1)
Explanation: you find the last character which is not a z, increment it, and replace all of the characters after it with a's. If the entire string is z's, then return a string of all a's that is one longer.
Are the answers at How would you translate this from Perl to Python? sufficient? Not 100% what you're asking, but close...
A different, longer, but perhaps more readable and flexible solution:
def toval(s):
"""Converts an 'azz' string into a number"""
v = 0
for c in s.lower():
v = v * 26 + ord(c) - ord('a')
return v
def tostr(v, minlen=0):
"""Converts a number into 'azz' string"""
s = ''
while v or len(s) < minlen:
s = chr(ord('a') + v % 26) + s
v /= 26
return s
def next(s, minlen=0):
return tostr(toval(s) + 1, minlen)
s = ""
for i in range(100):
s = next(s, 5)
print s
You convert the string into a number where each letter represents a digit in base 26, increase the number by one and convert the number back into the string. This way you can do arbitrary math on values represented as strings of letters.
The ''minlen'' parameter controls how many digits the result will have (since 0 == a == aaaaa).
Sucks that python doesn't have what ruby has: String#next So here's a shitty solution to deal with alpha-numerical strings:
def next_string(s):
a1 = range(65, 91) # capital letters
a2 = range(97, 123) # letters
a3 = range(48, 58) # numbers
char = ord(s[-1])
for a in [a1, a2, a3]:
if char in a:
if char + 1 in a:
return s[:-1] + chr(char + 1)
else:
ns = next_string(s[:-1]) if s[:-1] else chr(a[0])
return ns + chr(a[0])
print next_string('abc') # abd
print next_string('123') # 124
print next_string('ABC') # ABD
# all together now
print next_string('a0') # a1
print next_string('1a') # 1b
print next_string('9A') # 9B
# with carry-over
print next_string('9') # 00
print next_string('z') # aa
print next_string('Z') # AA
# cascading carry-over
print next_string('a9') # b0
print next_string('0z') # 1a
print next_string('Z9') # AA0
print next_string('199') # 200
print next_string('azz') # baa
print next_string('Zz9') # AAa0
print next_string('$a') # $b
print next_string('$_') # None... fix it yourself
Not great. Kinda works for me.

Categories

Resources