How can I pack a string in struct.pack - python

I am trying to pack a string using struct.pack.
I am able to see complete value if I use integer type but when I want to use string I only see one character.
struct.pack("<1L",0xabcdabcd)
'\xab\xcd\ab\cd'
struct.pack("<1s","overflow")
'o' prints just s. I wanted it to print full string: overflow.

In the format string ("<1s") you're passing to struct.pack, the 1 denotes the maximum number of characters that field can store. (See the paragraph beginning "For the 's'..." in the struct documentation.) Since you're passing 1, it will only store the first character. You'll need to choose a length that will fit any string you want to store in the struct, and specify that. For example, to store the string "overflow" (8 characters) you could use "<8s":
>>> struct.pack("<8s", "overflow")
'overflow'

Related

Two formatting strings in one with only one value

I want to have a string where I can format it with an integer so that it:
Adds a sign in front of the integer (+ for positive ints, - for negative ints)
Surround the signed int with parentheses (i.e. with ())
Left align the int with parentheses on the left, adding if necessary spaces to the end.
I know how to do these steps separately, but I haven't been able to combine them into a single string.
1 and 2 would be accomplished with for example '({:+d})'.format(3), this would result in (+3).
3 is done for an arbitrary string with '{:<5}'.format(3), this would result in 3 (4 trailing spaces).
My goal is to have a single string where I can call .format on only once, so
format_string.format(3)
would result in
(+3)
with one trailing space to make the string length 5.
Is this possible?
I've tried ({{:+d}:<5}) but this doesn't work as it thinks {:+d} is the field name to format with <5, which is obviously not the case.
I've also looked into f-strings, but these are not suitable for my use case as I call .format on the format string later than when it's created.
Any help would be most welcome!
Solution with one call for format:
def special_format_int(n, SPACES=5):
return '({:+d})'.format(n).ljust(SPACES)

Why Simple String's Character has So many array Dimensions?

