convert string to int? - python

Working on a letter-guessing game.
Why is it that in the following example, when I hardcode the value of the variable, "userGuessPosition" to 2, the code works as expected.
secretWord = ('music')
userGuessPosition = 2
slice1 = (secretWord.__len__()) - userGuessPosition - 1
print (secretWord[slice1:userGuessPosition])
But when I rely on the input() function and type in 2 at the prompt, nothing happens?
secretWord = ('music')
userGuessPosition = 0
userGuessPosition == input()
slice1 = (secretWord.__len__()) - userGuessPosition - 1
print (secretWord[slice1:userGuessPosition])
I assume this is because my keyboard input of "2" is being seen as a string and not an integer. If this is the case, then I'm unclear on the proper syntax to convert it.

userGuessPosition = int(input())
(Single =; int converts a string to an int)

The problem is not that the input is recognized as a string, but rather in the syntax: you're doing a comparison operation where you should be doing an assignment operation.
You have to use
userGuessPosition = input()
instead of
userGuessPosition == input()
The input() function actually does convert the input number into the most appropriate type, sp that should not be an issue. If however you need to convert a string (say, my_string) to an integer, all you need to do is my_int = int(my_string).
EDIT
As mentioned below by #HenryKeiter, depending on your Python version, you may in fact need to convert the return value of input() to an integer by hand, since raw_input() (which always takes in the input as a string) was renamed to input() in Python 3.

Related

How to read inputs separated by spaces in python, as different data types dynamically preferably onto a List?

Is there a way to insert first input as str the next input as int and the next as float onto a list. Assuming the three inputs are separated by spaces are taken as input.
data = map(str,int,float,input.split()) # Something like this, I know the syntax here is wrong
You can do it simply:
task = input().split()
task[1] = int(task[1])
task[2] = float(task[2])
or in a more convoluted way:
task = [ f(x) for (f, x) in zip([str, int, float], input().split()) ]
Yup, you can do this. Try this:
>>> task = input().split()
hello 3 42.3
>>> task # task is a list of strings
['hello', '3', '42.3']
# get the 3 parts of task
>>> string = task[0]
>>> int = int(task[1])
>>> float = float(task[2])
>>> string, int, float
('hello', 3, 42.3)
There isn't some already available way to do it but you can write your own function for it; such as this:
def my_input(data_types):
user_input = input()
split_user_input = user_input.split()
converted_input_tokens = []
for input_token, data_type in zip(split_user_input, data_types):
converted_input_tokens.append(data_type(input_token))
return converted_input_tokens
It will do exactly(no more, no less) what you showed in the example you gave. You can use it this way:
>>> my_input((str, int, float))
1 2 3
Which will return:
['1', 2, 3.0]
It can be made much more generic, of course. For example, you could add arguments for the input prompt, the sep and maxsplit for the str.split method used in the function, etc.
If you are in doubt about how to do that, have a look at the official documentation for input, str.split and also do some research on type-conversions in Python.
you can explicitly define each input as particular type.

python isdigit() returning unexpected result

I'm making a basic BMI calculation program for a class assignment using TKinter for the GUI, and ran into a problem when trying to validate the user's input.
I'm trying to only allow numerical input and to deactivate the 'calculate' button and send an error message when the user enters anything that's not a number. However, at the minute it will throw up an error for a single digit number (e.g. 2) but will accept multiple digits (e.g. 23). I'm quite new to this so could you please explain why this is happening, or if there's a better way to write this?
Here are the relevant parts of my code:
#calculate button
cal = ttk.Button(main, text = 'Calculate!')
cal.grid(row = 4, column = 2)
#height entry box
hb = tk.Entry(main, textvariable = height)
hb.grid(row = 2, column = 2)
hb.bind('<Key>', lambda event: val(hb.get()))
#validation error message
vrs = tk.Label(main, text = 'Please enter a number in the box')
vrs.grid(row = 8, column = 2)
#so that its position is saved but won't appear until validation fails
vrs.grid_remove()
#validation function
def val(value):
if value.isdigit():
print('valid')
vrs.grid_remove()
cal.state(['!disabled'])
else:
print('invalid')
vrs.grid()
cal.state(['disabled'])
Thanks in advance for your help.
The first thing you should do to debug this is to print out value inside of val, to see if your assumptions are correct. Validating your assumptions is always the first step in debugging.
What you'll find is that your function is being called before the digit typed by the user is actually inserted into the widget. This is expected behavior.
The simple solution is to put your binding on <KeyRelease>, since the default behavior of inserting the character is on <KeyPress>:
hb.bind('<Any-KeyRelease>', lambda event: val(hb.get()))
Even better would be to use the Entry widget's built-in validation features. For an example, see https://stackoverflow.com/a/4140988/7432
You need to use isdigit on strings.
val = '23'
val.isdigit() # True
val = '4'
val.isdigit() # True
val = 'abc'
val.isdigit() # False
If you're not sure what the type of the input is, cast it first to a string before calling isdigit().
If you want only one-digit numbers, you'll have to check if int(val) < 10
isdigit is a string method. Are you expecting a string, an int, or a float?
You can add some typechecking code like this, so that your program validates regardless of whether the value is a numerical type or a string type.
def val(value):
if type(value) in (int, float):
# this is definitely a numerical value
elif type(value) in (str, unicode, bytes):
# this is definitely a string

