Search

Python Print() Function: How it works

One of the ubiquitous and most often used functions in python is the python print function. We use it for realizing the output of our codes and even for debugging. So, it is pertinent that we understand how it works.

python print

 

In its essential form what the python print function does is to take a given object, convert it to a string object and print the value out to the standard output, or what is called the screen. It can even send the output to a file.

The python print syntax

The python print function despite its wide ranging value has a simple syntax. The syntax of the python print statement is print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False). I will be explaining each of the arguments in this post. So, just take note of the syntax.

Usually when you want to print something to the screen you provide the python print function with an object or several object arguments. If you don’t specify other parameters, what the function does is print each of the arguments to the screen, each separated by empty space and after all the arguments are printed, to go to a new line. Let’s illustrate this with an example and explain how it relates to the syntax.

When you run the code above, you will see that it nicely prints out each of the objects to the python print function. Here is what happened. I passed it 5 objects and it prints out the five objects each separated by a space. The separation by a space comes about from the sep parameter in the syntax above. The sep means separator. By default its value is a space. Notice that I cast one of the objects to a string before printing it out. This is a trick to make the period adhere to the value of the string. Very cool. We can change the value of the separator. I will highlight it in the separator section below.

Now what happens if we print without passing an object. Let me give an example following from our example above.

You can see that I repeated the earlier code. But on line five I wrote a print statement without giving it any argument or object. If you look at the output on the screen, you will see that it translated it into an empty space. Yes, without any argument the python print function just looks at what is at the end parameter and since the default is a newline, ‘\n’, it creates a new line.

Now let’s see how we can customize the working of the python print function using the keyword parameters outlined in the syntax.

Customizing python print with the sep keyword

The sep keyword separates each of the objects in the python print function based on its value. The default is a whitespace character. That means if you use the default, as outlined above, each of the objects when printed out will be separated by a whitespace.

What if we want another separator on python print, like we want a colon, :, to separate each of the objects to be printed. Here is code that could do it.

If you watch the output to the screen, you could see that each of the objects that was passed to the python print function now has a colon separator between them.

You could create any separator of your imagination. Most times when I have specific ways to print an output it could call for my customizing the separator.

Customizing python print with the end keyword.

The end keyword is another parameter that we could use to customize the python print function. As I highlighted above where I printed a print function without objects, the default for the end keyword is a newline, ‘\n’, which creates a new line after printing the objects. That means python print adds a newline to each line. Most times when I want python print without newlines, that means, subsequent lines of objects to print on the same line, I customize the end keyword. You just replace the default with a space character, ‘ ‘, which signifies to concatenate all the subsequent lines on one single line.

For example, you have code you want printed in the same line. Here is the code that could do it.

You can see that by customizing the end parameter to a space, I have made all the objects in the python print function print without newline to the same line.

How to print to file using file keyword

Most usually when you call the python print function, it prints to standard output, that is, the screen. That is the default. I will show you how to print to a file. You can customize it to print to a file by specifying a file object as the value to the file parameter which file object should be writable. For details on how to open, read, and make files writable, see this blog post.

Now, let’s take an example. This time instead of printing to the screen we will be printing to a file or writing to a file. Here is the code:

    
text = 'I feel cool using python.
        \nIt is the best programming language'
with open('new_file.txt', 'w') as source_file:
    print(text, file=source_file)

You can run it on your machine. When you do, rather than getting the text message to your screen, it will print to the file, new_file.txt. If new_file.txt doesn’t exist, it will create one.

One thing to note about file objects passed to the file keyword – you cannot use binary mode file objects. This is because python print function converts all its objects to the str class (strings) before passing them to the file. So, note this and if you want to write to binary mode file objects, use the write methods that are built-in for file objects.

You must really be feeling empowered with all the cool features in python print function. I am. You can subscribe to my blog or leave a comment below. I feel happy when I believe I have made an impact.

Happy pythoning.

Simulating A Random Walk In Python

Deterministic processes are what every programmer is familiar with when starting out in their journey. In fact, most beginner books on programmer will teach you deterministic processes. These are processes where for an input, you always get the same output. But when you get into industry, you find out that most times stochastic processes are the norm when finding solutions to problems. Stochastic processes give different results for the same input.

