So I am new to Julia and learned various ways of string formatting. Mainly from websites similar to this.
So I use f-strings a lot in Python, not a big fan of .format(). So I was wondering since someone created Formatting.jl Package to bring .format() like feature in Julia, is there any ongoing or useful package which does same for f-strings? Now I googled a bit about it too but didn't find anything.
What my main issue is that I want to replicate this behaviour:
a = 10
b = 20
print(f'The multiplication is = {a * b}')
In case anyone wondering what are f-strings, refer to this.
Yes, it is possible with standard Julia strings:
x = "World!"
y = 42
greeting = "Hello $x, $(y^2) !" # gives "Hello World!, 1764 !"
See also here:
https://docs.julialang.org/en/v1/manual/strings/#string-interpolation
Edit:
The example in the comment above is
j = 10; b = 20
println("The numbers and their square are $j, $b and $(j^2), $(b^2)")
There are multiple packages, of which the least well known but my favourite is PyFormattedStrings.jl.
Compare:
Package
Syntax
PyFormattedStrings.jl
f"Our yield is {harvest(crop):.3G} kg."
Fmt.jl
f"Our yield is {$(harvest(crop)):.3G} kg."
Formatting.jl
fmt("Our yield is {:.3f} kg.", harvest(crop))
(Note that Formatting has no g/G support).
PyFormattedStrings.jl uses the printf syntax, so eg aligning right is done with {var:20g}, and not {var:>20g} as in Python. Fmt.jl does use the Python syntax.
Neither package supports the f"{4+4=}" syntax of Python 3.8. (Though Julia has #show).
If you want more control over numeric formatting than the default string interpolation, you can use the Formatting.jl package in Julia, which provides Python f-string functionality.
Related
I have received a python notebook that is full of expressions like f"{expr=}" that in my environment produce error messages:
var=7
print(f"{var=}")
File "<fstring>", line 1
(var=)
^
SyntaxError: invalid syntax
I suspect/expect that it could be in fact a new syntax for f"expr={expr}", i.e. as in the following print statement:
print(f"var={var}")
var=7
In fact I often use expressions like the latter for debug, and it would be nice to have a shorthand for it.
Is that a higher version of python than mine (3.7.6)? Or is it a customization of the fstring module?
Searching for it on the web or in SE was not productive.
And if it is not a standard feature, how can I get it to work?
Answer - Python Version 3.8
f-strings simplified a lot of places where str.format and % style formatting. There was still a place where you want to print a value of the variable or expression and also add some context with the string like variable name or some arbitrary name so that when you have many statements you can differentiate between the printed values. So using variable name followed by value is more common format of print style debugging.
Blockquote
This caused users to write f"name = {name}" and can get unwieldy when
variable names are long like filtered_data_from_third_party would be
written as f"filtered_data_from_third_party =
{filtered_data_from_third_party}". In those cases we resort to shorter
names we understand easily at the context like f"filtered data
{filtered_data_from_third_pary}". f-strings also support format
specifiers so you can write f"{name!r}" which is same as
f"{repr(name)}".
Given the above boilerplate an idea was posted in python-ideas around
a format specifier where you can use it and the f-string would expand
like a macro into <variable_name> = <value_of_variable>. Initially !d
was chosen so f"{name!d}" would expand to f"name={repr(name)}". This
was initially implemented in bpo36774. After discussion !d was changed
to use = with input from Guido and other core devs since there could
be usecases served by !d in the future and to reserve alphabetical
names in format-string for other uses. So this was changed to use = as
the notation for this feature in bpo36817. An overview of it’s usage
is as below with various features available.
Read more here
This feature was discussed in Python issue 36817 and released in Python 3.8.
I want to insert commas into large integers for printing.
julia> println(123456789) # Some kind of flag/feature inserts commas.
"123,456,789"
In Python 3.6+ this is easy to do:
>>> print(f"{123456789:,d}")
123,456,789
However, it does not appear that the standard Julia print/println functions have this feature at the present time. What can I do using just the print/println functions?
I guess the most straightforward way in some languages would be to use the ' format modifier in printf. I Julia this WOULD look like so:
using Printf # a stdlib that ships with julia which defines #printf
#printf "%'d" 12345678
However, unfortunately, this flag is not yet supported as you can see from the error you'll get:
julia> #printf "%'d" 12345678
ERROR: LoadError: printf format flag ' not yet supported
If you like this feature, maybe you should think about adding it to the Printf stdlib so that everyone would benefit from it. I don't know how difficult this would be though.
UPDATE: Note that although the macro is defined in stdlib Printf, the error above is explicitly thrown in Base/printf.jl:48. I also filed an issue here
Here is a function based on a Regex from "Regular Expressions Cookbook," by Goyvaerts and Levithan, O'Reilly, 2nd Ed, p. 402, that inserts commas into integers returning a string.
function commas(num::Integer)
str = string(num)
return replace(str, r"(?<=[0-9])(?=(?:[0-9]{3})+(?![0-9]))" => ",")
end
println(commas(123456789))
println(commas(123))
println(commas(123456789123456789123456789123456789))
""" Output
123,456,789
123
123,456,789,123,456,789,123,456,789,123,456,789
"""
With an f-string you can fill in 'placeholders' in a string directly with some variable value. Opposed to, let's say using the str.format() method, often seen.
Example:
In [1]: x=3
In [2]: y=4
In [3]: print(f'The product of {x} and {y} is {x*y}.')
The product of 3 and 4 is 12.
Is this concept of f-strings only found in python? Or is there any other language that supports this, maybe under a different name?
Short answer: No - not unique to python. In python it was introduced with 3.6 by Literal String Interpolation - PEP 498
In C# there is $ - string interpolation as shorthand for some function you would use String.Format for:
string val = "similar";
string s = $"This is {val}" // s == "This is similar"
// vs.
var s2 = string.Format ("This is {0}", val); // {0} = 0th param that follows
You can find it under the name of Template Literals in Javascript as well. In particular, see the section Expression Interpolation for an example similar as the one in OP's question.
The shell: Starting in the Dark Ages shells used to expand parameters in double quoted strings (and unquoted arguments too).
Perl: Perl has a shellish side, and had interpolation in double quoted strings from at least the time I bought the 1st edition of the Camel book and started learning the language.
I think that other people may be more specific on the precise date of introduction of string interpolation in Perl, but I suspect it was there from the beginning.
Many other programming languages, especially those using sigils, share this concept of interpolation.
anyone could help me with python trying to use NET use, I don't know the diferences between / in python and perl, because code in perl works
$runMap = "C:\\Windows\\System32\\net.exe use \\\\$ip\\D\$ /persistent:no /user:$user_name $passwd";
system($runMap);
But in Python 3 don't work
os.system("C:/Windows/System32/net.exe use Z: \\\\ip/D:/ /persistent:no /user:user pass")
Perl is using interpolation, that is, it is possible to embed variables inside a double quoted string, since Perl 5 interpolated variables start with a $ or a # marker. In your case you are embedding $user_name and $passwd.
Python variable names are not prefixed by a "magic character" (sigil), so you cannot embed them inside strings except by using formatting statements. There are a couple of regimes, here is one which is a similar idea to printf:
cmd = "C:/Windows/System32/net.exe use Z: \\\\ip/D:/ /persistent:no /user:%s %s" % (username, passwd)
os.system(cmd)
As an ex-Perlmonger I missed interpolation so much I wrote a Python module to support it. While I learnt a lot about Python doing it, it was otherwise a waste of time. Python programming is a different style, you don't need interpolation any more.
By the way, unlike Perl's system(), Python's os.system() will always spawn a shell (as does C's). Therefore it is generally considered to be deprecated. The subprocess.Popen() method gives much more control.
EDIT:
With the advent of Python 3.6 and Literal String Interpolation (specified in PEP 498) - more commonly known as f-strings - my original post needs another way to do it.
Single or double quotes may be used, even triple quotes. Basically we just put the Python expression, commonly a variable, inside braces (similar to Ruby).
So, for example:
os.system(f"C:/Windows/System32/net.exe use Z: \\\\ip/D:/ /persistent:no /user:{username} {passwd}")
The comment about subprocess.Popen() is also out of date, since Python 3.5 the preferred interface is now subprocess.run().
I would like to do some simple math while I'm doing string formatting. For example
N = {'number':3}
four = '{number:d + 1}'.format(**N)
This doesn't work (of course). Is there a way to accomplish this that I'm not aware of?
Thanks!
"Is there a way to accomplish this that I'm not aware of?" If by "this" you mean encoding some mathematical logic in the format string using str.format, then no -- not that I'm aware of. However if you use a templating language you can express all kinds of stuff like this.
There are a billion different options for templating languages in Python, so rather than try to say which is best, I'll let you decide. See this article from the Python wiki: http://wiki.python.org/moin/Templating
A favorite of mine is Jinja2, although it's probably overkill for what you're talking about.
Here's an example of how to accomplish what you're after with Jinja2:
N = { 'd' : 3 }
four = Template(u'number:{{ d + 1 }}').render(**N)
The main advantage to a templating system like Jinja2 is that it allows you store templates as files separate from your application control logic such that you can maintain the view/presentation logic for your program in a way that limits or prohibits side effects from presentation execution.
About as close as you can get is to use positional arguments instead of keyword arguments:
four='{0:d}'.format(N['number']+1)
or the shorter old-school:
four='%d'%(N['number']+1)
What's your goal here?