How to have 2 outputs from 2 different functions in one line? - python

So the program should take a number and then should print this number using text.
print("Enter your number")
Number = int(input())
def number_to_text_ones(ones):
if ones == 1:
print("one")
elif ones == 2:
print("two")
elif ones == 3:
print("three")
elif ones == 4:
print("four")
elif ones == 5:
print("five")
elif ones == 6:
print("six")
elif ones == 7:
print("seven")
elif ones == 8:
print("eight")
elif ones == 9:
print("nine")
def number_to_text_tens(tens):
if tens == 2:
print("twenty ")
elif tens == 3:
print("thirty ")
elif tens == 4:
print("fourry ")
elif tens == 5:
print("fifty ")
elif tens == 6:
print("sixty ")
elif tens == 7:
print("seventy ")
elif tens == 8:
print("eighty ")
elif tens == 9:
print("ninety ")
def number_to_text_hundreds(hundreds):
if hundreds == 1:
print("one hundred")
elif hundreds == 2:
print("two hundreds")
elif hundreds == 3:
print("three hundreds")
elif hundreds == 4:
print("four hundreds")
elif hundreds == 5:
print("five hundreds")
elif hundreds == 6:
print("six hundreds")
elif hundreds == 7:
print("seven hundreds")
elif hundreds == 8:
print("eight hundreds")
elif hundreds == 9:
print("nine hundreds")
if Number == 0:
print("zero")
elif Number == 10:
print("ten")
elif Number == 11:
print("eleven")
elif Number == 12:
print("twelve")
elif Number == 13:
print("thirteen")
elif Number == 14:
print("fourteen")
elif Number == 15:
print("fifteen")
elif Number == 16:
print("sixteen")
elif Number == 17:
print("seventeen")
elif Number == 18:
print("eighteen")
elif Number == 19:
print("nineteen")
if Number < 10:
Result = Number % 10
number_to_text_ones(Result)
elif (Number >= 20 and Number < 100):
First = Number // 10
Second = (Number - (First * 10)) % 10
Result = First * 10 + Second
number_to_text_tens(First)
number_to_text_ones(Second)
elif (Number >= 100 and Number < 1000):
First = Number // 100
Second = (Number - (First * 100)) // 10
Third = (Number - (First * 100) - (Second * 10)) % 10
Result = First * 100 + Second * 10 + Third
number_to_text_hundreds(First)
number_to_text_tens(Second)
number_to_text_ones(Third)
The problem is when I input, say, 895 my output will be:
eight hundreds
ninety
five
Few questions I have:
How to make my output look better?
Is there any way to get rid of those if statements and use something more efficient? Something like switch/case

Here are the answers:
print function has an optional parameter end which specifies what will be written at the end of the string you are printing. Default is new line ('\n'). You would like to use
print('something', end=' ')
Nicer than that would be to first build a string with the name of entire number and the use print only once at the end.
A nice way to solve this is with dictionary, e.g.:
name = {1: "one hundred",
2: "two hundreds",
3: "three hundreds"}[hundreds]

I suspect there is a library for this but I'd refactor to use the following pattern
ones_text = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
def number_to_text_ones(number):
return ones_text[number - 1]

You should use dictionaries as it will reduce the lines of code (if-else conditions will no more be there just a return statement would be sufficient ) and will give your code a better look also execution time will decrease because using if-else condition the program checks each every condition specified, So dictionaries will make help u alot
And for printing your output in one line this one is a better
print(number_to_text_hundreds(First) + number_to_text_tens(Second) + number_to_text_ones(Third))
number_to_text_hundereds , number_to_text_tens and number_to_text_ones returns a value corresponding to value passed to function