random walk python

 

In this post, I will be simulating a stochastic process, a drunkard’s walk, which is an example of a random walk.

Python random walks are interesting simulation models for the following reasons:

  1. They are widely used in industry and interesting to study.
  2. They show us how simulation works in practice and can be used to demonstrate how to structure abstract data types.
  3. They usually involve producing plots which are interesting and as they say, a picture is worth a thousand words.

So, let’s go to the simulation exercise. It is interesting to find out how much distance a drunk would have made from his starting position if he takes a number of steps within a given space of time. Would he have moved farther after that time, would he still be close to the origin, or where would the drunk be? Such questions can only be simulated for us to get a general idea of the drunk’s position. We’ll imagine that for each movement, the drunk can take one step either in the north, south, east, or west direction. That means he has four choices to choose from for each step.

To model the drunk’s walk after some time, we will be using three classes representing objects that define his position relative to the origin: Location, Field, and Drunk classes.

The Location class defines his location relative to the origin. We could write code for the class this way:

    
class Location(object):

    def __init__(self, x, y):
        ''' x and y are numbers '''
        self.x, self.y = x, y

    def move(self, delta_x, delta_y):
        ''' delta_x and delta_y are numbers '''
        return Location(self.x + delta_x, self.y + delta_y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def dist_from(self, other):
        ox, oy = other.x, other.y
        x_dist, y_dist = self.x - ox, self.y - oy
        return (x_dist**2 + y_dist**2)**0.5

    def __str__(self):
        return '<' + str(self.x) + ', ' + str(self.y) + '>'

Each location has an x and y coordinate representing the x and y-axis. When the drunk moves and changes his location, we could return a new Location object to signify this. Also using the location class, we can calculate the distance of the drunk from another location, and most possibly the origin.

The second class we need to define is the Field class. This class will allow us to add multiple drunks to the same location. It is a mapping of drunks to their locations. Code could be written this way for it:

    
class Field(object):

    def __init__(self):
        self.drunks = {}

    def add_drunk(self, drunk, loc):
        if drunk in self.drunks:
            raise ValueError('Duplicate drunk')
        else:
            self.drunks[drunk] = loc

    def move_drunk(self, drunk):
        if drunk not in self.drunks:
            raise ValueError('Drunk not in field')
        x_dist, y_dist = drunk.take_step()
        current_location = self.drunks[drunk]
        # use move method of Location to get new location
        self.drunks[drunk] = 
                  current_location.move(x_dist, y_dist)

    def get_loc(self, drunk):
        if drunk not in self.drunks:
            raise ValueError('Drunk not in field')
        return self.drunks[drunk]            

As you can see, the Field class is a mapping of drunks to locations. When we move a drunk, his location reflects this move and we take note of the current location. Also, we can use this class to find out the location of any drunk.

The last class of interest is the Drunk class. The Drunk class embodies all the drunks we will be playing with. It is a common class or parent class as all other drunks will inherit from this class.

    
import random

class Drunk(object):

    def __init__(self, name=None):
        ''' Assumes name is a string '''
        self.name = name

    def __str__(self):
        if self != None:
            return self.name
        return 'Anonymous'

What the Drunk class does is give identity to each drunk object or subclass.

Now, we will create a drunk with our expected way of movement: that is take one step each time in the north, south, east, or west direction. We will call this drunk class, UsualDrunk. Here is the definition of the class.

    
class UsualDrunk(Drunk):

    def take_step(self):
        step_choices = [(0,1), (0, -1), (1,0), (-1,0)]
        return random.choice(step_choices)

The UsualDrunk class inherits from the Drunk class and the only method it defines is the random step it can take. From the take_step method you can see that it can only move one step to the east, west, north or south, and this in a randomized fashion.

So, now that we have our classes let us try to answer the question – where will the drunk be after taking a series of walks in a random fashion? Like taking 10 walks, or 100, or 1000? Normally, we would expect that when the number of walks increases, the distance from the origin should increase. But this might not be the case because you know how drunks walk – haphazardly. Some drunks can even retrace their steps back to where they started and go nowhere!

So, for our simulation, we will write code that makes use of these classes and run the code on the drunk taking a number of steps with different trials for each step. We are using different trials in order to balance out the randomized walk and get a mean of distances.

Here is the code:

When you run it there is one fact that stands out: The mean distance from the origin increases as the number of steps increases. That is the hypothesis we started with.

Some pertinent new driver code are the following:

    
def walk(f, d, num_steps):
    '''Assumes: f a field, d a drunk in f, 
    and num_steps an int >= 0.
    Moves d num_steps times; returns the distance between
    the final location and the location at the start 
    of the walk.'''
    start = f.get_loc(d)
    for _ in range(num_steps):
        f.move_drunk(d)
    return start.dist_from(f.get_loc(d))

The walk function returns the distance from the final location for a single trial based on the drunk taking a number of steps that is defined.

    
def sim_walks(num_steps, num_trials, d_class):
    '''Assumes num_steps an int >= 0, num_trials an int > 0,
    d_class a subclass of Drunk. 
    Simulates num_trials walks of num_steps steps each. 
    Returns a list of the final distance for each trial'''
    homer = d_class()
    origin = Location(0,0)
    distance = []
    for _ in range(num_trials):
        f = Field()
        f.add_drunk(homer, origin)
        distance.append(round(walk(f, homer, num_steps), 1))
    return distance

The sim_walks function (simulated walks) is different from the walk function only in one aspect: it relates to all the different trials that are used for a specific step. Say for a 10 steps walk we did 100 trails so as to get the mean. So sim_walk returns a list of the distances for the trials. This is so that we can take the mean distance for each number of steps since we are randomizing the walk.

And finally, the drunk_test function.

    
def drunk_test(walk_lengths, num_trials, d_class):
    '''Assumes walk_lengths a sequence of ints >= 0
    num_trials an int > 0, d_class a subclass of Drunk
    for each number of steps in walk_lengths, runs sim_walk
    with num_trials walks and prints results '''
    for num_steps in walk_lengths:
        distances = sim_walks(num_steps, num_trials, d_class)
        print(d_class.__name__, 'random walk of ', num_steps, 'steps')
        print('Mean:', round(sum(distances)/len(distances), 4))
        print('Max:', max(distances), 'Min:', min(distances))

This serves as the test of our code. It prints out the mean for each number of steps after doing the various trials and then the max and min for those trials in a specific step.

You could download the above code here, random_walk.py.

But a picture is worth a thousand words. Let us use a plotted graph to illustrate the variation in the number of steps to the distance from the origin.

drunkards walk python

 

You can see from the graph above that when the drunk is taking ten steps for each of the 100 trials, the distance he moves is closer to the origin than when he takes 100 or 1000 steps. But the drunk seems more determined to walk farther away if he is given the opportunity to take several steps. Drunks really mean to get home it seems! A graph of number of steps for each trial to mean distances shows that this is truly the case: the more opportunity he is given to take higher steps, the closer he gets to home and away from where he started with. The graph below shows that information.

drunkards walk python


The scales in the graph have been extrapolated to logarithmic scales to clearly show the straight line relationship between number of steps and mean distance from the starting point. To see how the code for the plotted graphs were written you can download it here, random_walk_mpl.py.

Now, our simulation has dwelt on a drunk walking the way we expect: for each step one unit towards the east, west, north, or south.

What if we could make the drunkard’s walk somewhat biased by skewing it a little. That would involve creating different drunks with different steps and comparing them to our usual drunk.

A biased random walk simulation.

Let’s imagine a drunkard who hates the cold and moves twice as fast in a southward direction. We could make him a subclass of Drunk class and change his way of movement in the class, calling him ColdDrunk.

This could be his class definition:

    
class ColdDrunk(Drunk):
    def take_step(self):
        step_choices = [(0.0, 1.0), (0.0, -2.0), 
                       (1.0, 0.0), (-1.0, 0.0)]
        return random.choice(step_choices)

You can see that whenever he moves southwards, y axis, he takes two times a unit step.

Now let’s also add another hypothetical drunk that moves only in the east-west direction. He really moves with the sun or is phototrophic. We could define his class, EWDrunk, in the following way:

    
class EWDrunk(Drunk):
    def take_step(self):
        step_choices = [(1.0, 0.0), (-1.0, 0.0)]
        return random.choice(step_choices)

So, we have all our drunks ready. Now let’s write code that will run them and compare their mean distances for various number of steps.

If you run the code above you will get a plotted graph that shows number of steps against mean distance from the origin for the three drunks. You will get a graph that looks like the following:

drunkards walk python


You will notice that for both the UsualDrunk, who we highlighted earlier, and the phototrophic drunk, EWDrunk, their variation in mean distance as the number of steps increases is not much compared to the South loving or north hating drunk, ColdDrunk. That means the ColdDrunk, or north hating drunk, is moving faster than all other drunks. This is not surprising based on the fact that whenever he moves south, he moves twice as fast. That means randomly the drunk’s movement is more favorable than the other two.

We could extrapolate on this conjecture and build a scatter plot of the location of each drunk’s movement for each step but I think the point has already been made: simulating a random walk could give us insights into a model and could confirm or deny a hypothesis.

If you would like a copy of the code for the three drunks, you can download it here, random_walk_biased.py.

That’s it folks. I hope you enjoyed this post. I really enjoyed coding it. It was fun.

This helps us to see the insight that plotting a class or set of classes can give to a programmer.

Happy pythoning.

Object Oriented Programming (OOP) in Python: Polymorphism Part 3

Polymorphism is a concept you will often find yourself implementing in code, especially in python. Polymorphism means essentially taking different forms. For example, a function implementing polymorphism might accept different types and not just a specific type.

oop in python polymorphism

 

There are different ways to show polymorphism in python. I will enumerate some here.

1. Python polymorphism with functions and objects.

In this implementation of polymorphism, a function can take objects belonging to different classes and carry out operations on them without any regard for the classes. One common example of this is the python len function, or what is called the python length function. You can read my blog post on the python length function here.

Here is an example of how the python length function implements polymorphism.

You can see from the above code that the python len function can take a str object as argument as well as a list object as argument. These two objects belong to different classes.

Now, not only can built-in functions exhibit polymorphism, we can use it in our custom classes.

I believe you have followed through with the earlier posts on python OOP so the example classes are self-explanatory. If not, you can get the links at the end of this post. I will just dwell on the print_talk function. You can see that we invoked the function in the for loop after creating the dog and person objects. Each time the print_talk function is invoked, different objects are passed to it and it successfully invoked their talk methods. Different objects but same function and different behavior.

2. Polymorphism with inheritance

Polymorphism with inheritance has been discussed in the python OOP inheritance post. I will just briefly highlight it here. It involves a method of the child class overriding the methods of the parent class. The code above shows it but let me point it out again. The method of the child class has the same name and arguments as the method of the parent class but the implementation of the method is different.

    
class Animal:
    
    type = 'Animal'

    def __init__(self, name):
        ''' name is a string '''
        self.name = name

    def talk(self):
        print(f'My name is {self.name} and I can talk')

    def walk(self):
        print(f'My name is {self.name} and I can walk')        

class Dog(Animal):

    legs = 4

    def __init__(self, name, bark):
        Animal.__init__(self, name)
        self.bark = bark 

    def talk(self):
        print(f'My name is {self.name} and 
                    I can bark: "{self.bark}"')

    def walk(self):
        print(f'My name is {self.name} and 
                   I walk with {self.legs} legs')

From, the code above you can see that the Dog class inherits from the Animal class. The Dog class overrides the talk and walk methods of the Animal class and implements them differently. That is what polymorphism in inheritance is all about.

As your skill with python increases, you will find yourself implementing polymorphism in a lot of instances. It is a feature of python that is commonplace.

I hope you enjoyed my three part series on how OOP is implemented in python. The first part was on OOP in python classes and objects, the second part was on OOP in python class inheritance and this is the third part. I hope you have learned something new about python and will be determined to implement these features in your coding.

Happy pythoning.

Matched content