python 3 string formatting (alignment) - python

i have a code where the out put should be like this:
hello 3454
nice 222
bye 45433
well 3424
the alignment and right justification is giving me problems.
i tried this in my string {0:>7} but then only the numbers with the specific amount of digits are alright. the other numbers that have some digits more or less become messed up. it is very obvious to understand why they are messing up, but i am having trouble finding a solution. i would hate to use constant and if statements all over the place only for such a minor issue. any ideas?

You could try:
"{:>10d}".format(n) where n is an int to pad-left numbers and
"{:>10s}".format(s), where s is a string to pad-left strings
Edit: choosing 10 is arbitrary.. I would suggest first determining the max length.
But I'm not sure this is what you want..
Anyways, this link contains some info on string formatting:
String formatting
You can try this:
def align(word, number):
return "{:<10s}{:>10d}".format(word, number)
This will pad-right your string with 10 spaces and pad-left your number with 10 spaces, giving the desired result
Example:
align('Hello', 3454)
align('nice', 222)
align('bye', 45433)
align('well', 3424)

Related

Formatting Number With Comma

I am trying to put comma's on a number without striping any numbers after the decimal point.
number
12018093.1000
results
12,018,093.10
I tried this code but it strips away the last 0 which I don't know why.
rps_amount_f = ("{:,}".format(float(rps_amount_f)))
I'm not sure why the zeros are stripped away in your example, although this may be a solution using an f-string:
rps_amount_f = 12018093.1
rps_amount_f_str = f"{rps_amount_f:,.10f}"
Here '10' before the f is the decimal precision you want to have in the string, i.e. 10 decimals in this case.
You said that you only want one zero so really isn't the solution just to add a 0 to the end of the string? Anyway here's my solution:
if("." in str(rps_amount_f)):
rps_amount_f = ("{:,}".format(float(rps_amount_f)) + "0")
else:
rps_amount_f = ("{:,}".format(float(rps_amount_f)))
If you want two decimal places you just get rid of the if statement and round it.
print("{:,.4f}".format(float(rps_amount_f))) # 12,018,093.1000
https://docs.python.org/3/library/string.html#format-specification-mini-language

0's in the beginning are being skipped & I'm not sure how to fix it

The output value is not including the 0's in the beginning, can someone help me fix the problem?
def bitwiseOR(P, Q):
return bin(P | Q)
bitwiseOR(0b01010111, 0b00111000)
OUTPUT: '0b1111111'
The leading zeroes are just for representation, so you can utilize Format Specification Mini-Language to display them as you wish:
Format string:
# Includes 0b prefix
0{length} Pad leading zeroes so total length is length
def bitwiseOR(P, Q, length=10):
return format(P | Q, f'#0{length}b')
x = bitwiseOR(0b01010111, 0b00111000)
# 0b01111111
print(x)
Leading zeros are a property of the string you produce, not the number. So, for example, if you're looking for a way to make the following two calls produce different results, that's not possible:1
bitwiseOR(0b01010111, 0b00111000)
bitwiseOR( 0b1010111, 0b111000)
However, if you can provide the number of digits separately, then you can do this using the format() function. It accepts a second argument which lets you customize how the number is printed out using the format spec. Based on that spec, you can print a number padded with zeros to a given width like this:
>>> format(127, '#010b')
'0b01111111'
Here the code consists of four pieces:
# means apply the 0b prefix at the beginning
0 means pad with leading zeros
10 means the total length of the resulting string should be at least 10 characters
b means to print the number in binary
You can tweak the format code to produce your desired string length, or even take the length from a variable.
1Well... technically there is a way to make Python re-read its own source code and possibly produce different results that way, but that's not useful in any real program, it's only useful if you want to learn something about how the Python interpreter works.

F-String round float to either 0 or 1 decimals, and how much logic inside an f-string is OK?

I have a bunch of floating point numbers that are either x.0 or x.5 and if they are x.0 I want no decimal points displayed, and if they are x.5 I want one decimal point displayed.
I have come up with a one-liner that does the job:
f'{x:+.{int(bool(x % 1))}f}'
Where int(bool(x % 1)) will always be 0 or 1 depending on whether modulo yields a remainder.
This works fine because of the nature of my float inputs, but it got me thinking, what if my inputs weren't so neat? For example the above one-liner with 10.01 as an input returns 10.0. My temptation is to first round the float to the desired precision:
f'{x:+.{int(bool(round(x, 1) % 1))}f}'
If there wasn't already a lot going on inside the f-string in my first example, there is now.
To be clear about my question:
Firstly, is my first method the 'right' way to go about what I'm actually trying to achieve given my real-world inputs?
Secondly, how about in the case of the hypothetical problem and my second example?
Thirdly, I'd like to canvas opinion from the community regarding where use of f-string crosses the line to abuse. As an example of how one might be tempted to pack a lot of stuff into the f-string, how about something like this to get a list of strings containing numbers to sort alphabetically:
f"String with number:{' ' if x >= 1000 else ' ' if x >= 100 else ' ' if x >= 10 else ' '}{x:+.{int(bool(round(x, 1) % 1))}f}"
So I hope tying this question about overuse of f-string in with my rounding question doesn't cause the overall question to be too vague, but these are two issues that I'm considering together. I suppose the 'neatness' of f-string can provide a temptation to shoehorn everything into one-liners.

How to string split numbers in python

This is what I have, but I know it is incorrect and I'm not sure what to change
print '0.4066145E-07-0.3677403'.split('E+(\-\d{2})', 1 )
I'm looking to get:
['0.4066145E-07','-0.3677403']
or more generally I just want to split up these numbers.
['######E-##','#########']
Also what if there is an exponent in the second number?
['######E-##','#######E-##']
You can try with:
(?<=E-\d\d)(?=-\d+.)
DEMO

randint with leading zero's

I want to generate numbers from 00000 to 99999.
with
number=randint(0,99999)
I only generate values without leading zero's, of course, a 23 instead of a 00023.
Is there a trick to generate always 5 digit-values in the sense of %05d or do I really need to play a python-string-trick to fill the missing 0s at front in case len() < 5?
Thanks for reading and helping,
B
You will have to do a python-string-trick since an integer, per se, does not have leading zeroes
number="%05d" % randint(0,99999)
The numbers generated by randint are integers. Integers are integers and will be printed without leading zeroes.
If you want a string representation, which can have leading zeroes, try:
str(randint(0, 99999)).rjust(5, "0")
Alternatively, str(randint(0, 99999)).zfill(5), which provides slightly better performance than string formatting (20%) and str.rjust (1%).
randint generates integers. Those are simple numbers without any inherent visual representation. The leading zeros would only be visible if you create strings from those numbers (and thus another representation).
Thus, you you have to use a strung function to have leading zeros (and have to deal with those strings later on). E.g. it's not possible to do any calculations afterwards. To create these strings you can do something like
number = "%05d" % random.randint(0,99999)
The gist of all that is that an integer is not the same as a string, even if they look similar.
>>> '12345' == 12345
False
For python, you're generating a bunch of numbers, only when you print it / display it is it converted to string and thus, it can have padding.
You can as well store your number as a formatted string:
number="%05d" % random.randint(0,9999)

Categories