i have a string with 60+ Variables inside and sometimes it throws me an Error: 'must be real number, not str'. While i know what the error means, i donĀ“t know which variable produces it.
Is there a reasonable way to find the trouble making variable?
My actual solution is to split the string up in groups and narrow it down until i find it, but thats quite tedious.
string looks like:
s = "%s bla bla %i some more bla %.2f etc." % \
(test_string, \
test_int, \
test_float)
Thanks for any advice or good ideas.
The error message comes from the %f format operator. %s formats a string, and %i formats an integer.
So you only need to check the variables that correspond to that format. In the example, it's test_float.
You can use this to print the types of all the variables that correspond to %f formats:
for i, v in enumerate([var1, var2, var3]):
if not isinstance(v, float):
print(f"{i} {type(v)}")
This will tell you the indexes in the list of the variables that aren't float.
Related
I'm using python to generate LaTeX code (long story - I need to produce 120-odd unique exams).
This means that I have lots of strings that have \ or { or } etc. So I'm making them literals. However, I also want to have Python calculate numbers and put them in. So I might have a string like:
r"What is the domain of the function $\exp{-1/(VARIABLE - x^2+y^2)}$?" which I want to write to a file. But I want VARIABLE to be a random numerical value. The question isn't how to calculate VARIABLE, but rather is there a clean way to put VARIABLE into the string, without something like:
r"What is the domain of the function $\exp{-1/(" + str(VARIABLE) + r"- x^2+y^2)}$?"
I'm going to be doing this a lot, so if it's doable, that would be great. I've got Python 3.5.2.
Python still supports the string substitution operator %:
r"What is ... $\exp{-1/(%s - x^2+y^2)}$?" % str(VARIABLE)
You can be more specific if you know the type of the variable, e.g.:
r"What is ... $\exp{-1/(%f - x^2+y^2)}$?" % VARIABLE
More than one variable can be substituted at once:
r"$\mathrm{x}^{%i}_{%i}$" % (VAR1, VAR2)
This will work as long as your strings do not have LaTeX comments that, incidentally, also begin with a %. If that's the case, replace % with %%.
You may be able to use the % formatting
variable = 10
"What is the domain of the function $exp{-1/x + %d}." % (variable)
I'm very partial to f-strings, since the variable names appear where the values eventually will.
You can have raw f-strings, but you'll need to escape curly braces by doubling them ({{), which could get confusing if you're writing out complex LaTex.
To get the string What is ... $\exp{-1/(10 - x^2+y^2)}$?:
VARIABLE = 10
rf"What is ... $\exp{{-1/({VARIABLE} - x^2+y^2)}}$?"
If your goal is to not break up the string you could do this to replace the variable with your variable value and also be able to use %s in your string:
r"What is the domain of the function $\exp{-1/(VARIABLE - x^2+y^2)}$?".replace("VARIABLE", str(VARIABLE))
If you need multiple values you can use this:
variable_list = [2, 3]
''.join([e+str(variable_list[c]) if c<len(variable_list) else str(e) for c,e in enumerate(r"What is the domain of the function $\exp{-1/(VARIABLE - x^2+y^2)}$?".split("VARIABLE"))])
I am a beginner and learning Python. My question is python can read a variable in a string without format identifier, then why has format identifiers been provided for?
Ex:
carPoolTotal = 4
print "We have total", carPoolTotal, "people in carpooling."
print "We have total %d people in carpooling." % carPoolTotal
Both works the same thing, then why exactly is identifier introduced in Python?
Format identifiers help if you want to provide non-default formatting for your values. For example, you might want to format a long decimal as a decimal with a maximum of two decimal places.
I know of two ways to format a string:
print 'Hi {}'.format(name)
print 'Hi %s' % name
What are the relative dis/advantages of using either?
I also know both can efficiently handle multiple parameters like
print 'Hi %s you have %d cars' % (name, num_cars)
and
print 'Hi {0} and {1}'.format('Nick', 'Joe')
There is not really any difference between the two string formatting solutions.
{} is usually referred to as "new-style" and %s is "old string formatting", but old style formatting isn't going away any time soon.
The new style formatting isn't supported everywhere yet though:
logger.debug("Message %s", 123) # Works
logger.debug("Message {}", 123) # Does not work.
Nevertheless, I'd recommend using .format. It's more feature-complete, but there is not a huge difference anyway.
It's mostly a question of personal taste.
I use the "old-style" so I can recursively build strings with strings. Consider...
'%s%s%s'
...this represents any possible string combination you can have. When I'm building an output string of N size inputs, the above lets me recursively go down each root and return up.
An example usage is my Search Query testing (Quality Assurance). Starting with %s I can make any possible query.
/.02
I'm reading into a csv file an extracting a piece of data with the line:
x = float(node[1])
when I print(x), I get the correct value or the exact value found in the cell. e.g 153.018848
But when I try to pass x as variable in the following:
print('<node version="0" lon="%d">' %(x))
the output will be <node version="0" lon="153"> . Of course I want the value 153.018848.
What have I overlooked?
Thanks in advance.
You've overlooked the fact that %d is for integers. Try %f instead.
You're using the wrong format flag. %d is for integers, use %f for floats.
You want to replace your %d with %f, problem solved ;)
See: http://docs.python.org/release/2.5.2/lib/typesseq-strings.html
For bonus points, are you aware you can put together long format strings that are still readable using dictionaries? You can read more about it, but the !r option I have used with call the repr() function on the variable, so you know what is inserted will be exactly what you've seen printed in your debugging:
string = """<tagname id=%{idval!r} type=%{tagtype!r} foo=%{bar!r}"""
print string.format( **{'idval':var1, 'tagtype':var2, 'bar':var3})
I was going through http://web2py.com/book/default/chapter/02 and found this:
>>> print 'number is ' + str(3)
number is 3
>>> print 'number is %s' % (3)
number is 3
>>> print 'number is %(number)s' % dict(number=3)
number is 3
It has been given that The last notation is more explicit and less error prone, and is to be preferred.
I am wondering what is the advantage of using the last notation.. will it not have a performance overhead?
>>> print 'number is ' + str(3)
number is 3
This is definitely the worst solution and might cause you problems if you do the beginner mistake "Value of obj: " + obj where obj is not a string or unicode object. For many concatenations, it's not readable at all - it's similar to something like echo "<p>Hello ".$username."!</p>"; in PHP (this can get arbitrarily ugly).
print 'number is %s' % (3)
number is 3
Now that is much better. Instead of a hard-to-read concatenation, you see the output format immediately. Coming back to the beginner mistake of outputting values, you can do print "Value of obj: %r" % obj, for example. I personally prefer this in most cases. But note that you cannot use it in gettext-translated strings if you have multiple format specifiers because the order might change in other languages.
As you forgot to mention it here, you can also use the new string formatting method which is similar:
>>> "number is {0}".format(3)
'number is 3'
Next, dict lookup:
>>> print 'number is %(number)s' % dict(number=3)
number is 3
As said before, gettext-translated strings might change the order of positional format specifiers, so this option is the best when working with translations. The performance drop should be negligible - if your program is not all about formatting strings.
As with the positional formatting, you can also do it in the new style:
>>> "number is {number}".format(number=3)
'number is 3'
It's hard to tell which one to take. I recommend you to use positional arguments with the % notation for simple strings and dict lookup formatting for translated strings.
I can think of a few differences.
First to me is cumbersome, if more than one variable is involved. I can not speak of performance penalty on that. See additional arguments below.
The second example is positional dependent and it can be easy to change position causing errors. It also does not tell you anything about the variables.
The third example, the position of variables is not important. You use a dictionary. This makes it elegant as it does not rely on positional structuring of variables.
See the example below:
>>> print 'number is %s %s' % (3,4)
number is 3 4
>>> print 'number is %s %s' % (4,3)
number is 4 3
>>> print 'number is %(number)s %(two)s' % dict(number=3, two=4)
number is 3 4
>>> print 'number is %(number)s %(two)s' % dict(two=4, number=3)
number is 3 4
>>>
Also another part of discussion on this
"+" is the string concatenation operator.
"%" is string formatting.
In this trivial case, string formatting accomplishes the same result as concatenation. Unlike string formatting, string concatenation only works when everything is already a string. So if you miss to convert your variables to string, concatenation will cause error.
[Edit: My answer was biased towards templating since the question came from web2py where templates are so commonly involved]
As Ryan says below, the concatenation is faster than formatting.
Suggestion is
Use the first form - concatenation, if you are concatenating just two strings
Use the second form, if there are few variables. You can invariably see the positions and deal with them
Use the third form when you are doing templating i.e. formatting a large piece of string with variable data. The dictionary form helps in providing meaning to variables inside the large piece of text.
I am wondering what is the advantage
of using the last notation..
Hm, as you said, the last notation is really more explicit and actually is less error prone.
will it not have a performance
overhead?
It will have little performance overhead, but it's minor if compared with data fetching from DB or network connections.
It's a bad, unjustified piece of advice.
The third method is cumbersome, violates DRY, and error prone, except if:
You are writing a framework which don't have control over the format string. For example, logging module, web2py, or gettext.
The format string is extremely long.
The format string is read from a file from a config file.
The problem with the third method should be obvious when you consider that foo appears three times in this code: "%(foo)s" % dict(foo=foo). This is error prone. Most programs should not use the third method, unless they know they need to.
The second method is the simplest method, and is what you generally use in most programs. It is best used when the format string is immediate, e.g. 'values: %s %s %s' % (a, b, c) instead of taken from a variable, e.g. fmt % (a, b, c).
The first concatenation is almost never useful, except perhaps if you're building list by loops:
s = ''
for x in l:
s += str(x)
however, in that case, it's generally better and faster to use str.join():
s = ''.join(str(x) for x in l)