So this function takes inputs from the user and converts their input into a value. For example, if they put in 1k, the output would be 1000. I want to be able to go backwards. So say if I had a value of 325000, I want to change that to 325k. Any ideas on how I could achieve this?
class Parsing:
def __init__(self, instring):
self.instring = instring
def valueParsing(self):
self.instring = self.instring.strip()
self.parsedString = ''
self.scalerDict = {'K': 1000, 'MEG': 1000000, 'G': 1000000000, 'M': 0.001, 'U': 0.000001, 'N': 0.000000001, 'P': 0.000000000001}
self.scaler = 1.0
self.stringCounter = 0
self.errorflag = False
self.Parsedvalue = 0.0
self.inStringLength = len(self.instring)
for self.stringCounter in range (self.inStringLength):
if ((self.instring[self.stringCounter].upper()) == 'K'):
self.scaler = self.scalerDict['K']
elif ((self.instring[self.stringCounter].upper()) == 'G'):
self.scaler = self.scalerDict['G']
elif ((self.instring[self.stringCounter].upper()) == 'U'):
self.scaler = self.scalerDict['U']
elif ((self.instring[self.stringCounter].upper()) == 'N'):
self.scaler = self.scalerDict['N']
elif ((self.instring[self.stringCounter].upper()) == 'P'):
self.scaler = self.scalerDict['P']
elif ((self.instring[self.stringCounter].upper()) == 'M'):
if (((self.instring.upper()).count('MEG'))):
self.scaler = self.scalerDict['MEG']
else:
self.scaler = self.scalerDict['M']
elif (( self.instring[ self.stringCounter ].upper() ) == 'F' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'W' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'S' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == '%' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'V' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'A' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'H' ):
break
elif (( self.instring[ self.stringCounter ].upper() ) == 'Z' ):
break
elif (( self.instring[ self.stringCounter ]) == '.' ):
self.parsedString = self.parsedString + self.instring[ self.stringCounter ]
elif (self.instring[self.stringCounter].isdigit()):
if(int(self.instring[self.stringCounter]) >= 0):
if(int(self.instring[self.stringCounter]) <= 9):
self.parsedString = self.parsedString + self.instring[self.stringCounter]
else:
self.errorflag = True
break
else:
self.errorflag = True
print('Invalid input, Try again.')
if (self.errorflag):
self.parsedvalue = -1
else:
self.parsedvalue = long(self.parsedString)*self.scaler
return self.parsedvalue
print '1. Resistors in series\n',\
'2. Resistors in Parallel\n',\
'3. Voltage Divider\n'
iput = int(input("Enter your choice: "))
if iput == 1:
r1 = raw_input("Enter first resistor:")
r2 = raw_input("Enter second resistor:")
R1 = Parsing(r1)
R2 = Parsing(r2)
req = R1.valueParsing() + R2.valueParsing()
print "The value of the series resistors is %s." % req
Try this:
import math
def fmtnum(num):
k = (1e3, 'k')
M = (1e6, 'M')
G = (1e9, 'G')
table = {3: k, 4: k, 5: k, 6: M, 7: M, 8: M, 9: G, 10: G, 11: G}
num = float(num)
exp = math.log10(num)
if num < 0:
exp = int(exp)-1
else:
exp = int(exp)
try:
denum, suffix = table[exp]
return '{:g} {}'.format(num/denum, suffix)
except KeyError:
return '{:g}'.format(num)
Extending this solution for negative powers of 10 has been left as an exercise for the reader. :-)
Examples:
In [50]: fmtnum(3250)
Out[50]: '3.25 k'
In [51]: fmtnum(32500)
Out[51]: '32.5 k'
In [52]: fmtnum(325000)
Out[52]: '325 k'
In [53]: fmtnum(3250000)
Out[53]: '3.25 M'
In [54]: fmtnum(32500000)
Out[54]: '32.5 M'
In [55]: fmtnum(325000000)
Out[55]: '325 M'
In [56]: fmtnum(3250000000)
Out[56]: '3.25 G'
how about:
n = 1000
for exp, name in zip(range(9, -13, -3), ('GMk1munp')):
if exp == 0:
continue
if isinstance(n, int):
if n % 10**exp == 0:
n = '{0:d}{1}'.format(n / 10**exp, name)
break
elif isinstance(n, basestring):
if n[-exp:] == '0' * exp:
n = '{0}{1}'.format(n[:-exp], name)
break
elif n[-1] == name:
n = n[:-1] + '0' * exp
break
by running exponents backwards you make sure that you find the right match.
Related
I'm making a roman numeral to integer converter. In the code below, you will see the function math_logic. When I give the input CCC, the program should skip the if statements and elif statements (because of the keyword and) and go right to the else statement since only one of the two conditions are met. The else statement should return a dictionary value using parameter char_0 as the key. However, the program will run the code inside the second elif statement and return TypeError: unsupported operand type(s) for +: 'int' and 'NoneType' as the error.
I'm not sure why this is happening. You can put a debug point at line 38 and step into 4 times to get to the issue I'm having.
Please see code below
romanToIntDictionary = {
"I": 1,
"V": 5,
"X": 10,
"L": 50,
"C": 100,
"D": 500,
"M": 1000
}
subtraction_happened = [
4,
9,
40,
90,
400,
900
]
def convert_roman_to_int(string, checker_state):
characters_left = len(string)
character_list = []
total = 0
if checker_state:
print("What you entered is a valid roman numeral.")
for character in string:
character_list.append(character)
while characters_left > 1:
did_i_sub = False
for item in subtraction_happened:
if (not did_i_sub) and (item == math_logic(character_list[0], character_list[1], romanToIntDictionary)): #the order of multiple conditions matters
total = total + math_logic(character_list[0], character_list[1], romanToIntDictionary)
characters_left -= 2
character_list.pop(0)
character_list.pop(0)
did_i_sub = True
if not did_i_sub:
total = total + math_logic(character_list[0], character_list[1], romanToIntDictionary)
characters_left -= 1
character_list.pop(0)
while characters_left == 1:
total = total + romanToIntDictionary[character_list[0]]
characters_left -= 1
character_list.pop(0)
print(total)
if not checker_state:
print("What you entered is not a roman numeral.")
def math_logic(char_0, char_1, r_to_i_dict):
if (char_0 == "I") and (char_1 == "V" or "X"):
if char_1 == "V":
return 4
elif char_1 == "X":
return 9
elif (char_1 == "L" or "C") and (char_0 == "X"):
if char_1 == "L":
return 40
elif char_1 == "C":
return 90
elif (char_1 == "D" or "M") and (char_0 == "C"):
if char_1 == "D":
return 400
elif char_1 == "M":
return 900
else:
return r_to_i_dict[char_0]
def roman_numeral_checker(string):
is_roman_numeral = True
characters_left = len(string)
while is_roman_numeral and characters_left > 0:
for character in string:
if character not in romanToIntDictionary.keys():
is_roman_numeral = False
characters_left -= 1
if not is_roman_numeral:
return False
if is_roman_numeral:
return True
string_from_user = (input("Enter a roman numeral to convert: ")).upper()
convert_roman_to_int(string_from_user, roman_numeral_checker(string_from_user))
The trouble is in your boolean logic:
value = 'c'
print(value == 'X' or 'V')
'V'
This is because 'V' is a "truthy" value:
bool('V')
True
So you are saying if value == 'X' or True: which will always be True. Because of this, there's an else that isn't evaluating:
if value == 'X' or 'V':
if value == 'X':
print('X!')
elif value == 'V':
print('V!')
else:
print('unexpected')
unexpected
The correct syntax is:
if value == 'X' or value == 'V':
Or even more succinctly:
if value in ('X', 'V'):
if value == 'X':
do something
else:
do something
The else ensures that all cases are covered, and they are, because value could only be 'X' or 'V'.
So your whole math logic function would be:
def math_logic(char_0, char_1, r_to_i_dict):
if char_0 == "I" and char_1 in ('V', 'X'):
if char_1 == "V":
return 4
else:
return 9
elif char_1 in ('L', 'C') and char_0 == "X":
if char_1 == "L":
return 40
else:
return 90
elif char_1 in ('D', 'M') and char_0 == "C":
if char_1 == "D":
return 400
else:
return 900
else:
return r_to_i_dict[char_0]
I looked at the other answers but they didn't seem to work for me, or I could just be doing something wrong, or not understanding what I am supposed to do in the context of this code. On line 78, it talks about how there is a Nonetype value, even though I assigned a value to both variables no matter what.
Here is a link to a similar problem (I think):
[https://stackoverflow.com/questions/53680913/typeerror-cannot-unpack-non-iterable-nonetype-object][1]
Here is where I think the faulty code lies:
def check_win(turn, gamestate):
if turn == 1:
if gamestate[0] == gamestate[1] == gamestate[2] != '-' or gamestate[3] == gamestate[4] == gamestate[5] != '-' or gamestate[6] == gamestate[7] == gamestate[8] != '-':
winner = 1
win = True
return winner, win
elif gamestate[0] == gamestate[3] == gamestate[6] != '-' or gamestate[1] == gamestate[4] == gamestate[7] != '-' or gamestate[2] == gamestate[5] == gamestate[8] != '-':
winner = 1
win = True
return winner, win
elif gamestate[0] == gamestate[4] == gamestate[8] != '-' or gamestate[2] == gamestate[4] == gamestate[6] != '-':
winner = 1
win = True
return winner, win
elif turn == 2:
if gamestate[0] == gamestate[1] == gamestate[2] or gamestate[3] == gamestate[4] == gamestate[5] or gamestate[6] == gamestate[7] == gamestate[8]:
winner = 2
win = True
return winner, win
elif gamestate[0] == gamestate[3] == gamestate[6] or gamestate[1] == gamestate[4] == gamestate[7] or gamestate[2] == gamestate[5] == gamestate[8]:
winner = 2
win = True
return winner, win
elif gamestate[0] == gamestate[4] == gamestate[8] or gamestate[2] == gamestate[4] == gamestate[6]:
winner = 2
win = True
return winner, win
else:
winner = 'None'
win = False
return winner, win
Later on when I try to alter those values in another function:
winner, win = check_win(turn, gamestate) <--- Where error was found
Here is the code in its entirety :
print('Tic Tac Toe:')
pos = 0
turn = 1
gamestate = ['-', '-', '-', '-', '-', '-', '-', '-', '-']
def display_board(gamestate):
print(gamestate[0:3])
print(gamestate[3:6])
print(gamestate[6:9])
def move_validity(pos, gamestate):
if str(gamestate[int(pos)]) != '-':
print('Invalid move.')
valid = False
return valid
else:
valid = True
return valid
def update(gamestate, pos):
if turn == 1:
gamestate[int(pos)] = 'X'
if turn == 2:
gamestate[int(pos)] = 'O'
else:
print('ERROR')
def check_win(turn, gamestate):
if turn == 1:
if gamestate[0] == gamestate[1] == gamestate[2] != '-' or gamestate[3] == gamestate[4] == gamestate[5] != '-' or gamestate[6] == gamestate[7] == gamestate[8] != '-':
winner = 1
win = True
return winner, win
elif gamestate[0] == gamestate[3] == gamestate[6] != '-' or gamestate[1] == gamestate[4] == gamestate[7] != '-' or gamestate[2] == gamestate[5] == gamestate[8] != '-':
winner = 1
win = True
return winner, win
elif gamestate[0] == gamestate[4] == gamestate[8] != '-' or gamestate[2] == gamestate[4] == gamestate[6] != '-':
winner = 1
win = True
return winner, win
elif turn == 2:
if gamestate[0] == gamestate[1] == gamestate[2] or gamestate[3] == gamestate[4] == gamestate[5] or gamestate[6] == gamestate[7] == gamestate[8]:
winner = 2
win = True
return winner, win
elif gamestate[0] == gamestate[3] == gamestate[6] or gamestate[1] == gamestate[4] == gamestate[7] or gamestate[2] == gamestate[5] == gamestate[8]:
winner = 2
win = True
return winner, win
elif gamestate[0] == gamestate[4] == gamestate[8] or gamestate[2] == gamestate[4] == gamestate[6]:
winner = 2
win = True
return winner, win
else:
winner = 'None'
win = False
return winner, win
def restart():
gamestate = ['-', '-', '-', '-', '-', '-', '-', '-', '-']
turn = 1
win = False
return gamestate, turn, win
def choose_position():
pos = input('Player ' + str(turn) + ': ')
if int(pos) < 0 or int(pos) > 8:
print('Invalid move')
else:
return pos
def Tic_Tac_Toe():
while True:
global pos
global turn
if turn == 1:
pos = choose_position()
valid = move_validity(pos, gamestate)
if valid == True:
update(gamestate, pos)
if valid == False:
break
winner, win = check_win(turn, gamestate)
if win == True:
print(str(winner) + ' wins!')
break
if '-' not in gamestate:
print('Tie game.')
break
if turn == 2:
pos = choose_position()
if move_validity(pos, gamestate) == True:
continue
if move_validity(pos, gamestate) == False:
break
update(gamestate, pos)
winner, win = check_win(turn, gamestate)
if win == True:
print(str(winner) + ' wins!')
break
turn = 1
if '-' not in gamestate:
print('Tie game.')
break
display_board(gamestate)
display_board(gamestate)
Tic_Tac_Toe()
restart_case = input('y/n Would you like to play? ')
if restart_case == 'y':
gameboard, turn, win = restart()
Thank you so much, and sorry if the solution was a small typo, I am really new to this and have spent way too much time on this. :D
There are certain cases where you don't return anything in the function check_win.
For example, when turn == 1, you have an if, elif, elif block within that, but nothing for else. So, when turn == 1, if none of the if statements within the block for that are true, your function will return nothing. There is a similar problem for turn == 2. You may want to add the code you have in the else block for that function as an else block for both turn == 1 and turn == 2, as this will fix your problem.
start = input('Enter quadratic equation: ')
w = start.split()
while len(w) != 7:
start = input('Enter quadratic equation correctly: ')
w = start.split()
while x < len(w):
if "x" in w[x] and '^2' in w[x]:
a = w[x]
if a == "x^2":
a = 1
else:
a = a.replace('x^2', '')
a = int(a)
if w[x-1] == '-':
a = a * (-1)
else:
a = a
elif 'x' in w[x] and '^' not in w[x]:
b = w[x]
if b == 'x':
b = 1
else:
b = b.replace('x', '')
b = int(b)
if w[x-1] == '-':
b = b * (-1)
else:
b = b
elif w[x].isdigit() and 'x' not in w[x] and w[x] != '0':
c = w[x]
elif w[x] == '-' or '+' or '=':
s = 0
elif not w[x].isdigit() and 'x' not in w[x] and w[x] != '-' or '+' or '=':
print('Mistake')
break #Would not this code here work?
x += 1
I have tried just doing 'else' block, but still it wouldn't work. What I am trying to do is to check whether the input is actually a quadratic equation.
The wrong condition is elif not w[x].isdigit() and 'x' not in w[x] and w[x] != '-' or '+' or '=':, it doesn't do what you want/need
The w[x] != '-' or '+' or '=': part :
is like (w[x]!='-') or ('+') or ('='):
not like w[x] != ('-' or '+' or '='):
What you want is w[x] not in '-+=': and same for the previous one
elif w[x] in '-+=':
s = 0
elif not w[x].isdigit() and 'x' not in w[x] and w[x] not in '-+=':
print('Mistake')
break
I currently have defined my object (is_matched) that contains a while loop and also the checking of a string. I am trying to pull out the while loop into it's own object but am having trouble completing the coding. I also need the while loop to continue running until a user enters 'q' into the input.
def is_matched():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
stack = Stack()
for i in expr:
if i == '{' or i == '(' or i == '[':
stack.push(i)
elif i == '}':
if len(expr) != 0:
c = stack.top()
if c == '{':
stack.pop()
else:
return "Unbalanced"
elif i == ')':
if len(expr) != 0:
c = stack.top()
if c == '(':
stack.pop()
else:
return "Unbalanced"
elif i == ']':
if len(expr) != 0:
c = stack.top()
if c == '[':
stack.pop()
else:
return "Unbalanced"
else:
return "Unbalanced"
if len(stack) != 0:
return "Unblanced"
return "Balanced"
result = is_matched()
print(result)
I am trying to pull out the while loop from above and enter into its own object as follows:
def main():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
else:
return is_matched()
your is_matched function will take one argument which will be the expression to evaluate.
def is_matched(expr):
stack = Stack()
for i in expr:
if i == '{' or i == '(' or i == '[':
stack.push(i)
elif i == '}':
if len(expr) != 0:
c = stack.top()
if c == '{':
stack.pop()
else:
return "Unbalanced"
elif i == ')':
if len(expr) != 0:
c = stack.top()
if c == '(':
stack.pop()
else:
return "Unbalanced"
elif i == ']':
if len(expr) != 0:
c = stack.top()
if c == '[':
stack.pop()
else:
return "Unbalanced"
else:
return "Unbalanced"
if len(stack) != 0:
return "Unblanced"
return "Balanced"
main function.
def main():
while True:
expr = input("Enter string (q to quit): ")
if expr == "q":
break
else:
print(is_matched(expr))
This code is supposed to print out a "barcode" from a given zip code. The problem is that it is only printing out none after it is done. No visible errors to me. Could you take a look?
def printDigit(d , x):
if x <= 5:
if d[x] == 0:
return "||:::" + printDigit(d , x + 1)
elif d[x] == 1:
return ":::||" + printDigit(d , x + 1)
elif d[x] == 2:
return "::|:|" + printDigit(d , x + 1)
elif d[x] == 3:
return "::||:" + printDigit(d , x + 1)
elif d[x] == 4:
return ":|::|" + printDigit(d , x + 1)
elif d[x] == 5:
return ":|:|:" + printDigit(d , x + 1)
elif d[x] == 6:
return ":||:|" + printDigit(d , x + 1)
elif d[x] == 7:
return "|:::|" + printDigit(d , x + 1)
elif d[x] == 8:
return "|::|:" + printDigit(d , x + 1)
elif d[x] == 9:
return "|:|::" + printDigit(d , x + 1)
else:
return
zipCode = str(input("Input a zip code: "))
print(printDigit(zipCode , 0))
Here is one way you can do this. Instead of using recursion for this problem you can just iterate through the characters of the input. If there are less than 5 characters you can immediately return None since the zip code input is wrong. Then we will iterate through each character and add the barcode to a list.
At the end we check if the length of the list is 25, this would mean that we indeed had 5 numbers, if there are any letters or special characters they will get ignored.
def printDigit(d):
if len(str(d)) == 5 and str(d).isdigit():
temp = []
for i in str(d):
if i == '0': temp.extend("||:::")
elif i == '1': temp.extend(":::||")
elif i == '2': temp.extend("::|:|")
elif i == '3': temp.extend("::||:")
elif i == '4': temp.extend(":|::|")
elif i == '5': temp.extend(":|:|:")
elif i == '6': temp.extend(":||:|")
elif i == '7': temp.extend("|:::|")
elif i == '8': temp.extend("|::|:")
elif i == '9': temp.extend("|:|::")
return ''.join(temp)
else: return None
zipCode = str(input("Input a zip code: "))
print(printDigit(zipCode))
To avoid rewriting code segments. We can also use a dictionary to hold the translation of each digit to its barcode value. Then we can use list comprehensions as
def printDigit(d):
dic = {'0': "||:::", '1': "||:::", '2': "::|:|",
'3': "::||:", '4': ":|::|", '5': ":|:|:",
'6': ":||:|", '7': "|:::|", '8': "|::|:",
'9': "|:|::"}
if len(str(d)) == 5 and str(d).isdigit():
return ''.join([dic[i] for i in str(d)])
else: return None
zipCode = str(input("Input a zip code: "))
print(printDigit(zipCode))
You're accepting the entered zipCode as a String object. So while comparing it's elements you can either put the digits within single quotes or convert the zipCode to an integer. I'd also suggest checking if the current character in the string is a digit using the isdigit() method. Also when the value of x crosses 5 then your printDigit method returns NoneType which cannot be combined with a string object. Therefore return ""
def printDigit(d , x):
if x <len(d) and d[x].isdigit():
if int(d[x]) ==0:
return "||:::" + printDigit(d , x + 1)
elif int(d[x]) == 1:
return ":::||" + printDigit(d , x + 1)
elif int(d[x]) == 2:
return "::|:|" + printDigit(d , x + 1)
elif int(d[x]) == 3:
return "::||:" + printDigit(d , x + 1)
elif int(d[x]) == 4:
return ":|::|" + printDigit(d , x + 1)
elif int(d[x]) == 5:
return ":|:|:" + printDigit(d , x + 1)
elif int(d[x]) == 6:
return ":||:|" + printDigit(d , x + 1)
elif int(d[x]) == 7:
return "|:::|" + printDigit(d , x + 1)
elif int(d[x]) == 8:
return "|::|:" + printDigit(d , x + 1)
elif int(d[x]) == 9:
return "|:|::" + printDigit(d , x + 1)
else:
return ""
zipCode = input("Input a zip code: ")
print(printDigit(zipCode , 0))