Reputation: 65
I made this calculator using Python and I'm happy with it(considering it's my very first Python program). The only thing I would like to improve is the input system. This is my current way of getting the variables, but I have to enter each variable with a space between, like this: 2 + 3 * 4. What I would like to be able to do is to enter them without a space, like this: 2+3*4.
In C++ you can do:
std::cin >> num1 >> act1 >> num2 >> act2 >> num3;
My question is if there is a way to do the same thing in Python?
This is the code I'm using now to get the variables:
user_input=input("Enter a num1 act1 num2 act2 num3 (with a space between them): ") #Gets the values
var1, action1, var2, action2, var3=user_input.split() #assigns the values into the variables
Upvotes: 1
Views: 110
Reputation: 110
You could look into the regular expression re
module to parse the user input:
import re
user_input = input(...)
pattern = '(?P<num1>\d+)\s?(?P<act1>.)\s?(?P<num2>\d+)\s?(?P<act2>.)\s?(?P<num3>\d+)'
res = re.search(pattern, user_input)
your_first_number = res.group('num1')
your_first_action = res.group('act1')
# etc.
(?P<num1>\d+)
, which is a re
group I named num1
. .
is any single character, or an operator in this case. \s?
.re
makes it a little more complicated, but it's more flexible in terms how the user can type in his input.
Upvotes: 0
Reputation: 43543
The easiest way is to use eval
, since this can calculate expressions for you.
However eval
can be dangerous with untrusted input since by default it exposes the whole Python interpreter. This is not an issue for a program you use yourself, but could be problematic for say a module used in a web application.
In the example below (in IPython), I've tried to make it less dangerous by using the locals
and globals
options. The _locals
dict is used to make some functions from the math
module available for use in expressions. The _globals
dict disables Python's built-ins. Also note that this is in Python 3 which uses floating point division for the /
operator.
In [1]: import math
In [2]: _globals = {"__builtins__": None}
In [3]: _lnames = ('acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'e', 'log', 'log10',
...: 'pi', 'sin', 'sinh', 'sqrt', 'tan', 'tanh')
In [4]: _locals = {k: eval('math.'+k) for k in _lnames}
In [5]: eval('2+3*4', _globals, _locals)
Out[5]: 14
In [6]: eval('1+2/3', _globals, _locals)
Out[6]: 1.667
In [7]: eval('sin(pi)', _globals, _locals)
Out[7]: 1.225e-16
In [8]: eval('cos(pi)', _globals, _locals)
Out[8]: -1
In [9]: eval('cos(pi/2)', _globals, _locals)
Out[9]: 6.123e-17
Note that the outputs of 7 and 9 (which should be 0) are caused by the limits on accuracy of floating point arithmatic.
Upvotes: 0
Reputation: 2293
You could do something like this:
user_input = '2+12*9'
numbers = ''.join([x if x.isnumeric() else ' ' for x in user_input])
operators = [x for x in user_input if not x.isnumeric()]
var1, var2, var3 = numbers.rsplit(' ')
action1, action2 = operators[0], operators[1]
Basically using list comprehension to separate out the numbers and then the operators, and then using rsplit
to assign the numbers to their variables and assigning the operator variables by their index in the list. This method will also allow you to use numbers with multiple digits.
Upvotes: 1