# Python Programming Language

## Printing Facilities

Extended Lecture for Python Tutorial
Bedri Doğan Emir (Prof. Dr. Ret.)
http://www.bedriemir.com

Content

1 - Basic Printing Procedures

1.1 -Python Printing Defaults

Python is a very frequently applied moden style programming language and from version 2.7 it supports both classic and modern style printing facilities. This makes Python programming language having very large printing possibilities but brings also difficulties to master them. The purpose of this manuscript. is to present and explain these new facilities.

Printing capabilities of Python is outstanding and unmatched with other programming. Python supports common style of printing like Java, Perl, JavaScript and similar programming languages, in addition it has an unique modern formatting system which surpasses the classic formatting system supported by other programming languages.

First of all, we should have a knowledge about Pyton printing function print(), since we will always need this function for data visualising.

The print() function of Python is defined with it's default values as :

print(value, ..., sep=' ',

end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments:

file: a file-like object (stream); defaults to the current sys.stdout.

sep: string inserted between values, default a space.

end: string appended after the last value, default a newline.

flush: whether to forcibly flush the stream.

We will begin with printing of simple singular objects for experiencing the default attitude of the print() function and opportunities to override the default values.

1.1.1 - Printing Strings

First we will examine printing of a single string with default values.

print ("Hello World !")

Hello World !

The printout obtained, reflects exactly the given data. The total length of the string was 13 spaces in the data and it is exactly the same length in the printout. Would more spaces is defined in the data, we will obtain the same amount of spaces printed in the printout.

print ("Hello    World ! !")

Hello    World !

Python print(attributes) function, receive his attributtes as a tuple, which is a comma separated list (CSV) of unchangeable items with same type as the data.

a = 10

print(a,type(a ))
12b<class= 'int'>

There were no spaces between CSV data but in the printout, we got a printout where each item is separated with a single blank space. this is due to the default action of sep =" ". The item separator default to one single blank space for the separation between items to be printed. When printed with this default, there is no need to explicitly state sep=" ",but when overriding this default, we must explicitly indicate the new separator that we wish in the printout. Any character may be chosen as an item separator for the coming printing.

a = 10

print(a,type(a), sep =" | ")
12 | class= 'int'>

There is a possibility in Python, to indicate whether the next print will be printed in same line or to the next line. The argument managing the subsequent printing is the end = "\n" (ecaped n) argument, where n stands for newline. This is the default behavior and there is no need to explicity state it, when the deafult is to be followed. But for overriding the default, one must explicitly state that the newline indicator is different from "\n". In the program below, the the next print will be displayed in the same line, without inserting an empty space between subsequent items to be printed, since the end point indicator end="" suggest that no empty spaces should be inserted between two subsequent printed data.

print("Hello World !" end="" )

print(" What a Nice Day !")

Hello World ! What a Nice Day !

The next printout will always occur according the decriptions of the previous print() function. In the program below, it is stated that the next print will be at the same line and 6 empty spaces will be inserted between printed items.

print("Hello World !" end="      ")

print(" What a Nice Day !" )

Hello World !      What a Nice Day !

The next printout will always be at the same line as far as the (end ="anything") part of the print() function is explicitly stated.

print("Section" , end = "/")

Section/

print("SubSection;", end = "/")

Section/SubSection/

print("Content") # Default behavior is restored

Section/SubSection/Content

Note that, unless it is expicitly stated as end="\n" any end = " termination character" will not initialize a new line, but print the termination character (here a slash) and proceed to the next print statement in the same line without leaving any blank space between two subsequent prints.

The ending indicator of the print() function when stated, is not permanent. If nothing is said about ending indicator, the print() function restores its default behavior and the subsequent prints will be done in the subsequent lines. Just like the last print() function of the example given above.

print("1 - Introduction")

1 - Introduction

Python prints any text by allowing enough spaces for the entire string so that nothing is lost.

print("Hello World !")

print("Hello World !")

Hello World !

Hello World !

Notice the right justification of the strings in the printout.

We can split long strings by a newline command(n), by escaping in the string as (\n) then the subsequent part of the string is printed to the next line.

Python programming language allows the insertion of two escaped characters \t and \n in the strings. The former indicates that there will be one tab length distance between two characters separated by \t and the later indicates that the next character after \n will be printed in the next line.

print("Hello luw, \t how's your mood? ")

print("Tea : \t 10 p.")

Tea : 	 10 p.

print("Instant Coffee :\t 15 p.")

Instant Coffee : 	 15 p.

No right alignment, only separation of one tab length.

print("Hello mate, \n how's going? ")

Hello mate,

how's going?

Note that the next line is a little intended in order to indicate that the line is the continuation of the same string.

1.1.2 - Printing Numbers

Working with numbers is somewhat detailed, because numbers may be integers or floating numbers. Also they may be signed or unsigned which make an additional case to be taken into account. As a default behavior, they are printed according to an internal procedure, so that no human intervention is required.

The type of the data is not changed when printed.

print(24.89 , type(24.89))

24.89 <class 'float'>

Positive sign is not required, since any non- negative numbers are to be understood as positive. But negative numbers should be explicitly stated as negative.

print(-16.18)

-16.18

Python allows three type of representation of the floating point numbers. In science, S.I. system suggest that the numbers are stated in scientific format which is like 3.9E-2 or 3.9e-2 or 3.9*10**-2 . All are equivalent to 0.039 as it illustrated in the example below.

print(3.9E-2 , 3.9e-2 , 3.9*10**-2 )

0.039 0.039 0.039

Or within a loop mechanism :

i=0

q=(25.25e-2 , 25.25E-2 , 25.25*10**-2)

for item in q:

i=i+1

print("item ", i  , ": ", item)

item  1 :  0.2525

item  2 :  0.2525

item  3 :  0.2525

1.1.3 - Arithmetic Operations

In Python, print() function can make some arithmetic before printing.

print( "12 + 45.89 = " , 12 + 45.89)

12 + 45.89 = 57.89

Substraction :

print( "10 - 8 = " , 10 - 8)

10 - 8 = 2

Multiplication :

print( " 25 * 4 = " , 25 * 4)

25 * 4 = 100

Divsion :

print( "12 / 2 = " , 12 / 2)

12 / 2 = 6

Modulus :

It is unfortunate that the modulus symbol % is the same with the formatting symbol %, but one can manage to have a modlus operation with the context of the statement.

print( "7 % 4 = " , 7 % 4)

7 % 4 = 3

Exponentiation :

print( "2**3 = " , 2 ** 3)

8

1.1.4 - Printing Binary, Octal and Hex Integers

Python supports binary, octal and hex integers and allows to make addition, substraction and multiplication among them. Division and modulus is not permitted since these operations are not closed (i.e. the result may not be an integer) for the integer set.

print( "Printing a binary number :" , 0b00100101 , " , type(0b00100101) : " , type(0b00100101))

Printing a binary number : 0b00100101= 37 , type(0b00100101) : <class 'int'>

print( "Printing a binary number " , 0b10101 , " , type(0b10101) : " , type(0b10101))

Printing a binary number 0b10101= 21 , type(0b10101) : <class 'int'>

print( "Printing an addition of two binary numbers : " , 0b00100101 + 0b10101 , " , type(0b00100101+0b10101) : " , type(0b00100101+ 0b10101))

Printing an addition of two binary numbers : 0b00100101 + 0b10101 = 58 , type(0b00100101 + 0b10101) : <class 'int'>

Note that the values of the binary, octal and hex numbers are retained in the internal memory as decimal integers. That is why the results of the permitted arithmetic operations between them is displayed as decimal integers. For converting back to the binary system, one can use the converversion functions like bin(), oct() and hex(). The result of the conversion will be a string whose content will be converted to a binary, octal or hex number. No arithmetic operations with converted string types. We can only concatenate them.

print ("Result : ", bin (58) ," , Type of the Result : ",type (bin (58)))

Result : 0b111010 , Type of the Result : <class 'str'>

print("bin(0b00100101 + 0b10101) = " , bin (0b00100101 + 0b10101) , " , type(bin(0b00100101+0b10101)): " , type(bin(0b00100101+ 0b10101)))

bin(0b00100101 + 0b10101) = 0b111010 , type (bin(0b00100101 + 0b10101)) : <class 'str'>

Exactly two equal results with the same type.

print("Printing an octal number :" ,0o237)

Printing an octal number : 159

print("Printing an hex number :" ,0x825CD)

Printing an hex number : 533965

2 - Latex Printing with Python

Yes, Latex printing is supported with Python. For achieving this, we must implement the Latex infrastructure in our computer. This is easily achived by following the steps described at the Internet. First we must implement Ipython notebook infrastucture in our environment. This may be achieved easily by downloading and running Anaconda or Winpython frameworks in our computer. The problems begin after their implementation. Anaconda is invasive. I reverts the Pyton version used in the system to a version implement with Anaconda. This impose problems of course, because one will choose the work with the latest release of the Python interpreter rather than the one inserted with Anaconda. It gives real headache, but if you stand with the Anaconda release, no problems will be experienced. WinPython is more restrictive because it only affects its framework, i.e. the folder which is inserted. Then we should import display() and Math() functions from Ipython display as :

from IPython.display import *

or with less memory allocation,

from IPython.display import display, Math

The display() function acts like print() but only prints string data.

display("88 + 2 = " + str(88 + 2))

'88 + 2 = 90'

Just like the normal print() but the result is displayed between quotes. But Math() function makes a better display and without quotes.

display(Math("88 + 2 = " + str(88 + 2)))

But the real realm comes with Latex printing. One sholud not know very deep latex. Here it is needed just matematical Latex notations and it is very easy to use the in printed material. We have collected the related section of the book of Latex of Wikipedia as a MSWord document Mathematical Latex symbols collected from Wikipedia. With that in hand it will be very easy to generate printed material in Latex style in Python.

we should not forget that it is used "escaped backslash" as "\\" for Latex printing.

Another way for obtention of pretty printed material is defined in stackoverflow :

This one is our interpretation based from the method above.

import matplotlib.pyplot as plt

import math

a = r'\sqrt{a}='+str(math.sqrt(2))

ax=plt.subplot(111)

ax.text(0.5,0.5,r"$%s$" %(a),fontsize=20,color="green")

plt.show()

Or, with more understandable code :

import matplotlib.pyplot as plt

a = r'\frac{a}{b}'

ax = plt.axes([0,0,0.3,0.3]) #left,bottom,width,height

ax.set_xticks([])

ax.set_yticks([])

ax.axis('off')

plt.text(0.4,0.4,'$%s$' %a,size=20,color="green")

We will define this classic style very soon.

Importing Matplotlib is delicate. The best implementation is cloning from the Git :

git clone git://github.com/matplotlib/matplotlib.git

cd matplotlib

python -mpip install

Then we will have hassle free Matplotlib implementation (hopefully).

3 - Data Type Conversion in Python

Python has large data conversion functions. Altough it is not directly related to printing, it is worth to have some knowledge about these functions.

3.1 - Conversion to String

3.1.1- Integer to String

The function str(atrribute) converts any attribute type to string.

After the conversion to string, no arithmetic operations are permitted. Only string concatenation (union of strings) is possible. Example :

print(str(23) + str(16))

Result : 2316

Note that altough the operation is defined with the addition operator, this is not an arithmetic operation. Only it concatenates two strings into one.

Binary, octal and hex values are integers by definition. Python does not support the floating point values of non-base-10 types.They can be converted to string as well.

print(str(0b0101) , type(str(0b0101)))

5 <class 'str'>

Python interpreter take the decimal equivalent of binary , octal or hex numbers in his memory. When converted to string, original values of these converts can not be restored. One strnge way to convert to string and retain the original value is given below.

print(bin(0b0101) , type(bin(0b0101)))

0b0101<class 'str'>

A very strange way of course!!!

3.1.2 -Float to String

nr_float=str(23.97)

print(nr_float , type(nr_float))

23.97 class<'str'>

3.2 - Conversion to Integer

The need for conversion to integer arises for two cases :

• Conversion from floating point to integer
• Restitution of original values from the previously string converted values.

3.2.1 - Float To Integer

Conversion of a floating point value to the integer is realised with the tranforming the floating point value to an integer. There is three ways to achieve thisk task :

• Truncating the decimal part. That is done with int()
• Reducing to the lowest and elevating to the highest value. The function math.ceil() returns an integer, whose value equals to the highest value of the data, i.e added 1 and truncating the decimal part, math.floor() returns an integer, whose value equals to the lowest value of the data. This the same as truncating the decimal part. For example math.ceil (43.16) will return 43 and math.floor(43.16) will return 44 as a result.

Example :

print(int(12.5557))

12

print(math.floor(12.5557)

12

print(math.ceil(12.5557)

13

Restitution of the data preconverted to string type is always possible via int() function.

t =16

t=str(t)

q=int(t)

print(q ,type(q))

print(q+2)

16 class<'int'>
18

First, we assign 16 to t. The value of the variable t is now integer. Then we convert t to string. we restitute t again to integer. That is supported, verified by type checking and realising an arithmetic operation.

w=0b0110101

w=str(w)

ws=int(w)

print(ws ,type(ws))

print(ws+2)

print(bin(ws) ,type(bin(ws)))

53 class<'int'>
55
0b0110101 class<'str'>

Now, we have the same cycle, but this time our attribute is a non-decimal integer. We could convert it to string and restore back, but this time the restored value is not the original, but the decimal equivalent of the original value. We could restitute the original value in the last line of the code, but the restituted value is in "string" type and not suitable to the arithmetic operations.

4 - String Formatting

Some methods defined for string data type is mentioned in pyton-course-eu. These methods are only supported in Python versions up to 3.6. General methods of string formatting is found in official Python documentation. Many other resources are given at the bibliography of this article.

4.1 - Justifying Strings

There is 4 methods for justifying of strings in a new versions of Python. These are,

• center(...)
• ljust(...)
• rjust(...)
• zfill(..)

4.1.1 - Centering

Using center adjustment is as follows :

S being a string,

print(S.center(width[, fillchar])

As seen from the definition width is compulsory and fillchar is optional. Default fillchar is an empty space. Otherwise any character may be chosen. Padding is done with the centering of the length of the string in the middle of the width specified and filling the both sides with the fillchar. As an example,

S="Atatürk"

print(S.center(20,"*"))

******Atatürk*******

Usage :

S.ljust(width[,fillchar]

Example:

print(myString.ljust(16,"-"))

Usage :

S.rjust(width[,fillchar]

Example:

hobby = "Cycling"

print("My best hobby : ", hobby.rjust(20,"."))

My best hobby : .............Cycling

4.1.4 - Zfill

Usage :

S.zfill(width)

Zfill, fills the remaining places with 0 after right adjusted the string to a specified width.

Example:

myTicketNumber = "121346"

print("Number in the ticket : ", myTicketNumber.zfill(10))

Number in the ticket : 0000121346

Zfill (Zero Fill) is in fact, a replacement of rjust(...) and can be replaced by this. As depicted in the example below :

myTicketNumber = "121346"

print("Number in the ticket : ", myTicketNumber.rjust(10, "0"))

Number in the ticket : 0000121346

The results are the same.

5 - Formatted Strings

Formatted strings came with Python 3.6 these are in fact replacement methods and can also be arranged by classic and modern format() type replacement printing. The advantage of this method is that do not need string data in the replacement. The usage of this method is best understood by the examples below.

BatchNumber = 237856

print(f"Team 16 produced the lots of the batch number {BatchNumber}")

print(f"Batch number {BatchNumber} is produced by team 16")

Team 16 produced the lots of the batch number: 237856

Batch number 237856 is produced by team 16

Some automation :

production = "(Produced in Switzerland)"

for item in ["FMChain", "Front wheel", "Rear Glass"]:

print(item,f" {production}")

FMChain (Produced in Switzerland)
Front wheel (Produced in Switzerland)
Rear Glass (Produced in Switzerland)

This method is efficient in the automated printouts.

These were the basic procedures of the usage of the print () function of the Python.

6 - Classic Style

Priting with a classic style is in fact very efficient style of printing procedure shared with many computer programming languages, among them the most remarquable is the Python's newcoming rival Julia.

Classic style of printinting beneficies with the type specifiers, displayed with % and data providers displayed also with % sign. In general the usage is like,

print("% [Flags] [Width] [.Precision] Type % [Flags] [Width] [.Precision] Type

..." %(Data0 , Data1 , Data2 , ...)

Here,

• Flags stand for the adjustement of the output.
• Width is the total number of spaces reserved for the entire output. including negative sign and the point (if are existing)
• Precision is the number of spaces reserved for the decimal part of the data (if exists)
• Type is the type specifier indicating the type which the data is to be converted.

Note that with type specifiers anything is optional except the type specifier. For data, the only restriction is to provide entries compatible with the type specifier in the sequence of application.

The type specifiers and the data in the (exchange/convert) queue is intrisically given an execution queue number, so that any type specifier meets the mutual data in the data sequence. But in classical way, these sequence numbers are not acessible for the user.

We will present the values supported by Python 3 interpreter for formatting data to printed. These are valid for either classical and for the modern way of printing data.

Flags
Flag Explanation
# When used with o,O,x and X specifiers, the value is followed by 0 , 0o , 00 , 0x , 0X
0 The result will be padded by zero's if there is some place left.
If there is not a minus sign, a blank space will be inserted between the message string and the result.
+ Minus or plus sign will be inserted instead of blank space.

Most Used Type Specifiers
Corvert to Explanation
d Total signed decimal integer digits.
o Unsigned octal integer digits (lowercase).
O Unsigned octal integer digits (uppercase).
x Unsigned hex integer digits (lowercase).
X Unsigned octal integer digits (uppercase).
e Floating number exponential format (lowercase).
E Floating number exponential format (uppercase).
f or F Floating number format.
s Convert to string.
% No conversion.

There is also %r and %a converters defined in Python. But, they are not very common. The %r converter converts any data to string, equivalent of %s in basic formatting and %a converter return ASCII codes of the data characters.

We will exploit these printing possibilities by concrete examples and by analysinig the results obtained by examples.

First we will consider only the examples which deals with the exchange of the same type data then we will see the examples of type conversions via type specifiers.

6.1 - Exchanging with String Type Specifier

print("%s%s"%("Paris","Rennes"))
ParisRennes

Well, as the argument of the print() function, there is a message string which includes type specifiers and the type specifier part in the parenthesis which follows a modulus operator.

Message string is responsible of the half of the printed result. Message string has his content, as a character or white spaces and type specifiers indicated with one ore more modulus operators. In this example message string suggest that there would be no white space between the city names and it is clearly reflected in the output string. Coming to other half, the format specifiers part does not preclude some blank spaces for the output string and nothing comes also from this half. In the output below, no separation spaces is observed in the output, but this is also is not a good style of viewing when printing any data with a computer program.

To remedy this, we have many ways to apply. One method is to arrange the message string so that one blank space separates two output items.

print("%s %s"%("Paris","Rennes"))
Paris Rennes

The other way is to arrange the format specifier so that there is a predefined spaces for printing the data and aligning it with a specified style.

print("%-010s%s"%("Paris","Rennes"))
Paris     Rennes

This means,

• prepare 10 blank spaces for the data,
• write the data left aligned,
• fill the rest of the blank spaces with 0 (invisible).

This is clearly visible in the output. 10 blank spaces are reserved for the first item, and Paris is written in beginning with his own 5 spaces, the remaining 5 spaces are filled with zero, but hey are invisible in the classic formatting. Then in the 11 th. space begin with R of Rennes, it will end with all the places needed for Rennes, since the two modula signs are juxtaposed with no spaces between them in the message string, second modula sign does not define any additional spaces and the data contains no additional spaces either.

6.1.1 - Truncating and padding :

With classic style, one can truncate long strings :

print("%10.7s"%("Turkmenistan"))
Turkmen

print("%-010.7s"%("Turkmenistan"))
Turkmen

6.1.2 - String Types

String type identifier, converts any valid data to the string type.

6.1.2.1 - Integer To String

t = 86

print("Result : %s  type of the result : "%t , end = " ")

print(type("%s"%t)

Result : 86 type of the Result : <class 'str'>

All blank spaces are due to the message string, formatting does not play any role here.

6.1.2.2 - Float To String

t = 41.43

<print("Result : %s  type of the result : "%t , end = " ")

print(type("%s"%t)

Result : 41.43 type of the Result : <class 'str'>

t = 23.3467E-3

print("Result : %s  type of the result : "%t , end = " ")

print(type(t)) "\t"# We may choose not formatting

Result : 0.0233467 type of the Result : <class 'str'>

t = 23.3467e-3

print("Result : %s  type of the result : "%t , end = " ")

print(type(t))

Result : 0.0233467 type of the Result : <class 'str'>

6.1.2.3 - Binary To String

t = 0b011101001

print("Result : %s  type of the result : "%t , end = " ")

print(type(t))

Result : 233 type of the Result : <class 'str'>

6.1.2.4.- Octal To String

t = 0o74

print("Result : %s  type of the result : "%t , end = " ")

print(type(t))

Result : 60 type of the Result : <class 'str'>

6.1.2.5 - Hex To String

t = 0x234

print("Result : %s  type of the result : "%t , end = " ")

print(type(t))

Result : 564 type of the Result : <class 'str'>

Binary, octal or hex values are converted to string with their decimal counterparts actually stored in the internal memory. They can be returned back with appropriate classic (and modern) formatting methods which will be described sooner to their original values.

6.2 - String Concatenation When Printing

Any string type data may be concatenated with other string type values.

print("The common value of pi is used as"+ "%s" % "3.1416")

The common value of pi is used as 3.1416

As opposed to :

print("The common value of pi is used as %s" % "3.1416")

The common value of pi is used as 3.1416

6.3 - Exchanging with Integer Type Specifier

Integers are described by %d in formatting style (d is used for invoking decimals, but it works for all integer compatible types). Only numeric data can be converted to an integer type. Strings may not be converted to the integer types with a style conversion and printing, even though they contain a numeric value.

6.3.1 - Float to Integer

Floating point types can be converted to integers, but with the cost of truncation

print( "They'r about %d quids each." % 3.34)

Note that, there is no need to apply this printing style, because the same output can be exactly obtained from appropriate argumentation of the print() function. That is why, that most experts believe that the classical style will sooner or later be deprecated in favor of the modern printing style introduced with the release of the version 2.6 of the Python.

6.3.2 - From Binary Integer to String with Equivalent Decimal Numeric Content

This is very controversial, since attempting to convert to a decimal integer any non-decimal integer, results the data is converted in fact to the decimal data but not to the integer type, rather to a string whose content is the decimal equivalent of the non-decimal data.

t = 0b0100111

print("Result : %d  type of the result : "%t , end = " ")

print(type(t))

Result : 39 type of the Result : <class 'str'>

6.3.3 - From Octal Integer to String with Equivalent Decimal Numeric Content

t = 0o1223

print("Result : %d  type of the result : "%t , end = " ")

print(type(t))

Result : 659 type of the Result : <class 'str'>

6.3.4 -From Hex Integer to String with Equivalent Decimal Numeric Content

t =0xccab

print("Result : %d  type of the result : "%t , end = " ")

print(type(t))

Result : 52395 type of the Result : <class 'str'>

6.3.5 - From String With Decimal Content to a String with Binary Equivalent Content

In this case preconversion to binary decimal is necessary. After this conversion the decimal integer data is converted to a string with a binary equivalent of the decimal data. Then it will be required an %s instead of %d for only transfering to print the data already transformed to a string type.

t =39

t =bin(t)

print("Result : %s  type of the result : "%t , end = " ")

print(type(t))

Result : 0b100111 type of the Result : <class 'str'>

6.3.6 - From Decimal Integer to a String with Octal Equivalent Content

t =659

print("Result : %o  type of the result : "%t , end = " ")

print(type(t))

Result :1223 type of the Result : <class 'str'>

6.3.7 - From Decimal Integer to a String with Hex Equivalent Content

t =52395

print("Result : %x  type of the result : "%t , end = " ")

print(type(t))

Result : ccab type of the Result : <class 'str'>

There is no need to apply style here, since all these printouts may be obtained from normal usage of the print()function itself.

print ("Result : ", oct(267)," , Type of the Result : ",type(oct(267)))

Result : 0o413 Type of the Result : <class 'str'>

print ("Result : ", hex (322) ," , Type of the Result : " ,type (hex (322)))

Result : 0x142 Type of the Result : <class 'str'>

print ("Result : ", hex (-0o166) ," , Type of the Result : " ,type (hex (-0o166)))

Result : -0x76 Type of the Result : <class 'str'>

String types with a numeric content can be converted to the apropriate numeric type.

print ( "Result : ", int ("3") ," , Type of the Result : ",type (int ("3")))

Result : 3 , Type of the Result : <class 'int'>

print( "Result : ", float ("3.12") ," , Type of the Result : ",type (float ("3.12")))

Result : 3.12 , Type of the Result : <class 'float'>

6.4 - Floating Point Types

Working with floating point data needs a little more attention, since floating point data is composed with or without a sign and an integer part followed by a point and the number of places reserved for the decimal part. All these should be formatted properly.

A formatter for the floating point number consists,

• A total spaces number
• A format designator (f or E or e) (f for normal decimals, E and e for exponential notation as 1.2E5 or 1.2e5

General scheme for floating points :

{Total number of spaces} (including algebraic sign, point and spaces reserved for floating part){.}{Number of spaces reserved}{format converter}

Let us say 6.2f , that means the number is represented as a normal decimal number with total 6 spaces and 2 decimals, then 2 places are reserved for decimals, one for the point, 3 for the integer part. If the number is a negative number, then one place will be added for the sign and we will have 3 places for the integer part. But no worry! Python will provide extra spaces when there will be a less than the needed spaces in the format statement. More, onthe f format in the section of the modern format method in this article.

We will make some examples with leading zero, so that one can understand the number of spaces used for the viewing the data. Normally one format without leading zero.

print( "The price is : %06.2f" %(23.86))

The price is : 023.86

Notice that there are six reserved places, 2 is used for the decimal part, one for the point and remaning three for the integer part. Since with 23.86 ve need for the integer part only two places, the place at the beginning is left blank, as may be clearly visible by the format 06.2f. We will repeat the printing process with a format 6.2f.

print( "The price is : %6.2f $" %(23.86)) The price is : 23.86$

This time, we do not have a leading zero in the numeric part of the output.

If the same number would have a negative sign as -23.86, then the assigned format specification will fit exacly this data.

print( "The result is : %6.2f" %(-23.86))

The result is : -23.86

If the length of the decimal part exceeds the places reserved, then, Python interpreter will provide enough spaces as the decimal part is written always not to exceed the reserved places but he last number is adjusted to the nearest integer.

print( "The result is : %6.2f" %(-23.86656))

The result is : -23.87

When the actual length of integer part of the data exceeds the places indicted by format specifier, Python interpreter, will make necessary adjustement with extending the decimal places by its own, so that no any digits of the input are lost.

print( "The result is : %6.2f" %(-44423.25))

The result is : -44423.25

Looking to the results f format is outstanding flexible as interpreted by the Python interpreter. The only thing to be well defined is the number of digits of the decimal part. If we do not exceed the actual length of the data, 6.2f or 9.2f will result the same visualisation for -44423.25. If we exceed 9 digits for the format specification i.e. 10.2f for -44423.25 then the result will shift one place to the right.

print( "The result is : %9.2f" %(-44423.25))

The result is : -44423.25

print( "The result is : %10.2f" %(-44423.25))

The price is :   -44423.25

X or x format is for formatting in exponential format. Since S.I system (Systeme International d'Unités) allows for one integer character followed by the decimal point and E or e followed by the decimal part, we will follow this specification.

print( "Positive floating number, big E exponential format 1123456 : 1.6E+06" %(1123456))

Positive floating number, big E exponential format 1123456 : 1.123456E+06

print( "Positive floating number, small e exponential format 1123456 : 1.6e+06" %(1123456))

Positive floating number, small e exponential format 1123456 : 1.123456e+06

Conversion to string :

Python can convert numeric types to string trough str() function. We can control the success of conversion by type() function.

print ( "Result : ", str (3) ," , Type of the Result : ",type (str ( 3)))

Result : 3 , Type of the Result : <class 'str'>

String types can only be concatenate but this will not produce an addition. By concatenation, the content of the two or more strings are put one after another in order to produce a single string.

print("Result : ", "23" + "16" )

Result : 2316

With strings, it is not possible to make any other arithmetic operations than the concatenation.

String types with a numeric content can be converted to the apropriate numeric type. But, in this case we should use an appropriate converter for this purpose like int() for "12" and float() for "28.6346". The converted values are of numeric type and all the arithmetic operations are permitted.

print ( "Result : ", int ("3") ," , Type of the Result : ",type (int ("3")))

Result : 3 , Type of the Result : <class 'int'>

print( "Result : ", float ("3.12") ," , Type of the Result : ",type (float ("3.12")))

Result : 3.12 , Type of the Result : <class 'float'>

Floating point types, are truncated when converted to the integer.

print ( "Result : ", int (3.8942) ," , Type of the Result : ",type (int (3.8942)))

Result : 3 , Type of the Result : <class 'int'>

Some attractive printouts may be devised by this so called “old style”.

Making the lists :

print( "The price of Tomatoes : %s pences per %s" %("16", "pound"))

print( "The price of Potatoes : %s pences per %s" %("18", "pound"))

The price of Tomatoes : 16 pences per pound

The price of Potatoes : 18 pences per pound

Some automation is always possible :

class myClass (object):

def __repr__ (self):

return('Turquoise')

print('%s ' % myClass())

print(myClass())

Turquoise

Turquoise

As a result, classic style formatting has some advantages over the system's print() function. But, classic style will be soon or later be depcrecated in favor of the modern format() function. That is why we should no longer rely to the classic style and concentrate ourselves to the modern format() style of pretty print formatting.

7 - Modern Style

7.1 - Introduction to Modern Style

Modern style of the data visualising with python begun with the introduction of the version 2.6 ofPython. It is really a revolutionary procedure never seen before in any programming language. That is well but mastering with it may take time. Many programmers stick with the classic style for avoiding the steep learning curve of the modern way.

The modern printing procedure has an application scheme given below :

print( " message". format (pos1 , pos2 , ..., posn , kwarg1 = value , kwarg2 = value , ... , kwargn = valuen))

This template may seem enigmatic at the first sight, but it will be found quite simple after using continually in our applications

Format specifications :

format_spec     ::=  [[fill]align][sign][#][0][width][grouping_option][.precision][type]

fill            ::=  <any character>

align           ::=  "<" | ">" | "=" | "^"

sign            ::=  "+" | "-" | " "

width           ::=  digit+

grouping_option ::=  "_" | ","

precision       ::=  digit+

type            ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

It can be seen that all the format specifiers are in fact optional. But for obtaining some elegant printouts we should apply this modern format() function.

7.2 - Arguments of the format() function

The format() function may have as many arguments as the need arises. These arguments are for accessing data from the message string with {[format specifier]}. Since format specifiers are optional, bringing the data to the message string can be achieved using three ways :

• Only as {} with the intrinsic indexes of occurence, beginining with zero.
• {Number of explicit index of occurence, beginining with zero}
• with names.

7.2.1 - Accessing with the Intrinsic Sequential Order Indexes of the Arguments List

In this case we use only {} in the message string. This is "First Come, First Serve" principle. First occurence of {} in the message string is indexed as zero. It will find his counterpart in the first argument of the format() function and bring him to the message string at the exact place where it is called. Example :

print( "The {} ! We have reached to the {}!" . format ("port" ,"target" ))

The port ! We have reached to the target !

Well, an example is worth of millon words. We can see from the example above, the actual meaning of the format version of the print()function.

The positional arguments are defined in curly parenthesis as {[0]} , {[1]} etc. They are indexed from 0 to n, their indexed usage is in fact optional, but their usage with explicit indexes is always beneficial.

İn this example, the first format specifier {} (First from the left, after "The") is intrinsically marked as zero. In the other part, the intrinsically zero indexed first argument from the left of the format() function is "port". The zero indexes, corresponds to each other and the argument with index zero is transported to the message string and replaced the zero indexed format specifier {} which is in fact is {0} intrinsically. So proceed the subsequent arguments called with their indexes augmented intrinsically.. At the end, we have the message string reassembled reflected in the printout, just as the printout of the example shown above.

Counting from the left, the first positional argument is the one indexed 0, his counterpart is "port", the counterpart of the second positional argument, i.e. the one that has index 1 is "target". Note that they are all strings but only for this example. They might be in any data type without restriction.

7.2.2 - Accessing with the Explicit Sequential Order Indexes of the Arguments List

The best is to show explicitly the indexes of the positional arguments.

print( "The {0} ! We have reached to the {1}!" . format ("port" ,"target" ))

The port ! We have reached to the target !

We can reverse the printing of the sequence of the counterparts by changing the place of the callers. That is why this is always a good practice to use them.

print( "The {1} ! We have reached to the {0}!" . format ("port" ,"target" ))

The target ! We have reached to the port !

A surprising action, interesting in fact! But in reality one will seldom need it! This opens up a choice of not to show the positional indexes when they are not in immediate need.

In the positional arguments, one can also state the format specifiers for formatting the counterparts.

For the integer data, formatting is straightforward :

print( "Amount Ready For The Shipment : {0: 3d} {1}." . format (128 , Parcels))

Amount Ready For The Shipment : 128 Parcels.

In addition of these, there is also possibilities for the alignment of the printed data explained is the table above. We repeat for the sake of stressing again in the table below.

 Symbol Definition < Left Aligned (Default for string types) > Right aligned 0 Preceded with zeros , Thousands separator = Padding after the sign (if there is one) but before any numeric character. Only with numeric data ^ Centering

like ,{:>b10s}

As an example we take "12" aligned to the right end to the allocated 6 blanks :

print(" {0:>6s}".format("12"))
1 2

For better understanding what is going on, it may be helpful to illustrate with a padding character like (b). Any character will go but (b) is chosen only because it is the first character of (b)lank.

print(" {0:b>6s}".format("12"))
bbbb12

Here, we clearly see that 6 blank spaces are right justified as the statement indicates. So last two spaces are occupied with the data which only needs two spaces for printing. The rest is filled blank spaces.

Printing data is left aligned by default (in contrast to the classic style) and there might be no need to indicate an additional left alignment code when printing data as left aligned.

print(" {0:b6s}".format("12"))
12bbbb

That will be the same if we have inserted the left alignment character,

print(" {0:b<6s}".format("12"))
12bbbb

Sometimes, blank characters may be extremely useful :

print("{0}   {1:->6s} {2}".format("Replacement Cartridge","12", "US $/ per Item")) Replacement Cartridge ----12 US$ / per Item

Here, the zero'th block, tells us nothing but the bare replacement of the first string data ("Replacement Cartridge") The first block, tells us taking the second text data ("Replacement Cartridge"), reserve 6 blank spaces, align the data to the left, fill the rest of the reserved blank spaces with "-". The third block is also a replacement block and brings the last string data ("US \$ / per Item") just left aligned as being the default for format type formatting.

Alignment can also be made to the middle of the area whose length is specified for printing the data.

print(" {0:b^6s}".format("12"))
bb12bb

For the floating point data, for an accurate format, we should state the format that we are intending the display data. For example 2.2f, say that the floating point data would be displayed with 2 integers, one point and 2 decimal numbers that makes 2+1+2 = 5 base length, needing exactly 5 blank spaces to allocate the foreseen display. Any specification as 1.2f will indicate the deficit in the reserved space, so Python interpreter will allocate the needed spaces for the display regardless of the deficiency in the statement. This will go up to 5.2f which is the exact specification for the data. When the spacification exceeds it like 6.2f, there will be a surplus for the allocation spaces needed for the display of the actual data, nevertheless 6 spaces will be allocated by the Python interpreter. Data will right adjusted to this area 5 spaces will be filled by the data and the remaing one blank space will be displayed in front of the data. For 7.2f there will be 2 blank spaces inserted in front of the data and so on...

For the signed data as -12.20 the base length is 1 for the sign+ 5 for the unsigned data totalling 6 spaces. the exact specification for this data is 6.2f and less than that will indicate a deficit, more than that will indicate, a surplus that will be reflacted to the display by adding blank spaces in front of the data. The examples below will clarify the usage of floating point formatting.

What if we do not know exact length of the data? if we wish to reflect the actual computer generated data we can simply state f in the specification.

print( "12/5.89556 = {0:f} " . format (12/5.89556))

12/5.89556 = 2.035430

Or we do not know exact value of the data but we wish that it would be printed with only two decimals.

print( "12/5.89556 = {0:0.2f} " . format (12/5.89556))

12/5.89556 = 2.04

Another example :

a = 234

b = 120

print("Percent of b in a = {0:0.2f}".format(b/a*100))
Percent of b in a = 51.28

7.2.3 -Accessing with the named elements of the Arguments List

Named elements may be used in the modern format method of the print object.

print(" {John} boxes of {mark} {stones}

has sent to {Ethan}.".format(John= 4, mark = "Context",

stones="drinking water",

Ethan = "Swiss Cottage agent"))

4 boxes of Context drinking water has sent to Swiss Cottage agent.

7.3 - Examples of Modern Output Formatting

In these examples we will use mainly explicitly defined indexed and named access methods.

7.3.1 - Named Access with Default Justification

The format() method, right justifies by default as experienced from the example below :

print(" {Flowers :\n     {Flower} .......{Price} {Amount}.".format(Flower = "Roses", Price = "1 £", Amount = "each"))

Flowers :

Roses .......1 £ each.

Note that the modern format() method of the print() fonction, right justify the objects by default, but other justifying methods are possible of course. As well as other access methods other than the "name" access.

7.3.2 -Sequential Access By Virtue of Intrinsic Indexes with Left Justification

In unsophistical works, simple access like the program below, will be more than enough.

print(" We are proud of our {:<6s} kitchen {:<10s}.".format("modern", "appliances"))

We are proud of our modern kitchen appliances.

Access as {:} means, sequential access without explicitly stating access index. Access will be done by the sequential order of the attributes given in the format() method. In this context, one can access the first attribute i.e. "modern" by the 0 th. index and the second attribute "appliance" by the index value of 1. Nevertheless, we may not state the indexes explicitly, since Python interpreter takes account of them for us, as practicised in the example above. We say {:}, Python interpreter understands {0:} or {n:} depending on the realm.

7.4 - Access by the Variable names

One can access the attributes of the format() method by defining them as variables.

m = "Motocycle"

e = "education"

p = "practice"

print("{} driving is extremely dangerous and needs substantial {} and {}.".format(m , e , p))

Motocycle driving is extremely dangerous and needs substantial education and practice.

Accesses may be defined as {} or {:} or {0:} {1:} and {2:}. The result will be unchanged.

That opens the opportunity for defining the arguments of the format() method as the elements of the lists, tuples, dicts, or return values of the functions. No sets, because set elements can not be indexed. We will exploit hem one by one.

7.4.1 -Access as the Elements of a List

d = ["Birds","cats"]

print("{0:} and {1:} can be house pets.".format(d[0],d[1]))

Birds and cats can be house pets.

7.4.2 - Access as the Elements of a Tuple.

d = ("Birds","cats")

print("{0:} and {1:} can be house pets.".format(d[0],d[1]))

Birds and cats can be house pets.

data = dict(b = "Birds", c="cats")

print("{b} and {c} can be house pets.".format(**data))

Birds and cats can be house pets.

7.4.4 - Access with the Return values of a Function

class myClass (object):

def __str__ (self):

return('Turquoise')

def __repr__ (self):

return('Açık')

print("{0!s} {0!a} {0!r}".format(myClass()))

Turquoise A\xe7\u0131k Açık

Quite interesting! In modern format method there is a possibility to extract unicode conversion of the ASCII data by repr conversion factor. The obtained Unicode values can be printed to obtain original characters.

print("A\xe7\u0131k")

Açık

This method is of course not convenient for printing what is returned by %s Simply print( "Turqouise") that is all! But it is very convenient for an ascii conversion. It is fast, without hassle and much better than running in the conversion tables.

7.5 - Access Via Docstring

A very interesting access method using Docstring is defined below.

John = "John van Holm";

Jane = 'Jane Doe';

print("""Best Employees of the Month :

1 - {0}

2 - {1}

""".format(John , Jane));

Best Employees of the Month :

1 - John van Holm

2 - Jane Doe

This is very convenient for making lists.

Note : The original css program of this article is open at http://www.bedriemir.com/Python/css and is particularly good for the web viewing of the Mathematica files. In addition two sophistically designed css programs which are graciously made open by the site https://pyformat.info/ is used. The author is highly indebted to Simon Whitaker designer of these meticulous css programs.

Nothing is original in this article, all the programs are shared mainly from the sources mentioned in the literature list. However, all the programs are fully tested mainly by Pyscripter

For being compétant in Python printing, it is advisable to leave all the default and classic style printing, concentrate on the modern printing procedures, even for the simplest printing works, with stating explicitly the indexes and the printing properties of the data to be printed. One will gain expertise very soon and gradually lesser consult the printing procedure articles.

Note : Python programming language becomes one of the scientific programming platform. But this make also an impossibiliy to implement the language with all resolved inconsistencies. It is advised to use Anaconda as the best platform for the Pyhton programming language with scientific oriented working extensions.

First download Anaconda from https://www.anaconda.com/distribution/ and select 64 bit distribution.Install to the default folder.After the installation, from windows start menu choose Anaconda prompt. A command line window will be opened. Input,

conda update conda

After this ,enter

conda update spyder

Then from windows start menu run Anaconda Navigator and from there install Visual Studio Code. A very instructive web site,maintained by Christiaan Dollen will be helpful for setting up the environment.

Launch spyder or notebook and run your programs. The editors like Visual Studio Code or Eclipse are text based and do not show plotting results. They are only useful for programs without plottings. There is some examples and some others in the example files, developed by the author of this article.

Happy printing...