Python defined functions doesn't work properly

Hi so my school is doing an RPG project on python, and i have encountered a problem where i define my own functions, and needs to call one of them inside another, and it doesn't work. The following code for example:
from characters1 import *
def printmana(typeofenemy):
print typeofenemy.mana
def printmany(typeofenemy):
print typeofenemy.damage
print typeofenemy.health
option = raw_input("Type something ")
if option == 1:
printmana(typeofenemy)
printmany(Goblin)
when i call printmany(Goblin), everything goes fine until i type in 1, where i expect it to call printmana(Goblin) and print Goblin.mana, but it doesn't. Yet when i call printmana(Goblin) separately, it works absolutely fine. I also tried this:
from characters1 import *
def printmana(typeofenemy):
return (typeofenemy.mana)
def printmany(typeofenemy):
print typeofenemy.damage
print typeofenemy.health
option = raw_input("Type something ")
if option == 1:
print (printmana(typeofenemy))
printmana(Goblin)
Where i thought i change the print in printmana as return, and call the print printmana(Goblin) in the second function, yet it still doesn't work when i type in 1. There must be some thing i don't yet understand about the nature of python functions, so can someone please explain why is my example code not working? Thank you!
Your trouble is that you're comparing the output of raw_input (a string) with an integer. Try one of the following:
if option == "1":
...
or
if int(option) == 1:
...
Option is a string in this code:
>>> option = raw_input("Type something ")
Type something 1
>>> print option
1
>>> print type(option)
<type 'str'>
>>> print option == 1
False
>>> print option == "1"
True
So you need change the if to:
if option == "1":
raw_input doesn't cast the value to an integer. You could compare option to a string, i.e:
if option == '1':
Or you could convert option to an int, i.e.:
option = int(option)
Be aware that the second choice has some interesting gotchas if the value can't be converted to an int.
You set the variable "option" to become whatever the user types in. If the user types '1' and hits return, "option" will hold the string value, '1'. So, the issue is in your "if" statement, where you compare a string and a integer.

Python: Capitalize a word using string.format()

Is it possible to capitalize a word using string formatting? For example,
"{user} did such and such.".format(user="foobar")
should return "Foobar did such and such."
Note that I'm well aware of .capitalize(); however, here's a (very simplified version of) code I'm using:
printme = random.choice(["On {date}, {user} did la-dee-dah. ",
"{user} did la-dee-dah on {date}. "
])
output = printme.format(user=x,date=y)
As you can see, just defining user as x.capitalize() in the .format() doesn't work, since then it would also be applied (incorrectly) to the first scenario. And since I can't predict fate, there's no way of knowing which random.choice would be selected in advance. What can I do?
Addt'l note: Just doing output = random.choice(['xyz'.format(),'lmn'.format()]) (in other words, formatting each string individually, and then using .capitalize() for the ones that need it) isn't a viable option, since printme is actually choosing from ~40+ strings.
As said #IgnacioVazquez-Abrams, create a subclass of string.Formatter allow you to extend/change the format string processing.
In your case, you have to overload the method convert_field
from string import Formatter
class ExtendedFormatter(Formatter):
"""An extended format string formatter
Formatter with extended conversion symbol
"""
def convert_field(self, value, conversion):
""" Extend conversion symbol
Following additional symbol has been added
* l: convert to string and low case
* u: convert to string and up case
default are:
* s: convert with str()
* r: convert with repr()
* a: convert with ascii()
"""
if conversion == "u":
return str(value).upper()
elif conversion == "l":
return str(value).lower()
# Do the default conversion or raise error if no matching conversion found
return super(ExtendedFormatter, self).convert_field(value, conversion)
# Test this code
myformatter = ExtendedFormatter()
template_str = "normal:{test}, upcase:{test!u}, lowcase:{test!l}"
output = myformatter.format(template_str, test="DiDaDoDu")
print(output)
You can pass extra values and just not use them, like this lightweight option
printme = random.choice(["On {date}, {user} did la-dee-dah. ",
"{User} did la-dee-dah on {date}. "
])
output = printme.format(user=x, date=y, User=x.capitalize())
The best choice probably depends whether you are doing this enough to need your own fullblown Formatter.
You can create your own subclass of string.Formatter which will allow you to recognize a custom conversion that you can use to recase your strings.
myformatter.format('{user!u} did la-dee-dah on {date}, and {pronoun!l} liked it. ',
user=x, date=y, pronoun=z)
In python 3.6+ you can use fstrings now. https://realpython.com/python-f-strings/
>>> txt = 'aBcD'
>>> f'{txt.upper()}'
'ABCD'

