0

i was making a calculator in which the user inputs an expression such as 3*2+1/20 and i use the eval to display the answer.

Is there a function that lets me do the same in other bases(bin,oct,hex)?

coolzoa
  • 43
  • 5

2 Answers2

2

If they enter in the values as hex, binary, etc, eval will work:

eval("0xa + 8 + 0b11")
# 21

Beware though, eval can be dangerous.

tom10
  • 67,082
  • 10
  • 127
  • 137
  • Eval is not dangerous when you control the inputs. If the calculator only lever allows the input of numbers via a keypad, eval is perfectly safe. – Bryan Oakley Sep 17 '14 at 10:57
1

No; eval is used to parse Python and the base of numbers in Python code is fixed.

You could use a regex replace to prefix numbers with 0x if you were insistent upon this method, but it would be better to build a parser utilizing, say, int(string, base) to generate the numbers.

If you really want to go down the Python route, here's a token based transformation:

import tokenize
from io import BytesIO

def tokens_with_base(tokens, base):
    for token in tokens:
        if token.type == tokenize.NUMBER:
            try:
                value = int(token.string, base)
            except ValueError:
                # Not transformable
                pass
            else:
                # Transformable
                token = tokenize.TokenInfo(
                    type   = tokenize.NUMBER,
                    string = str(value),
                    start  = token.start,
                    end    = token.end,
                    line   = token.line
                )

        yield token

def python_change_default_base(string, base):
    tokens = tokenize.tokenize(BytesIO(string.encode()).readline)
    transformed = tokens_with_base(tokens, base)
    return tokenize.untokenize(transformed)

eval(python_change_default_base("3*2+1/20", 16))
#>>> 6.03125

0x3*0x2+0x1/0x20
#>>> 6.03125

This is safer because it respects things like strings.

Community
  • 1
  • 1
Veedrac
  • 58,273
  • 15
  • 112
  • 169