String to Int conversion in python - python

If I have a string "2+3", is there anyway to convert it to an integer so it comes out as 5?
I tried this:
string = 2+3
answer = int(string)
But I get an error:
ValueError: invalid literal for int() with base 10: '2+3'
I'm trying to take a fully parenthesized equation and use stacks to answer it.
ex. Equation = ((2+3) - (4*1))
I tried taking the equation as an input, but python just solves it on its own.
So to avoid that problem, I took the equation as a raw_input.

There is one way, eval function..
>>> x = raw_input()
2 + 6
>>> x
'2 + 6'
>>> eval(x)
8
But be sure to verify that the input only has numbers,and symbols.
>>> def verify(x):
for i in x:
if i not in '1234567890.+-/*%( )':
return False
return True
>>> x = raw_input()
2 + 6
>>> x
'2 + 6'
>>> if verify(x):
print eval(x)
8
ast.literal_eval doesn't work:
>>> ast.literal_eval('2+3')
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
ast.literal_eval('2+3')
File "C:\Python2.7 For Chintoo\lib\ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "C:\Python2.7 For Chintoo\lib\ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string

Use eval (and remember to sanitize your input. More on this if you read the docs):
>>> eval('2+3')
5
It even supports variables:
>>> x = 1
>>> eval('x+1')
2

Related

Can't get my input value to be used in the subsequent calculation in Python [duplicate]

