Y=1
N=0
cont=Y
print "Welcome to SCLMIP(Simple Calculator For Linux Made In Python)"
while cont == Y:
    equation=input("Equation: ")
    print equation
    cont=input("Continue? (Y,N)")
else:
    print "Exiting..."

If you type 5/2 you get 2, I want it to display 2.5.

A workaround is typing 5.0/2.0, but it gets annoying. I want it to automatically decide to show decimals.

Dani AI

Generated

: the behavior you saw comes from Python 2 integer division (5/2 -> 2) and from using input() there (it evaluates Python code). is right that switching to Python 3 (or enabling true-division) fixes this globally. If you want a small, safe change that keeps a prompt-style calculator and prints decimals only when they matter, try parsing the typed expression and converting numeric literals to floats before evaluation.

The snippet below uses the ast module to (1) ensure only simple arithmetic is allowed, (2) convert integer literals into floats so / yields true division, and (3) evaluate safely with no builtins. It works on modern Python and is more secure than blindly calling eval() on user text.

import ast

try:
    integer_types = (int, long)
except NameError:
    integer_types = (int,)

ALLOWED = (ast.Expression, ast.BinOp, ast.UnaryOp, ast.Num,
           getattr(ast, 'Constant', ast.Num),
           ast.Add, ast.Sub, ast.Mult, ast.Div, ast.FloorDiv,
           ast.Pow, ast.Mod, ast.UAdd, ast.USub)

class Validator(ast.NodeVisitor):
    def generic_visit(self, node):
        if not isinstance(node, ALLOWED):
            raise ValueError("Disallowed node: %r" % type(node).__name__)
        super(Validator, self).generic_visit(node)

class NumToFloat(ast.NodeTransformer):
    def visit_Num(self, node):
        return ast.copy_location(ast.Num(float(node.n)), node)
    def visit_Constant(self, node):
        if isinstance(node.value, integer_types):
            return ast.copy_location(ast.Constant(float(node.value)), node)
        return node

def safe_eval(expr):
    tree = ast.parse(expr, mode='eval')
    Validator().visit(tree)
    tree = NumToFloat().visit(tree)
    ast.fix_missing_locations(tree)
    result = eval(compile(tree, '<expr>', 'eval'), {'__builtins__': None}, {})
    if isinstance(result, float) and abs(result - int(result)) < 1e-12:
        return int(result)
    return result

Usage: capture the equation as a string, pass it to safe_eval, then print the return value. That prints 2.5 for 5/2 and 2 for 4/2. Avoid input() in Python 2 (it evaluates user code); prefer reading a string and parsing it. Also consider 's suggestion to use booleans for your loop control or just while True with a break.

References: PEP on changing division semantics (PEP 238) and the standard ast docs (ast — Abstract Syntax Trees).

Recommended Answers

All 2 Replies

I know this doesn't answer the question, but
Could you just use True and False keywords instead of Y and N?

Starting with Python3 the / will be float division and // will be integer division. You can use these future feature already by importing the __future__ module:

from __future__ import division
print "Welcome to SCLMIP(Simple Calculator For Linux Made In Python)"
while True:
    equation = input("Equation: ")
    print equation
    if raw_input("Continue? (Y,N)").upper() == 'N': break
else:
    print "Exiting..."
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.