How to convert an integer into a roman numeral? - python-3.x

I'm having trouble to make an integer into roman numeral for having an ouptut of integer with square brackets (I'm pretty sure it's a list, but what I want is to have an integer) and I couldn't find solution why I'm having 'None' on 'rom' value.
I'm using python3.
roman.py
#!/usr/bin/env python3
import sys
def numToRom(number):
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
num = sys.argv[1:]
rom = numToRom(num)
print(num, " is ", rom)
$ ./roman.py 2
Old output:
['2'] is None
Desired output:
2 is II

Your problem stems from the fact that you're passing a list with a character inside to your function. And that function expects an integer (if number in range(0, 9)), so you need to convert it to the right integer.
import sys
def numToRom(number):
if type(number) is list: # If you know your number might be a list with only one str(value)
number = int(number[0])
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
That will work specifically for your use case, if number is of the form ['{some digit}]. If you want to get fancier, you could use recursion to return a list with the roman number of each number in a list, like so:
def numToRom(number):
if type(number) is list:
rom = []
for value in number:
rom.append(numToRom(int(value)))
return rom
else:
rom = ["", "I", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
if number in range(0, 9):
result = rom[number]
return result
>>> num = ['2', '3', '5']
>>> numToRom(num)
['2', '3', '5'] is ['III', 'IV', 'VI']
Note that this function works even if the values inside the input list are not characters, but normal integers.
>>> num = [2, 3, 5]
>>> rom = numToRom(num)
[2, 3, 5] is ['III', 'IV', 'VI']

pip install roman
import roman
print(roman.toRoman(int(input())))

Related

Conditional converting strings to integer

Hi I want to clean up my code where I am converting a list of items to integers whenever possible in the python programming language.
example_list = ["4", "string1", "9", "string2", "10", "string3"]
So my goal (which is probably very simple) is to convert all items in the list from integers to integers and keep the actual strings as strings. The desired output of the program should be:
example_list = [4, "string1", 9, "string2", 10, "string3"]
I am looking for a nice clean method as I am sure that it is possible. I am curious about what nice methods there are.
Alternatively, you do either one:
examples = ["4", "string1", "9", "string2", "10", "string3"]
# 1. Use for-loop to check
result = []
for item in examples:
if item.isdigit():
result.append(int(item))
else:
result.append(item)
print(result)
# 2. List Comprehension
ans = [int(x) if x.isdigit() else x for x in examples]
assert result == ans # silence, because they are same
Based on your previous question, I am assuming you are using python. You can use try ... except clause:
example_list = ["4", "string1", "9", "string2", "10", "string3"]
def try_int(s):
try:
return int(s)
except ValueError:
return s
output = [try_int(s) for s in example_list] # or map(try_int, example_list)
print(*output) # [4, 'string1', 9, 'string2', 10, 'string3']

How to add elements of a string in a list without changing their types?

I have a string which includes str and int, for example string = "qA2". I want to add 'q', 'A' and 2 in a list but I don't want to change the type of elements. Is it possible?
You can use the .isdigit() method of the str class to do the following:
>>> s = "qA234"
>>> [int(x) if x.isdigit() else x for x in s]
['q', 'A', 2, 3, 4]
Note that this will fail for strings such as "x²" because ² (superscript 2) is considered a digit by the .isdigit() method for some reason. The following is safer:
>>> s = "3x²"
>>> [int(x) if "0" <= x <= "9" else x for x in s]
[3, 'x', '²']

What does int(n) for n mean?

In order to put the input into a list:
numbersList = [int(n) for n in input('Enter numbers: ').split()]
Can someone explain what does 'int(n) for n in' mean?
How do I improve this question?
The entire expression is referred to as a List Comprehension. It's a simpler, Pythonic approach to construct a for loop that iterates through a list.
https://www.pythonforbeginners.com/basics/list-comprehensions-in-python
Given your code:
numbersList = [int(n) for n in input('Enter numbers: ').split()]
Lets say you run the code provided, you get a prompt for input:
Enter numbers: 10 8 25 33
Now what happens is, Python's input() function returns a string, as documented here:
https://docs.python.org/3/library/functions.html#input
So the code has now essentially become this:
numbersList = [int(n) for n in "10 8 25 33".split()]
Now the split() function returns an array of elements from a string delimited by a given character, as strings.
https://www.pythonforbeginners.com/dictionary/python-split
So now your code becomes:
numbersList = [int(n) for n in ["10", "8", "25", "33"]]
This code is now the equivalent of:
numbersAsStringsList = ["10", "8", "25", "33"]
numberList = []
for n in numbersAsStringsList:
numberList.append(int(n))
The int(n) method converts the argument n from a string to an int and returns the int.
https://docs.python.org/3/library/functions.html#int
For example input('Enter numbers: ').split() returns an array of strings like ['1', '4', '5']
int(n) for n in will loop throug the array and turn each n into an integer while n will be the respective item of the array.
let us try to understand this list comprehension expression though a simple piece of code which means the same thing.
nums = input('Enter numbers: ') # suppose 5 1 3 6
nums = nums.split() # it turns it to ['5', '1', '3', '6']
numbersList = [] # this is list in which the expression is written
for n in nums: # this will iterate in the nums.
number = int(n) # number will be converted from '5' to 5
numbersList.append(number) # add it to the list
print(numbersList) # [5, 1, 3, 6]

Using python need to get the substrings

Q)After executing the code Need to print the values [1, 12, 123, 2, 23, 3, 13], but iam getting [1, 12, 123, 2, 23, 3]. I have missing the letter 13. can any one tell me the reason to overcome that error?
def get_all_substrings(string):
length = len(string)
list = []
for i in range(length):
for j in range(i,length):
list.append(string[i:j+1])
return list
values = get_all_substrings('123')
results = list(map(int, values))
print(results)
count = 0
for i in results:
if i > 1 :
if (i % 2) != 0:
count += 1
print(count)
Pretty straight forward issue in your nested for loops within get_all_substrings(), lets walk it!
You are iterating over each element of your string 123:
for i in range(length) # we know length to be 3, so range is 0, 1, 2
You then iterate each subsequent element from the current i:
for j in range(i,length)
Finally you append a string from position i to j+1 using the slice operator:
list.append(string[i:j+1])
But what exactly is happening? Well we can step through further!
The first value of i is 0, so lets skip the first for, go to the second:
for j in range(0, 3): # i.e. the whole string!
# you would eventually execute all of the following
list.append(string[0:0 + 1]) # '1'
list.append(string[0:1 + 1]) # '12'
list.append(string[0:2 + 1]) # '123'
# but wait...were is '13'???? (this is your hint!)
The next value of i is 1:
for j in range(1, 3):
# you would eventually execute all of the following
list.append(string[1:1 + 1]) # '2'
list.append(string[1:2 + 1]) # '23'
# notice how we are only grabbing values of position i or more?
Finally you get to i is 2:
for j in range(2, 3): # i.e. the whole string!
# you would eventually execute all of the following
list.append(string[2:2 + 1]) # '3'
I've shown you what is happening (as you've asked in your question), I leave it to you to devise your own solution. A couple notes:
You need to look at all index combinations from position i
Dont name objects by their type (i.e. dont name a list object list)
I would try something like this using itertools and powerset() recipe
from itertools import chain, combinations
def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1))
output = list(map(''.join, powerset('123')))
output.pop(0)
Here is another option, using combinations
from itertools import combinations
def get_sub_ints(raw):
return [''.join(sub) for i in range(1, len(raw) + 1) for sub in combinations(raw, i)]
if __name__ == '__main__':
print(get_sub_ints('123'))
>>> ['1', '2', '3', '12', '13', '23', '123']

