2

I have to accept input (using raw_input()) as a power expression like 10**5 and then print its value. I have tried a few pieces of code but these do not give desired results:

print(f'{2**4}') #<-- prints 16 correctly
a = '{2**4}'
print(f'{{}}'.format(a)) #<-- prints {2**4}

Is it possible to achieve something like:

var = '2**4'
print(f'{<some way to expand var in here>}') #<-- prints 16
wim
  • 302,178
  • 90
  • 548
  • 690
tinker-tailor
  • 4,813
  • 6
  • 41
  • 78

2 Answers2

3

In f-strings expressions are parsed with the equivalent of:

ast.parse('(' + expression + ')', '<fstring>', 'eval')

see https://docs.python.org/3/library/ast.html#ast.parse

But variables will be replaced with their actual value. What are you looking for is sort of a nested evaluation which is not supported by f-strings. Instead as a safe approach you can first split with '**' then covert to int and finally use power:

In [9]: s = "2**4"

In [10]: print(f"{pow(*map(int, s.split('**')))}")
16
Mazdak
  • 100,514
  • 17
  • 155
  • 179
  • It does in this case yes, but in case of other operators or expression chains it won't e.g. `print(f'{2**4}') a = '((2+4-10+88*2)/100)**5' print(eval ('f"{'+a+'}"'))` – tinker-tailor May 07 '18 at 07:52
  • @BabyGroot In that case take a look at answers here https://stackoverflow.com/questions/2371436/evaluating-a-mathematical-expression-in-a-string?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa – Mazdak May 07 '18 at 07:54
  • Yes but most solutions require importing some module - `eval` and `extrapolation` is built into python - thanks anyways (+1) – tinker-tailor May 07 '18 at 07:58
  • @BabyGroot As it's also mentioned in many of those answers don't use `eval` on user input data. NEVER! – Mazdak May 07 '18 at 08:06
  • Yes i saw that - that's why i was wondering if we could just `int()` with builtin support – tinker-tailor May 07 '18 at 08:10
1

So this works for all expressions (e.g. ((2+4-10+88*2)/100)**5) but I am not sure if this is the right way to go (since eval is not recommended)

a = '2**4'
print(eval (a))  #<-- prints 16
tinker-tailor
  • 4,813
  • 6
  • 41
  • 78