how to allow user input both str and int [duplicate] - python-3.x

This question already has answers here:
converting individual digits to string
(4 answers)
Closed 7 years ago.
I have a function that is supposed to take a user input both string and int such as (555-GOT-FOOD) and print the correct digit for each string character. How can i get my function to take the user input (555-GOT-EATS)
Code:
def num(n):
chars = []
for char in n:
if char.isalpha():
if char.lower() in ['A', 'B', 'C']:
chars.append('2')
elif char.lower() in ['D', 'E', 'F']:
chars.append('3')
elif char.lower() in ['G', 'H', 'I']:
chars.append('4')
elif char.lower() in ['J', 'K', 'L']:
chars.append('5')
elif char.lower() in ['M', 'N', 'O']:
chars.append('6')
elif char.lower() in ['P', 'R', 'S']:
chars.append('7')
elif char.lower() in ['T', 'U', 'V']:
chars.append('8')
else:
chars.append('9')
else:
chars.append(char)
return ''.join(chars)
num (555-"got"-"food")

Either you take in a char array and convert the first three numbers in to an int afterwards. Alternatlively you can take in a string and after pull out the 3numbers and convert to an int.

If you are getting user input, you shouldn't need to worry about the 5's being ints because they aren't ints! Python gets all user input as a string. So they are numbers, yes, but they are of the type string, not int. Think of them as just the symbols representing numbers.
If you modify the end of your code like this, it should work.
elif char.lower() in ['T', 'U', 'V']:
chars.append('8')
elif char.lower() in ['X', 'Y', 'Z']:
chars.append('9')
else:
chars.append(char)
return ''.join(chars)
You will also want to use
n.replace("-", "")
to get rid of all "-", giving you "555GOTFOOD" instead of "555-GOT-FOOD".
Also, I'm not sure if it will work as is, or if you need to change char.lower() to char.upper() since your lists are all upper case letters.

Related

How do I iterate through a list by the indices of a different list?

