Python operator precedence when concatenating adjacent string literals - python

The docs say that two string literals that are next to each other are concatenated. For example:
>>>print("py" "thon")
python
However, this feature is implemented at compile time instead of runtime like the + and * operators, so this interesting effect occurs:
>>>print(2 * "py" + "thon")
pypython
>>>print(2 * "py" "thon")
pythonpython
I understand why this happens in the language, but I can't think of a reason for it to be that way. Is there a reason, or was it just easier to leave it alone?

Quite frankly, If I were to design python today, I would make
print ("py" "thon")
A syntax error
Same as
print (5 3)
I would guess that the reason for concatenating adjacent strings, is for consistency with bash / perl
echo "py""thon"

Related

What is the difference between using eval(*code*) and just *code*?

What is the difference between:
cerebro.addsizer(bt.sizers.FixedSize, **eval('dict(' + args.sizer + ')'))
and:
cerebro.addsizer(bt.sizers.FixedSize, dict(args.sizer))?
I ran the first one and it worked but the second one causes an error.
Can someone please help me?
Python’s eval() allows you to evaluate arbitrary Python expressions from a string-based or compiled-code-based input. This function can be handy when you’re trying to dynamically evaluate Python expressions from any input that comes as a string or a compiled code object.

In Julia, insert commas into integers for printing like Python 3.6+

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
"""

Net Use in Python 3

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().

Why would this line throw a syntax error in Python

I am getting a syntax error on this line of code in Python (tried in both 2.7.5 and 3.3)
Can someone tell me what is wrong?
if (ctx.bytes[0] = t + len) < t:
Appreciate any help!
Added 10/31/2013: My problem has stemmed from the fact that an online converter probably converted the code badly from C to Python. So I REALLY need help on how to convert this program to Python (will prefer 3, but 2 is fine). I need a lot of help with this because I don't 1) understand fully what the C code is doing and 2) I am still very new to Python! So help is appreciated!!! The full C source is posted at Pastebin here: http://pastebin.com/JTT1srSb.
Python won't let you use a single equals sign (assignment operator) within a conditional expression, unlike languages like C. Instead, try doing the following:
ctx.bytes[0] = t + len
if ctx.bytes[0] < t:
Unlike C, the assignment operator does not return any value and so can not be used in expressions. Python's if statement's condition has to be an expression. You can replace your code with:
ctx.bytes[0] = t + len
if len:
PS: You don't need to put brackets around the condition of an if statement in Python.
(ctx.bytes[0] = t + len) < t
You are using assignment operator (=) in the boolean expression, which is not allowed in python.

Why allow concatenation of string literals?

I was recently bitten by a subtle bug.
char ** int2str = {
"zero", // 0
"one", // 1
"two" // 2
"three",// 3
nullptr };
assert( int2str[1] == std::string("one") ); // passes
assert( int2str[2] == std::string("two") ); // fails
If you have godlike code review powers you'll notice I forgot the , after "two".
After the considerable effort to find that bug I've got to ask why would anyone ever want this behavior?
I can see how this might be useful for macro magic, but then why is this a "feature" in a modern language like python?
Have you ever used string literal concatenation in production code?
Sure, it's the easy way to make your code look good:
char *someGlobalString = "very long "
"so broken "
"onto multiple "
"lines";
The best reason, though, is for weird printf formats, like type forcing:
uint64_t num = 5;
printf("Here is a number: %"PRIX64", what do you think of that?", num);
There are a bunch of those defined, and they can come in handy if you have type size requirements. Check them all out at this link. A few examples:
PRIo8 PRIoLEAST16 PRIoFAST32 PRIoMAX PRIoPTR
It's a great feature that allows you to combine preprocessor strings with your strings.
// Here we define the correct printf modifier for time_t
#ifdef TIME_T_LONG
#define TIME_T_MOD "l"
#elif defined(TIME_T_LONG_LONG)
#define TIME_T_MOD "ll"
#else
#define TIME_T_MOD ""
#endif
// And he we merge the modifier into the rest of our format string
printf("time is %" TIME_T_MOD "u\n", time(0));
I see several C and C++ answers but none of the really answer why or really what was the rationale for this feature? In C++ this is feature comes from C99 and we can find the rationale for this feature by going to Rationale for International Standard—Programming Languages—C section 6.4.5 String literals which says (emphasis mine):
A string can be continued across multiple lines by using the backslash–newline line continuation, but this requires that the continuation of the string start in the first position of the next line. To permit more flexible layout, and to solve some preprocessing problems (see §6.10.3), the C89 Committee introduced string literal concatenation. Two string literals in a row are pasted together, with no null character in the middle, to make one combined string literal. This addition to the C language allows a programmer to extend a string literal beyond the end of a physical line without having to use the backslash–newline mechanism and thereby destroying the indentation scheme of the program. An explicit concatenation operator was not introduced because the concatenation is a lexical construct rather than a run-time operation.
Python which seems to have the same reason, this reduces the need for ugly \ to continue long string literals. Which is covered in section 2.4.2 String literal concatenation of the
The Python Language Reference.
Cases where this can be useful:
Generating strings including components defined by the preprocessor (this is perhaps the largest use case in C, and it's one I see very, very frequently).
Splitting string constants over multiple lines
To provide a more concrete example for the former:
// in version.h
#define MYPROG_NAME "FOO"
#define MYPROG_VERSION "0.1.2"
// in main.c
puts("Welcome to " MYPROG_NAME " version " MYPROG_VERSION ".");
I'm not sure about other programming languages, but for example C# doesn't allow you to do this (and I think this is a good thing). As far as I can tell, most of the examples that show why this is useful in C++ would still work if you could use some special operator for string concatenation:
string someGlobalString = "very long " +
"so broken " +
"onto multiple " +
"lines";
This may not be as comfortable, but it is certainly safer. In your motivating example, the code would be invalid unless you added either , to separate elements or + to concatenate strings...
From the python lexical analysis reference, section 2.4.2:
This feature can be used to reduce the
number of backslashes needed, to split
long strings conveniently across long
lines, or even to add comments to
parts of strings
http://docs.python.org/reference/lexical_analysis.html
For rationale, expanding and simplifying Shafik Yaghmour’s answer: string literal concatenation originated in C (hence inherited by C++), as did the term, for two reasons (references are from Rationale for the ANSI C Programming Language):
For formatting: to allow long string literals to span multiple lines with proper indentation – in contrast to line continuation, which destroys the indentation scheme (3.1.4 String literals); and
For macro magic: to allow the construction of string literals by macros (via stringizing) (3.8.3.2 The # operator).
It is included in the modern languages Python and D because they copied it from C, though in both of these it has been proposed for deprecation, as it is bug-prone (as you note) and unnecessary (since one can just have a concatenation operator and constant folding for compile-time evaluation; you can’t do this in C because strings are pointers, and so you can’t add them).
It’s not simple to remove because that breaks compatibility, and you have to be careful about precedence (implicit concatenation happens during lexing, prior to operators, but replacing this with an operator means you need to be careful about precedence), hence why it’s still present.
Yes, it is in used production code. Google Python Style Guide: Line length specifies:
When a literal string won't fit on a single line, use parentheses for implicit line joining.
x = ('This will build a very long long '
'long long long long long long string')
See “String literal concatenation” at Wikipedia for more details and references.
So that you can split long string literals across lines.
And yes, I've seen it in production code.
While people have taken the words out of my mouth about the practical uses of the feature, nobody has so far tried to defend the choice of syntax.
For all I know, the typo that can slip through as a result was probably just overlooked. After all, it seems robustness against typos wasn't at the front of Dennis's mind, as shown further by:
if (a = b);
{
printf("%d", a);
}
Furthermore, there's the possible view that it wasn't worth using up an extra symbol for concatenation of string literals - after all, there isn't much else that can be done with two of them, and having a symbol there might create temptation to try to use it for runtime string concatenation, which is above the level of C's built-in features.
Some modern, higher-level languages based on C syntax have discarded this notation presumably because it is typo-prone. But these languages have an operator for string concatenation, such as + (JS, C#), . (Perl, PHP), ~ (D, though this has also kept C's juxtaposition syntax), and constant folding (in compiled languages, anyway) means that there is no runtime performance overhead.
Another sneaky error I've seen in the wild is people presuming that two single quotes are a way to escape the quote (as it is commonly used for double quotes in CSV files, for example), so they'll write things like the following in python:
print('Beggars can''t be choosers')
which outputs Beggars cant be choosers instead of the Beggars can't be choosers the coder desired.
As for the original "why" question: why is this a "feature" in a modern language like python? - in my opinion, I concur with the OP, it shouldn't be.

Categories