Convert integer to string in Python

How do I convert an integer to a string?
42 ⟶ "42"
For the reverse, see How do I parse a string to a float or int?. Floats can be handled similarly, but handling the decimal points can be tricky because floating-point values are not precise. See Converting a float to a string without rounding it for more specific advice.
>>> str(42)
'42'
>>> int('42')
42
Links to the documentation:
int()
str()
str(x) converts any object x to a string by calling x.__str__(), or repr(x) if x doesn't have a __str__() method.
Try this:
str(i)
There is no typecast and no type coercion in Python. You have to convert your variable in an explicit way.
To convert an object into a string you use the str() function. It works with any object that has a method called __str__() defined. In fact
str(a)
is equivalent to
a.__str__()
The same if you want to convert something to int, float, etc.
To manage non-integer inputs:
number = raw_input()
try:
value = int(number)
except ValueError:
value = 0
>>> i = 5
>>> print "Hello, world the number is " + i
TypeError: must be str, not int
>>> s = str(i)
>>> print "Hello, world the number is " + s
Hello, world the number is 5
For Python 3.6, you can use the f-strings new feature to convert to string and it's faster compared to str() function. It is used like this:
age = 45
strAge = f'{age}'
Python provides the str() function for that reason.
digit = 10
print(type(digit)) # Will show <class 'int'>
convertedDigit = str(digit)
print(type(convertedDigit)) # Will show <class 'str'>
For a more detailed answer, you can check this article: Converting Python Int to String and Python String to Int
In Python => 3.6 you can use f formatting:
>>> int_value = 10
>>> f'{int_value}'
'10'
>>>
The most decent way in my opinion is ``.
i = 32 --> `i` == '32'
You can use %s or .format:
>>> "%s" % 10
'10'
>>>
Or:
>>> '{}'.format(10)
'10'
>>>
For someone who wants to convert int to string in specific digits, the below method is recommended.
month = "{0:04d}".format(localtime[1])
For more details, you can refer to Stack Overflow question Display number with leading zeros.
With the introduction of f-strings in Python 3.6, this will also work:
f'{10}' == '10'
It is actually faster than calling str(), at the cost of readability.
In fact, it's faster than %x string formatting and .format()!
There are several ways to convert an integer to string in python.
You can use [ str(integer here) ] function, the f-string [ f'{integer here}'], the .format()function [ '{}'.format(integer here) and even the '%s'% keyword [ '%s'% integer here]. All this method can convert an integer to string.
See below example
#Examples of converting an intger to string
#Using the str() function
number = 1
convert_to_string = str(number)
print(type(convert_to_string)) # output (<class 'str'>)
#Using the f-string
number = 1
convert_to_string = f'{number}'
print(type(convert_to_string)) # output (<class 'str'>)
#Using the {}'.format() function
number = 1
convert_to_string = '{}'.format(number)
print(type(convert_to_string)) # output (<class 'str'>)
#Using the '% s '% keyword
number = 1
convert_to_string = '% s '% number
print(type(convert_to_string)) # output (<class 'str'>)
Here is a simpler solution:
one = "1"
print(int(one))
Output console
>>> 1
In the above program, int() is used to convert the string representation of an integer.
Note: A variable in the format of string can be converted into an integer only if the variable is completely composed of numbers.
In the same way, str() is used to convert an integer to string.
number = 123567
a = []
a.append(str(number))
print(a)
I used a list to print the output to highlight that variable (a) is a string.
Output console
>>> ["123567"]
But to understand the difference how a list stores a string and integer, view the below code first and then the output.
Code
a = "This is a string and next is an integer"
listone=[a, 23]
print(listone)
Output console
>>> ["This is a string and next is an integer", 23]
You can also call format():
format(42) # 42 --> '42'
If you want to add a thousands separator:
num = 123456789
format(num, ",") # '123,456,789'
f"{num:,}"
"{:,}".format(num)
or to convert to string representation of floats
format(num, ",.2f") # '123,456,789.00'
f"{num:,.2f}"
'{:,.2f}'.format(num)
For a "European" separator:
format(num, "_.2f").replace('.', ',').replace('_', '.') # '123.456.789,00'
f"{num:_.2f}".replace('.', ',').replace('_', '.')
"{:_.2f}".format(num).replace('.', ',').replace('_', '.')

Categories

Resources