I want sub_main to be made from the 'sub' list as:
sub_main = ['c','d','e','f','j','k','l','m','n','o','p'...
I have tried:
for i in sub:
for j in main:
if j == i[0]:
while j != i[1]:
sub_main.append(j)
but it is an infinite loop for some reason
import string
sub_main = []
main = list(string.ascii_lowercase)
sub = [['c','f'],['j','p'],['r','t']]
import string
sub_main = []
main = list(string.ascii_lowercase)
sub = [['c', 'f'], ['j', 'p'], ['r', 't']]
indexed_main = {ch: i for i, ch in enumerate(main)}
for s in sub:
sub_main.extend(main[indexed_main[s[0]]:indexed_main[s[1]]+1])
import string
sub_main = []
main = list(string.ascii_lowercase)
sub = [['c','f'],['j','p'],['r','t']]
for chsub in sub:
amount = ord(chsub[1]) - ord(chsub[0])
remaining = amount
while remaining >= 0:
sub_main.append(main[ord(chsub[0])-ord('a') + amount - remaining])
remaining -= 1
This is how I would have done it, it uses the fact that every character has an ascii value.
Basically iterate over each sub-list in sub and get the amount of characters that are between the two in chsub.
main[ord(chsub[0])-ord('a') + amount - remaining] - This first finds the index of the character it should be on (c - a, for example, which is 2 which means it begins from main[2]).
Then inside that calculation I also check the difference between amount and remaining to see which character it needs to get past the initial character.
Result:
['c', 'd', 'e', 'f', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't']
The reason for your infinite loop has been given in a comment to your question, you never change j in the while, but 3 loops is too much for this issue.

Any reason not to convert string to list this way?

I'm using PyCharm on Windows (and very new to Python)
I'm a 'what happens when I try this?' person and so I tried:
alist = []
alist += 'wowser'
which returns ['w', 'o', 'w', 's', 'e', 'r']
Is there any reason not to convert a string to a list of individual characters like this? I know I could use For loop method OR I could .append or +concatenate (both seem to be too tedious!!), but I can't find anything that mentions using += to do this. So, since I'm new, I figure I should ask why not to do it this way before I develop a bad habit that will get me into trouble in the future.
Thanks for your help!
I think this would help: Why does += behave unexpectedly on lists?
About the question "Is there any reason not to convert a string to a list of individual characters like this". I think it depends on your purpose. It will be quite convenient if you need to split the letters. If you don't want to split the letters, just don't use it.
String is a type of array so it behaves like an array as lists do.
>>> # This way you would do it with a list:
>>> list('wowser')
['w', 'o', 'w', 's', 'e', 'r']
>>> lst=list('wowser')
>>> a='w'
>>> a is lst[0]
True
>>> # The String Version:
>>> strng = 'wowser'
>>> a is strng[0]
True
>>> # Iterate over the string like doing it with lists:
>>> [print(char) for char in 'wowser']
w
o
w
s
e
r
>>> [print(char) for char in ['w', 'o', 'w', 's', 'e', 'r']]
w
o
w
s
e
r
w3schools.com
docs.python.org

Python 3 - Dynamic Expression Evaluation

I am trying to figure out the syntax for evaluation an expression in Python that involves substituting a variable.
The code needs to go through a list of options, insert string input within the "{:(insert list item here)}"
Example Code (Python 3.x):
n = 11
print("my number is {:d}".format(n))
formatList = ['e', 'b', 'o', 'd', 'x', 'f', 's']
for atype in formatList:
# Failed Attempts:
# print("my number is {:eval(atype)}".format(n))
# print("my number is {:" + eval(atype) + "}".format(n))
# print(eval("my number is {:" + atype + "}").format(n))
# print(eval(' "my number is {:" + atype + "}".format(n)) '))
The output should resemble the number 11, in all the possible formats given by the list.
Thank you for everyones help!
You can achieve this by splitting in two passages:
n = 11
print("my number is {:d}".format(n))
formatList = ['e', 'b', 'o', 'd', 'x', 'f', 's']
for atype in formatList:
str_template = 'my number is {:' + atype + '}'
print(str_template.format(n))
If you really want one line, you can use this answer, to have a literal curly bracket in the string, by using double curly brackets '{{':
for atype in formatList:
print('my number is {{:{}}}'.format(atype).format(n))

Is there any way to force ipython to interpret utf-8 symbols?

I'm using ipython notebook.
What I want to do is search a literal string for any spanish accented letters (ñ,á,é,í,ó,ú,Ñ,Á,É,Í,Ó,Ú) and change them to their closest representation in the english alphabet.
I decided to write down a simple function and give it a go:
def remove_accent(n):
listn = list(n)
for i in range(len(listn)):
if listn[i] == 'ó':
listn[i] =o
return listn
Seemed simple right simply compare if the accented character is there and change it to its closest representation so i went ahead and tested it getting the following output:
in []: remove_accent('whatever !## ó')
out[]: ['w',
'h',
'a',
't',
'e',
'v',
'e',
'r',
' ',
'!',
'#',
'#',
' ',
'\xc3',
'\xb3']
I've tried to change the default encoding from ASCII (I presume since i'm getting two positions for te accented character instead of one '\xc3','\xb3') to UTF-8 but this didnt work. what i would like to get is:
in []: remove_accent('whatever !## ó')
out[]: ['w',
'h',
'a',
't',
'e',
'v',
'e',
'r',
' ',
'!',
'#',
'#',
' ',
'o']
PD: this wouldn't be so bad if the accented character yielded just one position instead of two I would just require to change the if condition but I haven't find a way to do that either.
Your problem is that you are getting two characters for the 'ó' character instead of one. Therefore, try to change it to unicode first so that every character has the same length as follows:
def remove_accent(n):
n_unicode=unicode(n,"UTF-8")
listn = list(n_unicode)
for i in range(len(listn)):
if listn[i] == u'ó':
listn[i] = 'o'.encode('utf-8')
else:
listn[i]=listn[i].encode('utf-8')
return listn

Musical note string (C#-4, F-3, etc.) to MIDI note value, in Python

The code in my answer below converts musical notes in strings, such as C#-4 or F-3, to their corresponding MIDI note values.
I am posting this because I am tired of trying to dig it up online every time I need it. I'm sure I'm not the only one who can find a use for it. I just wrote this up — it is tested and correct. It's in Python, but I feel that it pretty close to universally understandable.
#Input is string in the form C#-4, Db-4, or F-3. If your implementation doesn't use the hyphen,
#just replace the line :
# letter = midstr.split('-')[0].upper()
#with:
# letter = midstr[:-1]
def MidiStringToInt(midstr):
Notes = [["C"],["C#","Db"],["D"],["D#","Eb"],["E"],["F"],["F#","Gb"],["G"],["G#","Ab"],["A"],["A#","Bb"],["B"]]
answer = 0
i = 0
#Note
letter = midstr.split('-')[0].upper()
for note in Notes:
for form in note:
if letter.upper() == form:
answer = i
break;
i += 1
#Octave
answer += (int(midstr[-1]))*12
return answer
NOTES_FLAT = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']
NOTES_SHARP = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
def NoteToMidi(KeyOctave):
# KeyOctave is formatted like 'C#3'
key = KeyOctave[:-1] # eg C, Db
octave = KeyOctave[-1] # eg 3, 4
answer = -1
try:
if 'b' in key:
pos = NOTES_FLAT.index(key)
else:
pos = NOTES_SHARP.index(key)
except:
print('The key is not valid', key)
return answer
answer += pos + 12 * (int(octave) + 1) + 1
return answer

Resources