I want to write
vol_id = geom.get_owning_volume("surface", 12)
and I have S=12 on the fly during large code execution so I use
S=12
vol_id = geom.get_owning_volume("surface", "%d") %(S)
which gives me an error
TypeError: in method 'get_owning_volume', argument 2 of type 'int'
I have used the variation
S=12
vol_id = geom.get_owning_volume("surface", "%d" %(S))
this gives the same error
why I cannot parse the integer 12 to the desired place! any suggestions?
The % operator is for interpolating into strings, not into Python code. Your example is trying to pass the string "%d" where the function expects a number; no wonder it fails!
In your case, just put the variable S where you need it:
S=12
vol_id = geom.get_owning_volume("surface", S)
From the documentation that I found, get_owning_volume takes a string and an integer, and you already have an integer, so there's no need to convert it:
vol_id = geom.get_owning_volume("surface", S)
From the comments it looks like S is actually a string, and you want an integer, then this should work:
vol_id = geom.get_owning_volume("surface", int(S))
Related
as you know , python is a strongly typed language that does not allow concatenation of type int with str.
As you can see below; As I stated above python does not allow for such operations(concatenation of str with int due to the language's features).
a = 10
b = '20'
print(a + b)
#throws the error **TypeError: unsupported operand type(s) for +: 'int' and 'str'**
But Look into this too:
a = 1
b = '2'
print(f"{a} and {b}")
print("{} and {}".format(a, b))#or this for example
Here I did not converted variable a which has an int type assigned to ; into string, but I can include it in the formatted string
My question is ... what happens under the curtains when python interpreter encounters with this expression print(f"{a} and {b}")
what happens under the curtains when python interpreter encounters with this expression print(f"{a} and {b}")
What happens is that before a and b are built into the string, str(a) and str(b) are called. You can see this yourself when you build 2 classes like this:
class Test1(object):
pass
class Test2(object):
def __str__(self):
return "surprise"
which do the same (nothing) but Test2 returns "surprise" when str(Test2()) is called.
When you want to convince yourself try this:
t1 = Test1()
t2 = Test2()
print(t1)
print(t2)
print(f"{t1}")
print(f"{t2}")
print("{}".format(t1))
print("{}".format(t2))
Each time the same two lines are printed.
This is documented in chapter 2 of Python's documentation:
If a conversion is specified, the result of evaluating the expression is converted before formatting. Conversion '!s' calls str() on the result, '!r' calls repr(), and '!a' calls ascii().
If no conversion is specified, it immediately continues to the following step:
The result is then formatted using the format() protocol. The format specifier is passed to the __format__() method of the expression or conversion result. An empty string is passed when the format specifier is omitted. The formatted result is then included in the final value of the whole string.
The __format__() method then follows the format specifier mini-language syntax to determine the resulting string representation.
In your case the result is the same as calling str() on the variables, but this does not apply to all variables. Based on #Marv's answer, here is a little demonstration to show the difference:
class Test:
def __str__(self):
return "surprise"
def __format__(self, format_spec):
return "test"
t1 = Test()
print(t1)
print(str(t1))
print(f"{t1}")
print("{}".format(t1))
>>> surprise
>>> surprise
>>> test
>>> test
I am trying to write a function which takes two arguments:
an object
a formatter string (as specified in docs)
which then returns a formatted string:
What I tried is sort of:
def my_formatter(x, form):
return str(x).format(form)
What I am expecting is:
s = my_formatter(5, "%2f")
# s = 05
t = my_formatter(5, "%.2")
# t = 5.00
etc...
The format function unfortunately does not work like that. Any ideas?
For that style of formatting you'd have to use the string % values string formatting operation:
def my_formatter(x, form):
return form % x
You'd also have to alter your format; to get 05 you'd have to use "%02d", not "%2f".
You were getting confused by the str.format() method, which uses a different formatting syntax, and you got the arguments swapped; you'd use form.format(x) instead.
You probably want to look into the built-in format() function here; the syntax is slightly different, but offers more features:
>>> format(5, '02d')
'05'
>>> format(5, '.2f')
'5.00'
That's pretty close to what you were already using, minus the %.
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'
From my studying of python, I've found two uses for %. It can be used as what's called a modulo, meaning it will divide the value to the left of it and the value to the right of it and spit back the remainder.
The other use is a string formatter. So I can do something like 'Hi there %s' % name, where name is a list of names.
Also, if you see %% in a string formatting, that means a literal % will be entered.
Here is my question, I found this:
class FormatFormatStr(FormatObj):
def __init__(self, fmt):
self.fmt = fmt
def tostr(self, x):
if x is None: return 'None'
return self.fmt%self.toval(x)
What does return self.fmt%self.toval(x) mean? It can't be a modulo because toval will give me a string. It's not really a string formatter because there isn't another percent sign.
also, related to this:
def csvformat_factory(format):
format = copy.deepcopy(format)
if isinstance(format, FormatFloat):
format.scale = 1. # override scaling for storage
format.fmt = '%r'
return format
What does the percent mean in format.fmt = '%r' does this mean to insert a string a la repr()? Or does it mean insert what the variable r represents? r in this overall program also refers to a recarray.
Thanks everyone. Hope this makes sense =)
The string % operator is simpler than you are imagining. It takes a string on the left side, and a variety of things on the right side. The left side doesn't have to be a literal string, it can be a variable, or the result of another computation. Any expression that results in a string is valid for the left side of the %.
In your first example, self.fmt is a string. In order to be useful in this context, it should have a percent sign in it.
In your second example, format.fmt is being set to a string that would be useful as the left side of the %. In this case, "%r" means, insert the repr() of the value into the string, as you have said.
In
return self.fmt%self.toval(x)
self.fmt is a string, and that string presumably has a percent-sign placeholder in it.
%r in a format string is like %s but it prints the repr() of the string, so it'll have quotes and backslashes and all that.
% is just an operator which is just a method, and like any other method you can either pass in a literal value or a variable containing a value. In your examples they use a variable containing the format string.
def tostr(self, x):
if x is None: return 'None'
return self.fmt%self.toval(x)
The % in this is a string formatter, definitely. Pass the tostr method a formatter, eg "%s" or "%r" to see what happens
I think the '%r' in csvformat_factory is also a string formatter. '%r' means take the repr() which is a reasonable way to display something to a user. I imagine that format.fmt is used elsewhere format.fmt % somevalue.
The code:
return self.fmt % self.toval(x)
Is the "string formatting" use of the % operator, just like you suspected.
The class is handed format, which is a string containing the formatting, and when tostr(x) is called, it will return the string % x.
This is just like using % directly, only with saving the format string for later. In other words, instead of doing:
"I want to print the number: %n" % 20
What's happening is:
format_str = "I want to print the number: %n"
x = 20
print format_str % x
Which is exactly the same thing.
% has more than one use in string formatting. One use is in %s, %d, etc.
Another use is to separate 'string in which we use %d and %s' from int-value and string-value.
For example
'string in which we use %d and %s' % (17, 'blue')
would result in
'string in which we use 17 and blue'
we could store 'string in which we use %d and %s' in a variable,
a = 'string in which we use %d and %s'
then
a % (17, 'blue')
results in
'string in which we use 17 and blue'
In your example
self.fmt%self.toval(x)
self.fmt is similar to a above and self.toval(x) is (17, 'blue')
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('_', '.')