How to right-align numeric data? - python

I have some data that I am displaying in 3 column format, of the form:
key: value key: <tab> key: value <tab> key: value.
Here's an example:
p: 1 sl: 10 afy: 4
q: 12 lg: 10 kla: 3
r: 0 kl: 10 klw: 3
s: 67 vw: 9 jes: 3
t: 16 uw: 9 skw: 3
u: 47 ug: 9 mjl: 3
v: 37 mj: 8 lza: 3
w: 119 fv: 8 fxg: 3
x: 16 fl: 8 aew: 3
However, I'd like if the numbers were all right aligned, such as:
a: 1
b: 12
c: 123
How can I do this in Python?
Here is the existing printing code I have:
print(str(chr(i+ord('a'))) + ": " + str(singleArray[i]) + "\t" +
str(doubleArray[i][0]) + ": " + str(doubleArray[i][1]) + "\t" +
str(tripleArray[i][0]) + ": " + str(tripleArray[i][1]))

In python 2.6+ (and it's the standard method in 3), the "preferred" method for string formatting is to use string.format() (the complete docs for which can be found here).
right justification can be done with
"a string {0:>5}".format(foo)
this will use 5 places, however
"a string {0:>{1}}".format(foo, width)
is also valid and will use the value width as passed to .format().

In Python 2.5 use rjust (on strings). Also, try to get used to string formatting in python instead of just concatenating strings. Simple example for rjust and string formatting below:
width = 10
str_number = str(ord('a'))
print 'a%s' % (str_number.rjust(width))

Use python string formatting: '%widths' where width is an integer
>>> '%10s' % 10
' 10'
>>> '%10s' % 100000
' 100000'

In Python 3.6 you can use Literal String
Interpolation, which is less
verbose and probably more intuitive to use:
width = 5
number = 123
print (f'{number:>{width}}')
Or just:
number = 123
print (f'{number:>5}')
It reuses much of the str.format() syntax.
I guess/hope this will be the prefered way in the future.

If you know aa upper bound for your numbers, you can format with "%<lenght>d" % n. Given all those calculations are done and in a list of (char, num):
mapping = ((chr(i+ord('a')), singleArray[i]),
(doubleArray[i][0],doubleArray[i][1]),
(tripleArray[i][0],tripleArray[i][1])
)
for row in mapping:
print "%s: %3d" % row

Related

Is there a way to print the math that makes an integer in Python?

Suppose I have this code:
int1 = (2 + 2) * 4
print(int1)
OUTPUT: 16
But is there a way to print the math of the int without using a string instead? Like a literal() function or something?
Example program:
int1 = 2 + 2
int2 = 4
print('{} times {} equals:'.format(literal(int1), literal(int2))
print(int1 * int2)
OUTPUT:
2 + 2 times 4 equals:
16
I kind of feel like I'm looking for a solution to a problem that doesn't exist, but I'm new to Python and I'm curious.
Native python 'forgets' the operations you made, and just remembers the values of the variables you have. So when you do x = int1 * int2, python allocates the corresponding value to x, but does not store anything about the operations which yielded this value.
However, it could be a (not so easy) coding exercise: design your own integer class which stores the history of computations.
You can do something similar, except storing the literal firm in a string, and using the simple_eval method from the simpleeval module:
from simpleeval import simple_eval
int1 = '2 + 2'
int2 = 4
print('{} times {} equals:'.format(int1, int2))
print(simple_eval(int1) * int2)
Output:
2 + 2 times 4 equals:
16
simpleeval is a module that safely evaluates math expressions, as opposed to the infamous eval method, that allows malicious attacks to your OS.
The more reasonable approach would be to use strings, and then evaluate them. Using eval wouldn't be unsafe unless you were getting your strings from untrusted inputs, if they are from the source code it's fine.
-- comment by juanpa.arrivillaga
int1 = '2 + 2'
int2 = '4'
print('{} times {} equals:'.format(int1, int2))
print(eval(int1) * eval(int2))
Output:
2 + 2 times 4 equals:
16
class Math():
def __init__ (self):
self.val = 0
self.opList = []
def add(self,val):
self.val += val
self.opList.append(" + "+str(val))
def sub(self,val):
self.val -= val
self.opList.append(" - "+str(val))
def printOps(self):
print(self.val," = 0",end="")
for i in self.opList:print(i,end="")
t = Math()
t.add(10)
t.sub(5)
t.printOps()
python does have operator overloading but it looks like a pain to write

How to format float to integer if the value is integral. That is, display 13.0 as 13 but 13.5 as 13.5

[Working with Python 3.x]
I'm trying to display 2D line equations. I'm assuming the coefficents or constants to be float because it's possible they can be float. However, if they are integers, I'd like to show them as integers.
That is, instead of
x + 3.0y = 13.0
I want to display
x + 3y = 13
However,
x + 3.5y = 13.5
should stay as is.
How do I do this kind of conditional formatting?
Assumming the function for that will only be passed an exact multiplier (without unknown variable), input and output are strings:
def simplifyFloat(str):
f = float(str)
if f % 1 == 0: #if f has some floating point this is going to be false
f = int(f)
return str(f)
And usage:
equation = '2.0x + 3.5y + 2'
x_part, o, y_part, o, const_part = equation.split(' ') # o variables for dumping operators
# [:-1] before string means you get rid of the last letter, which is 'x' and 'y'
print(simplifyFloat(x_part[:-1])) # output '2'
print(simplifyFloat(y_part)[:-1]) # output '3.5'
There might be more efficient ways to do that, but branching with ceil value works correctly:
import math
number1 = 3.0
number2 = 3.5
def integral_formatting(n):
return n if n != math.ceil(n) else math.ceil(n)
>>> integral_formatting(number1)
3
>>> integral_formatting(number2)
3.5
An efficient way I can come up with, is to make a function that returns integer or float, depending on the case. The function can be like
def check(x):
if int(x) == x:
return int(x)
else:
return float(x)
Now, any number can be put in equation as check(1.0) * x + check(13) * y = check(13.5). This will result in 1x + 13y = 13.5. Hope this helps!

Decorating Hex function to pad zeros

I wrote this simple function:
def padded_hex(i, l):
given_int = i
given_len = l
hex_result = hex(given_int)[2:] # remove '0x' from beginning of str
num_hex_chars = len(hex_result)
extra_zeros = '0' * (given_len - num_hex_chars) # may not get used..
return ('0x' + hex_result if num_hex_chars == given_len else
'?' * given_len if num_hex_chars > given_len else
'0x' + extra_zeros + hex_result if num_hex_chars < given_len else
None)
Examples:
padded_hex(42,4) # result '0x002a'
hex(15) # result '0xf'
padded_hex(15,1) # result '0xf'
Whilst this is clear enough for me and fits my use case (a simple test tool for a simple printer) I can't help thinking there's a lot of room for improvement and this could be squashed down to something very concise.
What other approaches are there to this problem?
Use the new .format() string method:
>>> "{0:#0{1}x}".format(42,6)
'0x002a'
Explanation:
{ # Format identifier
0: # first parameter
# # use "0x" prefix
0 # fill with zeroes
{1} # to a length of n characters (including 0x), defined by the second parameter
x # hexadecimal number, using lowercase letters for a-f
} # End of format identifier
If you want the letter hex digits uppercase but the prefix with a lowercase 'x', you'll need a slight workaround:
>>> '0x{0:0{1}X}'.format(42,4)
'0x002A'
Starting with Python 3.6, you can also do this:
>>> value = 42
>>> padding = 6
>>> f"{value:#0{padding}x}"
'0x002a'
How about this:
print '0x%04x' % 42
If you don't need to handle negative numbers, you can do
"{:02x}".format(7) # '07'
"{:02x}".format(27) # '1b'
Where
: is the start of the formatting specification for the first argument {} to .format()
02 means "pad the input from the left with 0s to length 2"
x means "format as hex with lowercase letters"
You can also do this with f-strings:
f"{7:02x}" # '07'
f"{27:02x}" # '1b'
If just for leading zeros, you can try zfill function.
'0x' + hex(42)[2:].zfill(4) #'0x002a'
Use * to pass width and X for uppercase
print '0x%0*X' % (4,42) # '0x002A'
As suggested by georg and Ashwini Chaudhary
None of the answers are dealing well with negative numbers...
Try this:
val = 42
nbits = 16
'{:04X}'.format(val & ((1 << nbits)-1))
If you want to hold the preceding hex notation 0x you can also try this method too which is using the python3 f-strings.
f'0x{10:02x}' # 0x0a
Suppose you want to have leading zeros for hexadecimal number, for example you want 7 digit where your hexadecimal number should be written on, you can do like that :
hexnum = 0xfff
str_hex = hex(hexnum).rstrip("L").lstrip("0x") or "0"
'0'* (7 - len(str_hexnum)) + str_hexnum
This gives as a result :
'0000fff'

Is fortran-like print in python possible?

is it possible some way to "print" in python in a fortran like way like this?
1 4.5656
2 24.0900
3 698.2300
4 -3.5000
So the decimal points is always in the same column, and we get always 3 or n decimal numbers?
Thanks
>>> '%11.4f' % -3.5
' -3.5000'
or the new style formatting:
>>> '{:11.4f}'.format(-3.5)
' -3.5000'
more about format specifiers in the docs.
You could also take a look at the fortranformat library on PyPI or the project page if you wanted to fully recreate FORTRAN text IO.
If you have any questions, send me an email (I wrote it).
for i in [(3, 4.534), (3, 15.234325), (10,341.11)]:
... print "%5i %8.4f" % i
...
3 4.5340
3 15.2343
10 341.1100
print "%10.3f" % f
will right align the number f (as an aside: %-10.3f would be left-aligned). The string will be right-aligned to 10 characters (it doesn't work any more with > 10 characters) and exactly 3 decimal digits. So:
f = 698.230 # <-- 7 characters when printed with %10.3f
print "%10.3f" % f # <-- will print " 698.2300" (two spaces)
As a test for your example set do the following:
print "\n".join(map(lambda f: "%10.3f" % f, [4.5656, 24.09, 698.23, -3.5]))
You can use string.rjust(), this way:
a = 4.5656
b = 24.0900
c = 698.2300
d = -3.5000
a = "%.4f" % a
b = "%.4f" % b
c = "%.4f" % c
d = "%.4f" % d
l = max(len(a), len(b), len(c), len(d))
for i in [a, b, c, d]:
print i.rjust(l+2)
Which gives:
~ $ python test.py
4.5656
24.0900
698.2300
-3.5000
Fortran io is totally different to C style io in every way.
Go for Brendan's fortranformat package.
https://pypi.python.org/pypi/fortranformat
easy_install fortranformat
This allows arcane old fortran input files to be created with much less trial and error than trying to use C style string formatting.

How can I make `bin(30)` return `00011110` instead of `0b11110`? [duplicate]

This question already has answers here:
Python int to binary string?
(36 answers)
Closed 3 years ago.
What does the b stand for in the output of bin(30): 0b11110? Is there any way I can get rid of this b? How can I get the output of bin() to always return a standard 8 digit output?
Using zfill():
Return the numeric string left filled with zeros in a string of length width. A sign prefix is handled correctly. The original string is returned if width is less than len(s).
>>> bin(30)[2:].zfill(8)
'00011110'
>>>
0b is like 0x - it indicates the number is formatted in binary (0x indicates the number is in hex).
See How do you express binary literals in python?
See http://docs.python.org/dev/whatsnew/2.6.html#pep-3127-integer-literal-support-and-syntax
To strip off the 0b it's easiest to use string slicing: bin(30)[2:]
And similarly for format to 8 characters wide:
('00000000'+bin(30)[2:])[-8:]
Alternatively you can use the string formatter (in 2.6+) to do it all in one step:
"{0:08b}".format(30)
Take advantage of the famous format() function with the lesser known second argument and chain it with zfill()
'b' - Binary
'x' - Hex
'o' - Octal
'd' - Decimal
>>> print format(30, 'b')
11110
>>> print format(30, 'b').zfill(8)
00011110
Should do. Here 'b' stands for binary just like 'x', 'o' & 'd' for hexadecimal, octal and decimal respectively.
You can use format in Python 2 or Python 3:
>> print( format(15, '08b') )
00001111
[]'s
You can use this too :
bi=bin(n)[2:]
This will remove the '0b' portion of the returned value and you can use the output anywhere .
The current answers don't consider negative values (thanks #Gui13 for the comment!) in which case you get -0b... instead of just 0b.... You can handle both with a simple if-else where the value is checked whether it's less than zero or not
>>> def printBit(x):
if x < 0:
return '-' + bin(x)[3:].zfill(8) # replace
else:
return bin(x)[2:].zfill(8)
>>> print(printBit(30))
'00011110'
>>> print(printBit(-30))
'-00011110'
or by using replace()
>>> print(bin(30)).replace('0b', '').zfill(8)
The problem with the call above is that one of the bits gets "lost" to the - sign due to the same value being used for the zfill(). You can handle this too with a simple ternary check:
>>> x = 30
>>> print(bin(x)).replace('0b', '').zfill(9 if x < 0 else 8)
'00011110'
>>> x = -30
>>> print(bin(x)).replace('0b', '').zfill(9 if x < 0 else 8)
'-00011110'
Last but not least you can also make the zfill() to automatically adapt the number of 0s to match a byte (8 bits) or a n number of bit quadruplets (4 bits):
>>> def pb(x):
bres = bin(x).replace('0b', '').replace('-', '') # If no minus, second replace doesn't do anything
lres = len(bres) # We need the length to see how many 0s we need to add to get a quadruplets
# We adapt the number of added 0s to get full bit quadruplets.
# The '-' doesn't count since we want to handle it separately from the bit string
bres = bres = ('-' if x < 0 else '') + bres.zfill(lres + (4-lres%4))
return bres
>>> print(pb(7))
'0111'
>>> print(pb(-7))
'-0111'
>>> print(pb(30))
'00011110'
>>> print(pb(-30))
'-00011110'
Here is the final version with adaptable filling of 0s and additional split with space every n characters (where the n is determined by filling factor):
>>> def pb(x, fillingBits=4, splitWithSpace=True):
# If no minus, second replace doesn't do anything
bres = bin(x).replace('0b', '').replace('-', '')
lres = len(bres)
bres = bres.zfill(lres + (fillingBits - (lres % fillingBits)))
lres = len(bres)
# We can also add a blank after every fillingBits character
if splitWithSpace:
bres = ' '.join([bres[i:(i + fillingBits)] for i in range(0, lres, fillingBits)])
bres = ('-' if x < 0 else '') + bres
# We remove any trailing/leading blanks (occurring whenever splitWithSpace enabled)
return bres.strip()
>>> print(pb(7))
'0111'
>>> print(pb(-7))
'-0111'
>>> print(pb(30))
'0001 1110'
>>> print(pb(-30))
'-0001 1110'
python 2.7
print "{0:b}".format(30)
python 3.x
print ('{0:b}'.format(30))

Categories

Resources