Python Forum

Full Version: trying to understand a string literal in a basic server program
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have this code:

import socket

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(),1234))
s.listen(5)

while True:
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established!")

    msg = "Welcome to the server!"
    msg = f'{len(msg):<10{HEADERSIZE}}'+ msg

    clientsocket.send(bytes("msg", "utf-8"))

    while True:
        time.sleep(3)
        msg = f"The time is! {time.time()}"
        msg = f'{len(msg):<{HEADERSIZE}}' + msg
        clientsocket.send(bytes(msg, "utf-8"))
and i'm trying to understand this line: f{len(msg):<10{HEADERSIZE}}

so i opened my ide and i did this:

>>> msg = 'Hello World!'
>>> len(msg)
12
>>> len(msg):<10
SyntaxError: invalid syntax

for me it's pretty much the same thing so... why doen't it work?
Plus, if you remove the string literal in line fourteen, doesn't give : msg = 22:<10 10 + msg???

I tried to find an explanation on the web, but to no avail...
Could someone explain what's going on?
Could someone explain?
This is using the format language for f-strings. The first bit inside the braces is the thing you want to evaluate (and print the str() representation of), and the second bit (after the colon) is the Format specification mini-language.

In your particular case the less-than sign indicates left alignment within the field and HEADERSIZE is evaluated and interpreted as the size of the field.

>>> headersize = 10
>>> n = 45
>>> f"{n}"
'45'
>>> f"{n:{headersize}}"
'        45'
>>> f"{n:<{headersize}}"
'45        '
In the example below, both prints produce the same output:
import socket
HEADERSIZE=10
msg = "Welcome to the server!"
print(f'{len(msg):<10{HEADERSIZE}}+msg')  # {HEADERSIZE} will be replaced by 10
print(f'{len(msg):<1010}+msg')
So this makes a string that starts with len(msg) followed lots and lots of padding and finally "Welcome to the server!"
    msg = f'{len(msg):<10{HEADERSIZE}}'+ msg
The reason you got an error trying to evaluate "len(msg):<10" is that this is not Python code, it is f'string formatting code. Just like the syntax for regular expressions is not Python, the format syntax for f'strings is not Python. These are special purpose mini-languages for doing specific tasks.
(Nov-13-2021, 11:55 PM)deanhystad Wrote: [ -> ]In the example below, both prints produce the same output:
import socket
HEADERSIZE=10
msg = "Welcome to the server!"
print(f'{len(msg):<10{HEADERSIZE}}+msg')  # {HEADERSIZE} will be replaced by 10
print(f'{len(msg):<1010}+msg')
So this makes a string that starts with len(msg) followed lots and lots of padding and finally "Welcome to the server!"
    msg = f'{len(msg):<10{HEADERSIZE}}'+ msg
The reason you got an error trying to evaluate "len(msg):<10" is that this is not Python code, it is f'string formatting code. Just like the syntax for regular expressions is not Python, the format syntax for f'strings is not Python. These are special purpose mini-languages for doing specific tasks.

if I write : f'{msg:<1010}' the first 10 stands for 10 charcaters and msg is inside those 10 characters, but what does the second 10 stands for? Does it multiply the first 10, because that's what it looks like when i put it in python
iimport socket
HEADERSIZE=10
msg = "Welcome to the server!"
print(len(msg))
x = f'{len(msg):<10{HEADERSIZE}}'+msg
y = f'{len(msg):<1010}'+msg
print(len(x), len(y), x == y)
Output:
1032 1032 True
10{HEADERSIZE} ends up as 1010. The resulting string is 1032 characters long. 1010 character for the message length and padding and 22 characters for the message.

If I print x it looks like this:
Output:
22 Welcome to the server!
This is "22" followed by 1008 blanks and then "Welcome to the server!"