I am currently working on a python's String and List.
When I assign string in variable str="string" and try to access it first character by str[0] it works perfectly and give "s".
But, when I try to find character str[0][0][0][0][0][0] it again gives "s". But when I give str[0][1] it gives an error:
IndexError: string index out of range
Its Correct. My Question is Why Simple String Character has So many array Dimensions? and it did not given any error and print 0 character of string when str[0][0][0][0][0][0]. What is Data Structure of String?
My Code is
str="string"
print((str[0][0][0][0][0][0][0][0])) # Working, but my Question is Why Working
print((str[1][0][0][0][0])) # Working
print((str[2][0][0][0][0])) # Working
print((str[3][0][0][0][0])) # Working
list=["0","p",0]
print(list[0][0][0]) # Working
My Output is:
s
t
r
i
0
Why shouldn't it work?
Indexing a string returns a one element string which is again indexable and returns the same value:
>>> 's'[0]
's'
since it consists of one element, you can continue indexing the zero-element [0] as much as you want.
This is explained in the standard type hierarchy section of the Python Reference manual:
Strings
A string is a sequence of values that represent Unicode code points. All the code points in the range U+0000 - U+10FFFF can be represented in a string. Python doesn’t have a char type; instead, every code point in the string is represented as a string object with length 1.
(Emphasis mine)
Side-note: Don't use names such as str, you mask the built-in str.
In Python a string is a sequence of characters, but characters are 1-char strings.
So if you access 'foobar'[0], you obtain 'f'. Since f is however a string, we can access the first character of that string. Since 'f'[0] is 'f'. As a result if you access a strings s with s[i][0][0][0], you thus keep accessing the first character of the string s.
If you write s[i][1] however, this will error, since s[i] is a one-character string, and thus you can not obtain the second character, since there is no such character.
The string itself is not multidimensional, you simply obtain a new string and call the index of that new string. You can add as many [0]s as you like.
The problem is not in Python, it is due to the fact that you assume there is a char type in Python (based on the title of this question).
A string in Python is an array of essentially single element strings. s[0] simply returns the string 's', not a character. s[0]...[0] can be thought of as an infinite recursion that keeps getting the same single element string, infinitely many times.
You can go as deep as you want: (in this case, in order to do it more than 997 times you will need to modify Python`s default allowed recursion depth)
def string_dive(s, count=0):
if count < 997:
count += 1
return string_dive(s[0], count)
else:
return s
print(string_dive('string'))
# 's'

python trying to remove single apostrophe

I'm using a program called CityEngine which has a python element to it.
The problem: I've just called a function on an object and returns me a list of numbers, xyz. I split the xyz into their own names. I also call a function to retrieve a different attribute related to this object to replace the previously retrieved y value.
Now, when I print the y value, it contains numerical characters only apart from decimal place.
When I incorporate the y value into a new list, it's value has single apostrophe around it.
For example, print(y) returns 5.0000000
If I place it like this position[x,y,z] I get a print(position) of [0, '5.000000' , 0]. The program can't read the single apostrophes so ignored the value completely.
I've tried .remove("'","") and .strip() and nothing.
Any help would be appreciated.
Thanks.
That looks more as if the function were not returning a number but a string. So, in order to deal with it, you’ll have to convert the string using either int() or float().
In general, if you do a print(l) on some list of items, each item will be printed with the output of it’s __repr__ method. Convention has it that the __repr__ method of string wraps the string with single apostrophes, whereas numbers do not get wrapped. This is to remove potential ambiguity. Hence, a print(l) which returned
[0, '5.00000', 0.1]
would be a list containing an int, a str and a float.
Convert it to float ... It is a string, so you need to do string to float conversion

Python - Writing to a text file using functions?

i wrote a simple function to write into a text file. like this,
def write_func(var):
var = str(var)
myfile.write(var)
a= 5
b= 5
c= a + b
write_func(c)
this will write the output to a desired file.
now, i want the output in another format. say,
write_func("Output is :"+c)
so that the output will have a meaningful name in the file. how do i do it?
and why is that i cant write an integer to a file? i do, int = str(int) before writing to a file?
You can't add/concatenate a string and integer directly.
If you do anything more complicated than "string :"+str(number), I would strongly recommend using string formatting:
write_func('Output is: %i' % (c))
Python is a strongly typed language. This means, among other things, that you cannot concatenate a string and an integer. Therefore you'll have to convert the integer to string before concatenating. This can be done using a format string (as Nick T suggested) or passing the integer to the built in str function (as NullUserException suggested).
Simple, you do:
write_func('Output is' + str(c))
You have to convert c to a string before you can concatenate it with another string. Then you can also take off the:
var = str(var)
From your function.
why is that i cant write an integer to
a file? i do, int = str(int) before
writing to a file?
You can write binary data to a file, but byte representations of numbers aren't really human readable. -2 for example is 0xfffffffe in a 2's complement 32-bit integer. It's even worse when the number is a float: 2.1 is 0x40066666.
If you plan on having a human-readable file, you need to human-readable characters on them. In an ASCII file '0.5' isn't a number (at least not as a computer understands numbers), but instead the characters '0', '.' and '5'. And that's why you need convert your numbers to strings.
From http://docs.python.org/library/stdtypes.html#file.write
file.write(str)
Write a string to the file. There is no return value. Due to buffering,
the string may not actually show up in
the file until the flush() or close()
method is called.
Note how documentation specifies that write's argument must be a string.
So you should create a string yourself before passing it to file.write().

Unable to understand a line of Python code exactly

Alex's answer has the following line when translated to English
print "%2d. %8.2f %8.2f %8.2f" % (
i, payment, interest, monthPayment)
I am unsure about the line
"%2d. %8.2f %8.2f %8.2f" % #Why do we need the last % here?
It seems to mean the following
apply %2d. to i
apply %8.2f to payment
apply %8.2f to interest
apply %8.2f to monthPayment
The %-words seem to mean the following
%2d.: a decimal presentation of two decimals
2-4. %8.2f: a floating point presentation of two decimals
I am not sure why we use the 8 in %8.2f.
How do you understand the challenging line?
The 8 in 8.2 is the width
"Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger"
The 2 is the number of decimal places
The final % just links the format string (in quotes) with the list of arguments (in brackets).
It's a bit confusing that they chose a % to do this - there is probably some deep python reason.
edit: Apparently '%' is used simply because '%' is used inside the format - which is IMHO stupid and guaranteed to cause confusion. It's like requiring an extra dot at the end of a floating point number to show that it's floating point!
The last % is an operator that takes the string before it and the tuple after and applies the formatting as you note. See the Python tutorial for more details.
The % is an operator which makes a format string. A simple example would be:
"%s is %s" % ( "Alice", "Happy" )
Which would evaluate to the string "Alice is Happy". The format string that is provided defines how the values you pass are put into the string; the syntax is available here. In short the d is "treat as a decimal number" and the 8.2 is "pad to 8 characters and round to 2 decimal places". In essence it looks like that format in particular is being used so that the answers line up when viewed with a monospace font. :)
In my code example the s means "treat as a string".
The % after a string tells Python to attempt to fill in the variables on the left side of the
'%' operator with the items in the list on the right side of the '%' operator.
The '%' operator knows to find the variable in the string by looking for character in the string starting with %.
Your confusion is that you think the % operator and the % character in the string are the same.
Try to look at it this way, outside a string % is an operator, inside a string it is possibly a template for substitution.
As usual, a quote of the doc is required - string-formatting:
String and Unicode objects have one unique built-in operation: the % operator (modulo). This is also known as the string formatting or interpolation operator. Given format % values (where format is a string or Unicode object), % conversion specifications in format are replaced with zero or more elements of values. The effect is similar to the using sprintf in the C language.
And the description of the conversion specifier to explain %8.2f
A conversion specifier contains two or more characters and has the following components, which must occur in this order:
The '%' character, which marks the start of the specifier.
Mapping key (optional), consisting of a parenthesised sequence of characters (for example, (somename)).
Conversion flags (optional), which affect the result of some conversion types.
Minimum field width (optional). If specified as an '*' (asterisk), the actual width is read from the next element of the tuple in values, and the object to convert comes after the minimum field width and optional precision.
Precision (optional), given as a '.' (dot) followed by the precision. If specified as '*' (an asterisk), the actual width is read from the next element of the tuple in values, and the value to convert comes after the precision.
Length modifier (optional).
Conversion type.
When the right argument is a dictionary (or other mapping type), the format string includes mapping keys (2). Breaking the example to 2 steps, we have a dictionary and a format that includes keys from the dictionary (the # is a key):
>>> mydict = {'language':'python', '#':2}
>>> '%(language)s has %(#)03d quote types.' % mydict
'python has 002 quote types.'
>>>
the %8.2f means allow 8 character spaces to hold the number given by the corrisponding variable holding a float, and then have decimal precision of 2.

Categories

Resources