If I try to do the following:
things = 5
print("You have " + things + " things.")
I get the following error in Python 3.x:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
... and a similar error in Python 2.x:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
How can I get around this problem?
The problem here is that the + operator has (at least) two different meanings in Python: for numeric types, it means "add the numbers together":
>>> 1 + 2
3
>>> 3.4 + 5.6
9.0
... and for sequence types, it means "concatenate the sequences":
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
>>> 'abc' + 'def'
'abcdef'
As a rule, Python doesn't implicitly convert objects from one type to another1 in order to make operations "make sense", because that would be confusing: for instance, you might think that '3' + 5 should mean '35', but someone else might think it should mean 8 or even '8'.
Similarly, Python won't let you concatenate two different types of sequence:
>>> [7, 8, 9] + 'ghi'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
Because of this, you need to do the conversion explicitly, whether what you want is concatenation or addition:
>>> 'Total: ' + str(123)
'Total: 123'
>>> int('456') + 789
1245
However, there is a better way. Depending on which version of Python you use, there are three different kinds of string formatting available2, which not only allow you to avoid multiple + operations:
>>> things = 5
>>> 'You have %d things.' % things # % interpolation
'You have 5 things.'
>>> 'You have {} things.'.format(things) # str.format()
'You have 5 things.'
>>> f'You have {things} things.' # f-string (since Python 3.6)
'You have 5 things.'
... but also allow you to control how values are displayed:
>>> value = 5
>>> sq_root = value ** 0.5
>>> sq_root
2.23606797749979
>>> 'The square root of %d is %.2f (roughly).' % (value, sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> 'The square root of {v} is {sr:.2f} (roughly).'.format(v=value, sr=sq_root)
'The square root of 5 is 2.24 (roughly).'
>>> f'The square root of {value} is {sq_root:.2f} (roughly).'
'The square root of 5 is 2.24 (roughly).'
Whether you use % interpolation, str.format(), or f-strings is up to you: % interpolation has been around the longest (and is familiar to people with a background in C), str.format() is often more powerful, and f-strings are more powerful still (but available only in Python 3.6 and later).
Another alternative is to use the fact that if you give print multiple positional arguments, it will join their string representations together using the sep keyword argument (which defaults to ' '):
>>> things = 5
>>> print('you have', things, 'things.')
you have 5 things.
>>> print('you have', things, 'things.', sep=' ... ')
you have ... 5 ... things.
... but that's usually not as flexible as using Python's built-in string formatting abilities.
1 Although it makes an exception for numeric types, where most people would agree on the 'right' thing to do:
>>> 1 + 2.3
3.3
>>> 4.5 + (5.6+7j)
(10.1+7j)
2 Actually four, but template strings are rarely used, and are somewhat awkward.
Other Resources:
Real Python: Splitting, Concatenating, and Joining Strings in Python
Python.org: string - Common string operations
python string concatenation with int site:stackoverflow.com

How to take input in array in python 3

I was trying to pass input into an array but it throws an error.
I already defined the value type in the array. I assigned the array with 'i' and also passed the int type value.
>>> import array as arr
>>> a = arr.array('i', [int(input())])
print(a)
Here's the error that I'm getting:
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
a = arr.array('i', [int(input())])
ValueError: invalid literal for int() with base 10: 'print(a)'
You're typing this into a REPL environment, so each time you type a line, it runs (more or less), so when you enter the line:
a = arr.array('i', [int(input())])
The line after that is expecting the input for input, not the next line of code. Because you then type print(a) you're passing the value "print(a)" to int, essentially:
a = arr.array('i', [int("print(a)")])
Obviously "print(a)" is not a base 10 number so int is failing because "p" is not a character in base 10 (the digits 0 to 9 are the only valid digits).
To resolve this you need to pass a value for the input before continuing with your code:
>>> import array as arr
>>> a = arr.array('i', [int(input())])
5
>>> print(a)
array('i', [5])

format value that could be number and/or string in python 3

Is there a concise way of formatting a number, that on occasion can also be a string?
The number would normally be a float, but occasionally it's also denoted as the string "n/a".
I would like to format the float with a fixed number of decimals, but print the entire string in case it is not a number.
For instance:
var=3.145623
print("This is {0:.2f}".format(var))
>>>This is 3.14
,but
var = "n/a"
print("This is {0:.2f}".format(var))
>>> File "<stdin>", line 1, in <module>
>>> ValueError: Unknown format code 'f' for object of type 'str'
I am not surprised by the ValueError, but wonder if there is a concise way around it, ideally without an explicit if-statement.
Indeed, the f format specifier only works on actual float values. You can't avoid having to special-case your n/a value.
You can format the float separately, and conditionally, then interpolate the result into the larger template:
var_formatted = format(var, '.2f') if var != 'n/a' else var
print("This is {0:4}".format(var_formatted))
If you are really averse to if, you can use exception handling too:
try:
var_formatted = format(var, '.2f')
except ValueError:
var_formatted = 'n/a'
print("This is {0:4}".format(var_formatted))
Another option would be for you to wrap the value in a class with a __format__ method:
class OptionalFloat(object):
def __init__(self, value):
self.value = value
def __format__(self, fmt):
try:
return self.value.__format__(fmt)
except ValueError:
return self.value
print("This is {0:.2f}".format(OptionalFloat(var)))
This moves the requirement to detect the type into another class method, keeping your output code a little cleaner and free of all those pesky conditionals or exception handlers:
>>> var = 3.145623
>>> print("This is {0:.2f}".format(OptionalFloat(var)))
This is 3.15
>>> var = 'n/a'
>>> print("This is {0:.2f}".format(OptionalFloat(var)))
This is n/a
Python supports not-a-number as float('nan') and it may be more useful than the string "n/a" in your code. It works with formatting and produces more sane results than a string if you use it in computations.
NaN:
>>> n = float('nan')
>>> n
nan
>>> "{0:.2f}".format(n)
'nan'
>>> n == 3
False
>>> n * 2
nan
>>> n < 5
False
String:
>>> n = 'n/a'
>>> "{0:.2f}".format(n)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'f' for object of type 'str'
>>> n == 3
False
>>> n * 2
'n/an/a'
>>> n < 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()
maybe something like this
str = "{0:.2f}".format(var) if isinstance(var, float) else var
print(str)

How to check if a string represents a float number

I'm using this to check if a variable is numeric, I also want to check whether it's a floating point number.
if(width.isnumeric() == 1)
The easiest way is to convert the string to a float with float():
>>> float('42.666')
42.666
If it can't be converted to a float, you get a ValueError:
>>> float('Not a float')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: 'Not a float'
Using a try/except block is typically considered the best way to handle this:
try:
width = float(width)
except ValueError:
print('Width is not a number')
Note you can also use is_integer() on a float() to check if it's an integer:
>>> float('42.666').is_integer()
False
>>> float('42').is_integer()
True
def is_float(string):
try:
return float(string) and '.' in string # True if string is a number contains a dot
except ValueError: # String is not a number
return False
Output:
>> is_float('string')
>> False
>> is_float('2')
>> False
>> is_float('2.0')
>> True
>> is_float('2.5')
>> True
Here another solution without "try" and which is returning a truth-value directly. Thanks to #Cam Jackson. I found this solution here: Using isdigit for floats?
The idea is to remove exactly 1 decimal point before using isdigit():
>>> "124".replace(".", "", 1).isdigit()
True
>>> "12.4".replace(".", "", 1).isdigit()
True
>>> "12..4".replace(".", "", 1).isdigit()
False
>>> "192.168.1.1".replace(".", "", 1).isdigit()
False

Python format with variable digits count

So, I can do:
>>> '%.4x' % 0x45f
'045f'
But I need to pass 4 from variable, smth like
>>> digits=4
>>> '%.'+str(digits)+'x' % 0x45f
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
The % operator has a higher precedence than +, so you need to put the first part in parenthesis:
>>> digits = 4
>>> ('%.'+str(digits)+'x') % 0x45f
'045f'
>>>
Otherwise, 'x' % 0x45f will be evaluated first.
However, the modern approach is to use str.format for string formatting operations:
>>> digits = 4
>>> "{:0{}x}".format(0x45f, digits)
'045f'
>>>

Categories