I suggest you using lists of strings as follows:
print("Enter your number")
Number = int(input())
units = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
teens = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ['', '', "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
h = Number // 100
t = (Number % 100) // 10
u = (Number % 10)
result = []
if h == 0:
pass
elif h == 1:
result.append('one hundred')
else:
result.append(units[h] + ' hundreds')
if (t == 0):
if (u != 0):
result.append(units[u])
elif (h == 0):
result = ['zero']
elif (t == 1):
result.append(teens[u])
else:
result.append(tens[t])
if (u != 0):
result.append(units[u])
result = ' '.join(result)
print(result)
# input = 895 : result = 'eight hundreds ninety five'
# input = 507 : result = 'five hundreds seven'
# input = 120 : result = 'one hundred twenty'
# input = 071 : result = 'seventy one'
# input = 16 : result = 'sixteen'
# input = 0 : result = 'zero'

Related

how to elimate the need for a large number of if elif else statements

My script uses a if elif else check to determine which array item to look at for crafting values. The issue is there are a total of 24 elif statements to allow for a total of 26 choices, (1 for the if, 1 for error catching). What I'm trying to figure out is how to reduce the number of elif statements so the code is better structured.
while choice == 0:
choice = input("Choose a block (Enter only the Number):")
if not choice.isalpha(): # Makes sure that the input is a number and not a string.
choice = int(choice)
else:
choice = 0
print("Thats not a number. Choose a number Numbnuts.")
if choice == 1:
print("\n",block[0])
elif choice == 2:
print("\n",block[1])
elif choice == 3:
print("\n",block[2])
elif choice == 4:
print("\n",block[6])
elif choice == 5:
print("\n",block[7])
elif choice == 6:
print("\n",block[8])
elif choice == 7:
print("\n",block[3])
elif choice == 8:
print("\n",block[4])
elif choice == 9:
print("\n",block[5])
elif choice == 10:
print("\n",block[9])
elif choice == 11:
print("\n", block[10])
elif choice == 12:
print("\n", block[11])
elif choice == 13:
print("\n",block[12])
elif choice == 14:
print("\n",block[13])
elif choice == 15:
print("\n",block[14])
elif choice == 16:
print("\n",block[15])
elif choice == 17:
print("\n",block[16])
elif choice == 18:
print("\n",block[17])
elif choice == 19:
print("\n",block[18])
elif choice == 20:
print("\n",block[19])
elif choice == 21:
print("\n",block[20])
elif choice == 22:
print("\n", block[21])
elif choice == 23:
print("\n", block[22])
elif choice == 24:
print("\n",block[23])
elif choice == 25:
print("\n",block[24])
elif choice == 26:
print("\n",block[25])
Look for structure:
elif choice == 12:
print("\n", block[11])
elif choice == 13:
print("\n",block[12])
elif choice == 14:
print("\n",block[13])
elif choice == 15:
print("\n",block[14])
elif choice == 16:
print("\n",block[15])
Clearly, this is the same as;
print("\n", block[choice - 1])
However, for choice in {4,5,6,7,8,9} the logic isn't that simple, so you could keep the ifs:
if choice == 4:
print("\n",block[6])
elif choice == 5:
print("\n",block[7])
elif choice == 6:
print("\n",block[8])
elif choice == 7:
print("\n",block[3])
elif choice == 8:
print("\n",block[4])
elif choice == 9:
print("\n",block[5])
else:
print("\n", block[choice - 1])
You could also go a step deeper: for choice in {4,5,6} the index is choice-2, and for choice in {7,8,9} the index is choice-4:
if choice in {4,5,6}:
idx = choice - 2
elif choice in {7,8,9}:
idx = choice - 4
else:
idx = choice - 1
print("\n", block[idx])
As another answer suggested, look for structure; you have different ranges of choices that correspond to different offsets in block, so you can iterate over those:
while True:
try:
choice = input("Choose a block (Enter only the Number):")
except ValueError:
print("Thats not a number. Choose a number Numbnuts.")
continue
if choice < 1 or choice > 26:
continue
print("\n")
for limit, offset in ((3, -1), (6, 2), (9, -4), (26, -1)):
if choice <= limit:
print(block[choice + offset])
break
break
Hence for 1 <= choice <= 3 you print block[choice-1], for 4 <= choice <= 6 you print block[choice+2], and so on.
my version:
block_2 = block[:3]+block[6:9]+block[3:6]+block[9:]
print("\n", block_2[choice - 1])

Accounting for zero in number to word translator

I am creating a number-to-word translator and have it working with one exception.
I am having trouble accounting for zeros, for example if the number 4056 is typed in 'four thousand zero hundred fifty six' is output. Furthermore if 50 is typed in 'fifty zero' is output.
What I have so far is included below:
def convert(number_str):
d1 = {0: 'zero',1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', \
6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', \
11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', \
15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen'}
l2 = ['twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety']
if (int(number_str) >= 1) and (int(number_str) < 19):
return(d1[number_str])
elif (int(number_str) >= 20) and (int(number_str) <99):
tens, single = divmod(number_str, 10)
return l2[tens-2] + " " + d1[single]
elif (int(number_str) >= 100) and (int(number_str) <999):
hundreds, tens1 = divmod(number_str, 100)
tens, single = divmod(tens1,10)
return(d1[hundreds]+' hundred '+l2[tens-2]+" "+d1[single])
elif (int(number_str) >= 1000) and (int(number_str) <9999):
thousands, hundreds1 = divmod(number_str,1000)
hundreds, tens1 = divmod(hundreds1,100)
tens, single = divmod(tens1,10)
return(d1[thousands]+' thousand '+d1[hundreds]+' hundred '+l2[tens-2]+" "+d1[single])
def main():
user_input = input('> ')
while user_input != 'quit':
print(convert(int(user_input)))
user_input = input('> ')
main()
What logic can I add in order to better handle the use of zeros to bolster this program? Thanks in advance!
You need to add special conditions for zero. For example, the problem with 50 can be checked with an if statement:
lif (int(number_str) >= 20) and (int(number_str) <99):
tens, single = divmod(number_str, 10)
if single == 0:
return l2[tens-2]
else:
return l2[tens-2] + " " + d1[single]
You can write a similar if to deal with a 0 in the hundreds place.
The numbering system that we use in language developed well before the use of the Arabic numbering system that uses zeros effectively as a placeholder.
I'd imagine some logic in which any zero is not commented upon would work. Purely view it as a place holder to make the numbers to the left a higher 10^n value.
def convert(number_str):
d1 = {0: '',1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', \
6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', \
11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', \
15: 'fifteen', 16: 'sixteen', 17: 'seventeen', 18: 'eighteen', 19: 'nineteen'}
# Changed zero to an empty string
l2 = ['twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety']
if int(number_str) == 0: # Catches the unique case when zero is mentioned
return('zero')
elif (int(number_str) >= 1) and (int(number_str) < 19):
return(d1[number_str])
elif (int(number_str) >= 20) and (int(number_str) <=99):
tens, single = divmod(number_str, 10)
return l2[tens-2] + " " + d1[single]
elif (int(number_str) >= 100) and (int(number_str) <=999):
hundreds, tens1 = divmod(number_str, 100)
tens, single = divmod(tens1,10)
return(d1[hundreds]+' hundred '+((l2[tens-2]+" "+d1[single]) if tens > 1 else d1[tens*10+single]))
# Added a conditional statement above to deal with numbers ending
# in a number less than 20
elif (int(number_str) >= 1000) and (int(number_str) <=9999):
thousands, hundreds = divmod(number_str,1000)
return(d1[thousands]+' thousand '+ convert(hundreds))
# Added a recursive call to save code
def main():
user_input = input('> ')
while user_input != 'quit':
print(convert(int(user_input)))
user_input = input('> ')
main()
Note that it is edited in two places. Firstly to make the zero an empty string, then to catch the condition where it is simply zero.

List failing on second run

I am currently trying to program a mathematical card trick, which asks the user what pile their random card is in. However, the second time it runs (the 'trick phase' has to occur 3 times for the trick to work) the list index becomes out of range. I am unsure where exactly the problem lies and will attach the current version so you can try to run it to see clearer. Thanks!
import random
def makedeck():
listy = []
cardsindeck = 0
while cardsindeck != 21:
suit = random.randint(1,4)
if suit == 1:
suit = "D"
elif suit == 2:
suit = "H"
elif suit == 3:
suit = "S"
else:
suit = "C"
cardtype = random.randint(1,13)
if cardtype == 1:
card = "A"
elif cardtype == 2:
card = "2"
elif cardtype == 3:
card = "3"
elif cardtype == 4:
card = "4"
elif cardtype == 5:
card = "5"
elif cardtype == 6:
card = "6"
elif cardtype == 7:
card = "7"
elif cardtype == 8:
card = "8"
elif cardtype == 9:
card = "9"
elif cardtype == 10:
card = "10"
elif cardtype == 11:
card = "J"
elif cardtype == 12:
card = "Q"
else:
card = "K"
cardandsuit = (card + suit)
if cardandsuit not in listy:
listy.append(cardandsuit)
cardsindeck = cardsindeck + 1
return listy
def dealdeck(listy):
list1 = []
list2 = []
list3 = []
for i in range(len(listy)):
if i % 3 == 0:
list1.append(listy[i])
elif i % 3 == 1:
list2.append(listy[i])
else:
list3.append(listy[i])
return[list1, list2, list3]
def makepiles(pile1,pile2,pile3):
print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
for i in range(7):
print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")
def usercardpile():
userinput = input("What pile is your card in?")
if userinput == "1" or userinput.title() == "One":
return 1
elif userinput == "2" or userinput.title() == "Two":
return 2
elif userinput == "3" or userinput.title() == "Three":
return 3
else:
print("Please only write 1, 2 or 3")
return usercardpile()
listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
newlisty = makepiles(pile1,pile2,pile3)
userspile = usercardpile()
if userspile == 1:
newlisty = (pile2,pile1,pile3)
elif userspile == 2:
newlisty = (pile1,pile2,pile3)
else:
newlisty = (pile1,pile3,pile2)
pile1, pile2, pile3 = dealdeck(newlisty)
print("Your card is",newlisty[10])
One issue is with this line of code:
newlisty = makepiles(pile1, pile2, pile3)
You're expecting makepiles to return 3 lists, whereas it returns None (no explicit item returned).
I imagine if you were to return the piles from that function, it'd work.
The other thing is, You are doing this:
newlisty = (pileX, pileY, pileZ)
This will create a tuple of lists, and you will iterate over the entire lists rather than the individual cards. I believe you want
newlisty = pile1 + pile3 + pile2`
This'll create a composite list of 21 elements by linearly combining the smaller piles.
Other comments:
Consider storing your decktype and card type in dicts. That way, you can quickly lookup and generate your piles without having to write a long set of if statements. Example:
You can reduce
cardtype = random.randint(1,13)
if cardtype == 1:
card = "A"
elif cardtype == 2:
card = "2"
elif cardtype == 3:
card = "3"
elif cardtype == 4:
card = "4"
elif cardtype == 5:
card = "5"
elif cardtype == 6:
card = "6"
elif cardtype == 7:
card = "7"
elif cardtype == 8:
card = "8"
elif cardtype == 9:
card = "9"
elif cardtype == 10:
card = "10"
elif cardtype == 11:
card = "J"
elif cardtype == 12:
card = "Q"
else:
card = "K"
To...
cardtype_lookup = { 1 : 'A', 2 : '2', 3 : '3', .... 12 : 'K' }
card = cardtype_lookup[random.randint(1, 13)]
...And so on.
I think you are hitting a few issues with your code beyond just the final iterations. Below are some suggestions along with comments that I believe accomplishes your purpose.
from random import shuffle
# Function for generating 21 random cards
def makedeck():
# Create 52 cards by suit and cardtype
listy = [card + suit for card in ['A','2','3','4','5','6','7','8','9','10','J','Q','K'] for suit in ['D','H','S','C']]
# Shuffle the list
shuffle(listy)
# Choose only the first 21 items of that list
listy = listy[:21]
return listy
# Function for dividing 21-card deck into 3 equally-sized piles
def dealdeck(listy):
# Iterate over listy, stepping by 3, starting with the first, second, and third item
list1 = listy[::3]
list2 = listy[1::3]
list3 = listy[2::3]
# Return the three lists as three items to correspond to the three piles of the call
return list1, list2, list3
# This works
def makepiles(pile1,pile2,pile3):
print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
for i in range(7):
print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")
# This works
def usercardpile():
userinput = input("What pile is your card in?")
if userinput == "1" or userinput.title() == "One":
return 1
elif userinput == "2" or userinput.title() == "Two":
return 2
elif userinput == "3" or userinput.title() == "Three":
return 3
else:
print("Please only write 1, 2 or 3")
return usercardpile()
listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
# Because this function does not return anything, it should be run on its own, and not assigned to a variable
makepiles(pile1,pile2,pile3)
userspile = usercardpile()
# Now you want to re-order the piles based on user input. Because these are lists, you can simply add them together in a new order to create a newly arranged list
if userspile == 1:
newlisty = pile2 + pile1 + pile3
elif userspile == 2:
newlisty = pile1 + pile2 + pile3
else:
newlisty = pile1 + pile3 + pile2
# Now you create new piles based on the re-sorted list and re-iterate
pile1, pile2, pile3 = dealdeck(newlisty)
# Uses .format method instead
print("Your card is {}".format(newlisty[10]))

Variable not storing the correct value in Python

So I have written a program in python to try and convert a number typed into the letter version of that number. Ex: 323 -> three hundred twenty-three
The problem I am having is that the one of the variables is not displaying the correct value when the process is complete and the output is displayed. The desired output would look something like this:
Enter a number under 999: 323
323 -> three hundred twenty-three
but instead looks like this:
Enter a number under 999: 323
23 -> three hundred twenty-three
If anyone can help me figure this out, I would greatly appreciate it. Here is my code:
from __future__ import print_function, division
import sys
input = raw_input
n = int(input("Enter a number under 999: "))
if n >= 999:
print("Well, you didn't follow directions.")
sys.exit(1)
word = ""
hundred = n//100
if hundred == 1:
word += "one hundred"
elif hundred == 2:
word += "two hundred"
elif hundred == 3:
word += "three hundred"
elif hundred == 4:
word += "four hundred"
elif hundred == 5:
word += "five hundred"
elif hundred == 6:
word += "six hundred"
elif hundred == 7:
word += "seven hundred"
elif hundred == 8:
word += "eight hundred"
elif hundred == 9:
word += "nine hundred"
if hundred > 0:
word += " "
n = n%100
if n == 10:
word += ' ten'
elif n == 11:
word += ' eleven'
elif n == 12:
word += ' twelve'
elif n == 13:
word += ' thirteen'
elif n == 14:
word += ' fourteen'
elif n == 15:
word += ' fifteen'
elif n == 16:
word += ' sixteen'
elif n == 17:
word += ' seventeen'
elif n == 18:
word += ' eighteen'
elif n == 19:
word += ' nineteen'
else:
ones = n%10
tens = n//10
if tens == 2:
word += "twenty"
elif tens == 3:
word += "thirty"
elif tens == 4:
word += "fourty"
elif tens == 5:
word += "fifty"
elif tens == 6:
word += "sixty"
elif tens == 7:
word += "seventy"
elif tens == 8:
word += "eighty"
elif tens == 9:
word += "ninety"
if tens > 0 and ones > 0:
word += '-'
if ones == 1:
word += 'one'
elif ones == 2:
word += 'two'
elif ones == 3:
word += 'three'
elif ones == 4:
word += 'four'
elif ones == 5:
word += 'five'
elif ones == 6:
word += 'six'
elif ones == 7:
word += 'seven'
elif ones == 8:
word += 'eight'
elif ones == 9:
word += 'nine'
print("{} -> {}".format(n, word))
Oh and btw, My class is learning python 3 while using a python 2 interpreter so that's why the code has some weird aspects to it.
since
n = n%100
mutates "n", you need to "save" the value of "n" first. the most simple method would be:
after declaring
n = int(input("Enter a number under 999: "))
set another variable to n
n = int(input("Enter a number under 999: "))
num = n
then replace
print("{} -> {}".format(n, word))
with
print("{} -> {}".format(num, word))
Change your code to
n = int(input("Enter a number under 999: "))
user_number = n
(...)
print("{} -> {}".format(user_number, word))
Every time you do operations on n you modify it:
n = n%100
So just save it in another variable before modifying it (user_number) and print it at the end.

Appending specific values to a list while iterating from a string using a for loop

Basically I need help creating a function to read a given parameter which is a list, go through each digit of the list, checking them and adding their binary value to a different list. I am trying this code, but it's not working the way I think it should. Any help is welcome: The side parameter is there to help sort the binary. I have two sets and depending on which 'side' the digits in the list are on, they have a different binary code.
def bin_convert(upc, side):
bin_list = []
if side == 0:
for digit in upc:
if digit == 0:
bin_list.append(0001101)
elif digit == 1:
bin_list.append(0011001)
elif digit == 2:
bin_list.append(0010011)
elif digit == 3:
bin_list.append(0111101)
elif digit == 4:
bin_list.append(0100011)
elif digit == 5:
bin_list.append(0110001)
elif digit == 6:
bin_list.append(0101111)
elif digit == 7:
bin_list.append(0111011)
elif digit == 8:
bin_list.append(0110111)
elif digit == 9:
bin_list.append(0001011)
print bin_list
return bin_list
else:
for digit in upc:
if digit == 0:
bin_list.append(1110010)
elif digit == 1:
bin_list.append(1100110)
elif digit == 2:
bin_list.append(1101100)
elif digit == 3:
bin_list.append(1000010)
elif digit == 4:
bin_list.append(1011100)
elif digit == 5:
bin_list.append(1001110)
elif digit == 6:
bin_list.append(1010000)
elif digit == 7:
bin_list.append(1000100)
elif digit == 8:
bin_list.append(1001000)
elif digit == 9:
bin_list.append(1110100)
print bin_list
return bin_list

Categories

Resources