I've looked into this but I couldn't find anything that helped me (Apologies if the answer to something similar is out there that could have helped me). I'm writing a currency converter that suffers from tons of if's that just doesn't seem efficient nor can I imagine very nicely readable, so I'd like to know how I can write more efficient code in this case:
prompt = input("Input") #For currency, inputs should be written like "C(NUMBER)(CURRENCY TO CONVERT FROM)(CURRENCY TO CONVERT TO)" example "C1CPSP"
if prompt[0] == "C": #Looks at first letter and sees if it's "C". C = Currency Conversion
#CP = Copper Piece, SP = Silver Piece, EP = Electrum Piece, GP = Gold Piece, PP = Platinum Piece
ccint = int(''.join(list(filter(str.isdigit, prompt)))) # Converts Prompt to integer(Return string joined by str.(Filters out parameter(Gets digits (?), from prompt))))
ccalpha = str(''.join(list(filter(str.isalpha, prompt)))) #Does the same thing as above expect with letters
if ccalpha[1] == "C": #C as in start of CP
acp = [ccint, ccint/10, ccint/50, ccint/100, ccint/1000] #Array of conversions. CP, SP, EP, GP, PP
if ccalpha[3] == "C": #C as in start of CP
print(acp[0]) #Prints out corresponding array conversion
if ccalpha[3] == "S": #S as in start of SP, ETC. ETC.
print(acp[1])
if ccalpha[3] == "E":
print(acp[2])
if ccalpha[3] == "G":
print(acp[3])
if ccalpha[3] == "P":
print(acp[4])
if ccalpha[1] == "S":
asp = [ccint*10, ccint, ccint/10, ccint/10, ccint/100]
if ccalpha[3] == "C":
print(asp[0])
if ccalpha[3] == "S":
print(asp[1])
if ccalpha[3] == "E":
print(asp[2])
if ccalpha[3] == "G":
print(asp[3])
if ccalpha[3] == "P":
print(asp[4])
if ccalpha[1] == "E":
aep = [ccint*50, ccint*5 ,ccint , ccint/2, ccint/20]
if ccalpha[3] == "C":
print(aep[0])
if ccalpha[3] == "S":
print(aep[1])
if ccalpha[3] == "E":
print(aep[2])
if ccalpha[3] == "G":
print(aep[3])
if ccalpha[3] == "P":
print(aep[4])
if ccalpha[1] == "G":
agp = [ccint*100, ccint*10, ccint*2, ccint, ccint/10]
if ccalpha[3] == "C":
print(agp[0])
if ccalpha[3] == "S":
print(agp[1])
if ccalpha[3] == "E":
print(agp[2])
if ccalpha[3] == "G":
print(agp[3])
if ccalpha[3] == "P":
print(agp[4])
if ccalpha[1] == "P":
app = [ccint*1000, ccint*100, ccint*20, ccint*10, ccint]
if ccalpha[3] == "C":
print(app[0])
if ccalpha[3] == "S":
print(app[1])
if ccalpha[3] == "E":
print(app[2])
if ccalpha[3] == "G":
print(app[3])
if ccalpha[3] == "P":
print(app[4])
You can always use dictionaries for lookups:
lookup = {'C': {'C': ccint, 'S': ccint/10, 'E': ccint/50, 'G': ccint/100, 'P': ccint/1000},
'S': {'C': ccint*10, 'S': ccint, 'E': ccint/10, 'G': ccint/10, 'P': ccint/100},
'E': {'C': ccint*50, 'S': ccint*5, 'E': ccint, 'G': ccint/2, 'P': ccint/20},
'G': {'C': ccint*100, 'S': ccint*10, 'E': ccint*2, 'G': ccint, 'P': ccint/10},
'P': {'C': ccint*1000, 'S': ccint*100, 'E': ccint*20, 'G': ccint*10, 'P': ccint}
}
Then all your ifs are mostly covered by:
print(lookup[ccalpha[1]][ccalpha[3]])
However is it possible that other characters are included? Then you'd need to introduce a fallback:
try:
print(lookup[ccalpha[1]][ccalpha[3]])
except KeyError:
# Failed to find an entry for the characters:
print(ccalpha[1], ccalpha[3], "combination wasn't found")
As noted it's not the most efficient way because it calculates every conversion (even unneccessary ones) each time. It could be more efficient to have a baseline, for example P and have the factors saved:
lookup = {'C': 1000,
'S': 100,
'E': 50,
'G': 10,
'P': 1,
}
# I hope I have them the right way around... :-)
print(ccint * lookup[ccalpha[3]] / lookup[ccalpha[1]])
Instead of converting directly from the source unit to the target unit, you should do it in two steps:
factors = { 'CP': 1, 'SP': 10, and so on }
def convert_currency(amount, from_unit, to_unit):
copper = amount * factors[from_unit]
return copper / factors[to_unit]
This code is all you need. You can call it like this:
print(convert_currency(12345, 'SP', 'EP'))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With