converting individual digits to string

I think i'm very close but i cant seem to fix my issues. I need a function that takes a 10-digit input from user (me) and sets each letter to is numeric value.
Example: user inputs (941-019-abcd) the function should then take this and return (941-019-2223)
Anything that i should be doing differently please feel free to elaborate
Here is what i have thus far:
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
ch = digits[i]
for ch in phone_number:
if ch.isalpha():
elif ch== 'A' or 'b' or 'c':
i=2
elif ch== 'd' or 'e' or 'f':
i=3
elif ch== 'g' or 'h' or 'i':
i=4
elif ch=='j' or 'k' or 'l':
i=5
elif ch== 'm' or 'n' or 'o':
i=6
elif ch== 'p' or 'r' or 's':
i=7
elif ch=='t' or 'u' or 'v':
i=8
else:
index=9
numeric_phone= numeric_phone+ch
print (numeric_phone)
phone_number = '941-019-aBcD'
# A map of what letters to convert to what digits.
# I've added q and wxy & z.
digit_map = {
'abc': 2,
'def': 3,
'ghi': 4,
'jkl': 5,
'mno': 6,
'pqrs': 7,
'tuv': 8,
'wxyz': 9
}
# Break this out into one letter per entry in the dictionary
# to make the actual work of looking it up much simpler.
# This is a good example of taking the data a person might
# have to deal with and making it easier for a machine to
# work with it.
real_map = {}
for letters, number in digit_map.iteritems():
for letter in letters:
real_map[letter] = number
# Empty new variable.
numeric_phone = ''
# For each character try to 'get' the number from the 'real_map'
# and if that key doesn't exist, just use the value in the
# original string. This lets existing numbers and other
# characters like - and () pass though without any special
# handling.
# Note the call to `lower` that converts all our letters to
# lowercase. This will have no effect on the existing numbers
# or other speacial symbols.
for ch in phone_number.lower():
numeric_phone += str(real_map.get(ch, ch))
print(numeric_phone)
def main(phone_number):
digits = ["2", "3", "4", "5", "6", "7", "8", "9"]
numeric_phone=" "
for ch in phone_number:
if ch.isalpha():
if ord(ch) >= 97:
ch = +2 (ord(ch)-97)/3
else:
ch = +2 (ord(ch)-65)/3
numeric_phone= numeric_phone+ch
print (numeric_phone)
Use ord() to convert chars to their ASCII values and then get the right number.
You can create a formula to ascertain the correct number to add depending on the letter:
math.ceil((index(char)+1)/3)
Use a list and depending on which character it is, append a number to the list. At the end, return the list, but joined so that it is a string:
def numerify(inp):
from math import ceil as _ceil
from string import lowercase as _lowercase
chars = []
for char in inp:
if char.isalpha():
num = _ceil((_lowercase.index(char)+1)/float(3))
chars.append(str(int(num+1)))
else:
chars.append(char)
return ''.join(chars)
>>> from numerify import numerify
>>> numerify('1')
'1'
>>> numerify('941-019-abcd')
'941-019-2223'
>>>
I think it's easiest to pre-calculate the number character for each letter.
# len(keys) == 26 so that the index of a letter
# maps to its phone key
keys = ['2']*3 + ['3']*3 \
+ ['4']*3 + ['5']*3 + ['6']*3 \
+ ['7']*4 + ['8']*3 + ['9']*4
def letter_to_key(x):
if x.isalpha():
# calculate the 'index' of a letter.
# a=0, b=1, ..., z=25
index = ord(x.lower()) - ord('a')
return keys[index]
# If it's not a letter don't change it.
return x
def translate_digits(phone_num):
return ''.join(map(letter_to_key, phone_num))
print(translate_digits('941-019-abcd'))

Resources