Python creating a calculator

2020-02-16 04:48发布

I am fairly new to python.

I have been asked to create a calculator using only string commands, conversions between int/string/float etc.(if needed), and using functions is a requirement. while and for loops can also be used.

The program needs to take an input of the form x/y or x/y/z, where x y z are any positive or negative number. Where "/" can be replaced by addition multiplication and subtraction as well. And where any number of white spaces can exist between operands and operators. This is an idea of what I have so far.

I would have a unique definition for +,-,/, and *. I would create a function for what the user inputs. I would use ".lstrip" and ".rstrip" to get rid of white spaces.

Now what I am having trouble with is creating the input function. I am very new to functions and this is basically what I have. I know it isn't much to work with but I am really stuck on how to properly enter the function.

def multiplication(x,a,y,b,z):
    if (a== "*"):
        return x*y
    if (b== "*"):
        return y*z

def division(x,a,y,b,z):
    if (a== "/"):
        return x/y
    if (b== "/"):
        return y/z

def addition(x,a,y,b,z):
    if (a== "+"):
        return x+y
    if (b== "+"):
        return y+z

def subtraction(x,a,y,b,z):
    if (a== "-"):
        return x-y
    if (b== "-"):
        return y-z

def (x,y,z):
    x=0
    y=0
    z=0

    zxc=int(input()):# this is where I get stuck and I don't know how to implement x,y,z into the input.

All help is appreciated. If you are unsure of whether the code you provide is too intense for my needs, please ask before wasting your time for me, making code that I can't possibly use. I promise to reply ASAP.

Basically I am trying to find a way to split the inputted string AND THEN start calculations with it.

4条回答
我欲成王,谁敢阻挡
2楼-- · 2020-02-16 05:22

Here is a possible solution outline using regular expressions. Error checking left as exercise. If this isn't homework and you'd like to see the fleshed-out solution, view it here

import re

# input is a list of tokens (token is a number or operator)
tokens = raw_input()

# remove whitespace
tokens = re.sub('\s+', '', tokens)

# split by addition/subtraction operators
tokens = re.split('(-|\+)', tokens)

# takes in a string of numbers, *s, and /s. returns the result
def solve_term(tokens):
    tokens = re.split('(/|\*)', tokens)
    ret = float(tokens[0])
    for op, num in <FILL THIS IN>:
        # <apply the operation 'op' to the number 'num'>
    return ret

# initialize final result to the first term's value
result = solve_term(tokens[0])

# calculate the final result by adding/subtracting terms
for op, num in <FILL THIS IN>:
    result +=  solve_term(num) * (1 if op == '+' else -1)

print result
查看更多
够拽才男人
3楼-- · 2020-02-16 05:23

I have an alternative to your code. The user can enter stuff like: 8*6/4-3+3 and this will still work. It also will not crash if a letter (d, a, s) is entered. Very compact.

Code (Python v3.3.0):

valid_chars = "0123456789-+/* \n";
while True:
    x = "x="
    y = input(" >> ")
    x += y
    if False in [c in valid_chars for c in y]:
        print("WARNING: Invalid Equation");
        continue;
    if(y == "end"):
        break
    exec(x)
    print(x)
查看更多
干净又极端
4楼-- · 2020-02-16 05:33

If you're making just a toy calculator, eval() accepts local and global variables, so you could use something like this:

def calculate(x=0, y=0, z=0):
    expression = raw_input('Enter an expression: ')

    return eval(expression, None, locals())

Here's a sample console session:

>>> calculate()
Enter an expression: x + 5 - y
5

Note that eval() is not secure. If you want to make something serious, you will have to parse the expression.

Also, since your expressions are simple, you could use a regex to validate the input before evaling it:

def validate(expression):
    operator = r'\s*[+\-/*]\s*'

    return bool(re.match(r'^\s*(?:x{o}y|x{o}y{o}z)$'.format(o=operator), expression))
查看更多
\"骚年 ilove
5楼-- · 2020-02-16 05:39

Since this looks like homework, I doubt the OP is allowed to use the typical ways to solve the problem. I think this is an exercise in input validation and string manipulation; followed by program flow and understanding function return values.

There are two things you need to do here:

  1. Figure out what would be valid inputs to your program.
  2. Keep prompting the user till he or she enters input that is valid for your program.

For #1, we know that valid inputs are numbers (positive or negative integers), and they must be in the form of an expression. So this means, the minimum length of the input will be three (two numbers and a math symbol) and characters (strings) in the input are not valid.

This is our basic loop to get the user's input:

expression = raw_input('Please enter the expression: ')
expression_result = check_input(expression)

while not expression_result:
    print 'You did not enter a valid expression'
    expression = raw_input('Please enter the expression: ')
    expression_result = check_input(expression)

The check_input method will validate whatever the user entered is accurate based on our rules:

def check_input(input_string):

    # Check the basics
    if len(input_string) < 3:
        return False

    # Check if we are getting passed correct characters
    for character in input_string:
        if character not in '1234567890' or character not in '/*+-':
            return False

    # Things like /23 are not valid
    if input_string[0] in '/*+':
        return False

    return input_string

After you have the correct input, the next step is to split the input into the various parts that you need to feed to your math functions. I'll leave that part up to you.


Assuming you have the correct string (that is, it is valid input for your program), you now need to split it into two parts.

  1. The operator (the math symbol)
  2. The operands (the numbers surrounding the math symbol)

So we know that we have a limited set of operators +,-,/,*, so one idea is to use the split() method of strings. This works well:

>>> s = '4+5'
>>> s.split('+')
['4', '5']

You would try splitting the string with all of your operators and then check the results. Note that splitting a string with a character that doesn't exist won't raise any errors, but you'll just the string back:

>>> s = '4+5'
>>> s.split('/')
['4+5']

So one approach is - split the string on the operators, if the resulting list has length > 2, you know that the first member of the resulting list is the left hand side of the operator, and the second member of the list is whatever is on the right hand side.

This works fine with positive numbers, with negative numbers however:

>>> s = '-4+3'
>>> s.split('-')
['', '4+3']

Good news is we aren't the first ones to reach this problem. There is another way to evaluate equations, called the Polish notation (also called prefix notation). Here's the algorithm from the wikipedia page:

Scan the given prefix expression from right to left
for each symbol
 {
  if operand then
    push onto stack
  if operator then
   {
    operand1=pop stack
    operand2=pop stack
    compute operand1 operator operand2
    push result onto stack
   }
 }
return top of stack as result

To get a normal expression (called infix) to the polish flavor, use the shunting yard algorithm, which is my favorite train-based algorithm in computer science.

Use shunting yard to convert your expression to Polish notation, then use the pseudo code to solve the equation. You can use lists as your "stack".

Keep in mind all your inputs are in strings, so make sure you convert them to integers when you are doing the actual math.

查看更多
登录 后发表回答