Basics of Python (Best Tutorial 2019)

Python Basics

Python Complete Basics

Python can do many things, especially in the socket and networking field. Additionally, in system monitoring, it has huge importance. In the advanced level of ethical hacking, it can cast a magical spell.

 

You can write your own Python program for any type of security purpose. This tutorial explains the Basics of Python with the best examples. 

 

Remember, any program written in Python or any language does issue some instructions. And they are more or less the same. They are:

  1. INPUT: Get data from a keyboard or any file or any source.
  2. OUTPUT: Display data on screen or send it to any file, device or any other source.
  3. MATHEMATICS: Do some basic mathematical operations like add, subtract, multiply or divide. It can be complex also. It depends on your application.
  4. CONDITIONAL EXECUTION: Check that the conditions are properly met. Like “if that is true then do something else/do some other thing.”
  5. REPETITION: Perform some action repeatedly.

 

Most people used to have a Windows or Macintosh platform at their home. Before you start, I ask you to try Linux as a dual operating system. There are a lot of user-friendly, free Linux distributions available.

 

You can try Ubuntu or any Debian package. Just download the stable ISO image and burn it onto a DVD and install it along with your running OS. It will help. Python comes with every Linux distribution. This tutorial explains the Basics of Python with the best examples and installation. 

 

The available Linux will run inside Windows so whenever you want to try any open source programming language like Python or PHP, you can take advantage of it.

 

You can try the Linux terminal whenever necessary. Basically, Python comes with any Linux Distribution, so you need not to worry about the installation in Linux. That is also a plus.

 

If you want to stick to Windows, please visit the download section of the official Python site. 

 

According to your system configuration, download the “python-3.4.4.tar. xz” file for windows. When you extract that file, you will get the “Python-3.4.4 Windows Installer Package.”

 

Just run it and follow the simple steps. I suggest you download the documentation along with the installer package. This documentation is extremely helpful, not only for beginners but for seasoned programmers. After downloading, open the documentation.

 

This documentation is purely designed for programmers, not for beginners. But as a beginner, you need to accustom yourself to this manual so that after a certain period, it becomes a part of your programming life. 

 

Almost every possible programming problem is discussed in this documentation and, moreover, you can develop the code and create some awesome application with the help of this documentation.

 

Python Environment

Python Environment

You are going to learn Python 3. Python 2 has been around for a long time and has a huge library and module support, but Python 3 is the future language. You can also easily install Python 3.

 

Consult the download section of the official website. In any modern Linux distribution, open your terminal and type “python3”. It will give you the Python interpreter or shell where you can write your code.

 

Remember, Python comes with every modern Linux distribution. So you need not install it anymore. But a few packages you might need to install. There are tons of tutorials and a lot of community help you can get over the Internet.

 

In any modern Linux distribution, you need not to do anything. Open the terminal and type “python3”, and you will have an output like this:

hagudu@hagudu-H81M-S1:~$ python3
Python 3.4.3 (default, Oct 14 2015, 20:28:29)
[GCC 4.8.4] on Linux
Type "help", "copyright", "credits" or "license" for more information.

It says my computer has Python 3.4.3. Now you can write some code directly on it to get some output like this:

  • name = "Sanjib"
  • print(name) Sanjib

In Linux, you save a Python file first. Write this code:

<code>
#!/usr/bin/python3
def main():
print("Hello Python!")
if __name__ == "__main__":
main()
</code>

If you are new to Linux, first save this Python file as “http://hello.py” and then change it to executable with this command: sudo chmod +x http://hello.py

 

On the terminal, run this file with this command: ./hello.py

It will give the output: Hello Python!

This is your first Python code.

 

For Windows, download Python installer and document. The document comes in a “.chm” file. It will help later. To install Python, just run the installer. It will be installed in your “C” drive in a minute.

 

Now you can go to “all programs” and run Python from there. Normally, a small IDE called IDLE comes with Python. You can write code and just run it. Let us see how it looks:

 

In the above image, you see on the top is IDLE, which is the Python Shell. You can directly get output from it. You can also go the file section of IDLE and create a new file.

 

I have done that. I created a file, ”http://test.py”, and wrote some code in it. Then from IDLE, you can either run this module or just press F5 and it will keep running.

 

As you see in the picture, our Python code drew a beautiful shape. In Windows 7 or later, you can open Power Shell and type the same thing and you will get the same result. But I prefer you to install a good Python text editor or IDE first.

 

For Linux, “Pycharm” community edition is a good choice. It is free. For Windows or Mac, there are several good free text editors. Search on the Internet and install. The main advantage is you don’t have to indent every line of code. It is automated. Second, the support of a large Python library is available in every IDE.

 

General Syntaxes

General Syntaxes

In this blog, we will learn something just to try some codes. We will learn the same things in detail later. All we need to do now is just try to write some code in Python and see how it works. At the same time, we will learn about the general syntaxes used often in Python.

 

Create the main( ) function

As I said, Python scripts are almost like a human language. You need not to use a lot of special characters or symbols. All you need to remember is that “indentation” plays a very important role in Python. When you apply some special conditions inside your code, this indentation is important.

 

Few things repeat in every code. So you can write it out in a separate file and just use them in every new Python file. The general syntax structure code looks like this:

<code>
#!/usr/bin/python3
def main():
print("I am a general syntax Python file")
if __name__ == "__main__":
main()
</code>

 

Save this file as “http://general-syntax.py”. When you execute this file, it will say or print out:
“I am a general syntax Python file.”

 

The very first line, “#!/usr/bin/python3”, denotes the path of Python interpreter. 

The greatness of Python is that it remains the same in every operating system. In the second part we have defined a main() function and, under that main() function, we can call any function.

 

Without a main() function, you cannot call a function before it is defined. Consider this example:

<code>
#!/usr/bin/python3
def main():
print("I am a general syntax Python file")
LetUsDoSomething()
def LetUsDoSomething():
print("I am doing something")
if __name__ == "__main__":
main()
</code>

 

Now it will give a nice output like this:

  • I am a general syntax Python file
  • I am doing something

Suppose you don’t have any main() function. Now if you want to call the function LetUsDoSomething() before that function is defined, it will give an error. Try this code and see the error:

<code>
#!/usr/bin/python3
LetUsDoSomething()
def LetUsDoSomething():
print("I am doing something")
</code>

It says: NameError LetUsDoSomething() is not defined. You can always call it after the function is defined. In that case, you don’t need the main() function defined. But in a long line of code where many functions are involved, it is not always possible to maintain it.

 

To solve that problem, it is a good practice to define the main() function first. After that, you can write any function after the main() function and call it inside the main().

 

Indentation and White Space

White Space

They play a very vital role when you work with Python. An indentation or white space is very, very important. Before you start learning Python, you need to understand this properly. Consider this code:

<code>
# coding=utf-8 def main():
print('A line inside main function.') print("A line outside main function.") if __name__ == main():main()
</code>

 

Look at this code. The print() function inside the main() function has been indented. It has about four spaces. And the second print() function is outside the main() function.

 

And look at the code; it falls on the same line with the main() function. So when we run this program, the outside print() function executes first. And the output is like this:

  • //output
  • A line outside the main function.
  • A line inside main function.
  • //output ended

 

If we try to push the outside print() function a little bit inside, it will give an error, because Python interpreter will think that it is inside the main() function. Actually, this is not true.

 

If we want to push that “outside print() function” inside the main() function, we need to place it on the same line of the inside print() function like this:

<code>
# coding=utf-8 def main():
print('A line inside main function.') print("A line outside main function.")
if __name__ == main():main() </code>
Now the output changes. It looks like this:
//output
A line inside main function.
A line outside main function.
//output ended

We learn a very important lesson that we should learn by heart. The lesson is: whitespace or indentation in Python plays a major role. When we write a function and put some other functions inside it, they must fall on the same line. In any text editor or IDE, it is automatically done.

 

When you press the “enter” or “return” key, the following lines keep falling on the same line. If you want to go outside that function, just follow the first example. Just to understand how indentation works in Python, we write a little lengthy code and see how it looks.

<code>
# coding=utf-8 def main():
# print('A line inside main function.')
#
# print("A line outside main function.") OutsideMainFunction()
def OutsideMainFunction():
x = 0
while x < 5:
print(x)
x = x + 1
if __name__ == main():main()
</code>

 

Look at the code. We have a main() function. Additionally, we have a function called “OutsideMainFunction()'”. It is really outside of the main() function. So they are different functions and they have their own indentations. Inside of the “OutsideMainFunction()” we see a “while loop.”

 

That “while loop” also has its own indentation. Actually, we better call it a “block.” So every block of code has its own “white space” or the code inside that block is indented accordingly.

 

If you don't use any IDE and try to write it on your terminal, you have to use the space bar. Inside a function, if you use “four spaces,” then whatever you write inside that function must fall on the same line. That is, whenever you write a new line, it must have “four spaces.”

 

You cannot give two or three space suddenly. But if you write another function, you can change that rule. In that case, the new function has its own block of code and it has its own rule. You may use two spaces now.

 

Commenting

Commenting

In any kind of programming, commenting is very important. Another programmer will read your program. Your every step should be readable. If there is any kind of twist or you try something special, you must explain that inside your code. Consider this code:

<code>
# this is main() function def main():
OutsideMainFunction()
# this function is outside main() function def OutsideMainFunction():
x = 0
while x < 5:
print(x)
x = x + 1
if __name__ == main():main()
</code>

Normally any comment is written with a # (hash) mark. When Python interpreter sees #, it knows that is a comment and it ignores it.

 

In our code, we clearly define what is the main() function and we also say in our comments that there is another function which is outside the main() function.

 

Normally a seasoned programmer never comments such simple stuff. But to begin with, you can add comments when you feel it is necessary. Because after some time, when you revisit your old codes, you can remember why you did that. Commenting is useful in that way.

 

At the same time, you cannot trust all the comments. Programmers often forget to change comments when they change their codes.

 

Assigning Values

Assigning Values

In Python, the assignment operator is an equal (=) sign. When you write “a = 10”, it means “a” is a variable or a container. This variable “a” is assigned to an integer value. What is that value?

 

It is 10. This value could have been a string. What is a string? A string is an addition of characters. Suppose you write “b = Two”.

 

It means the variable “b” is assigned to a string value, and that string is “Two”, which is nothing more than three characters: “T”+“w”+“o”. According to your assignment, Python interprets the value and keeps a definite storage place for them. It knows how many bits and bytes will be required for them.

 

In Python, everything is an object. Python is an object-oriented programming language. As a beginner, you may not understand this concept. Don’t worry. We will discuss it in detail as we progress. You will learn about it. Presently you just remember that an object means an instance of the class. Imagine yourself as an object.

 

In that case, you are an instance of the “human” class. You have some properties like height, width, etc. You also can do something. The “human” class is a blueprint of you and other humans and in “human” class, everything has been well-defined.

 

There are a lot of properties and a lot of action verbs defined. And according to that definition, you, me, and other humans keep doing things.

 

When we say in Python that everything is an object, it means everything has a class or blueprint behind it. We write like this:

<code>
#!/usr/bin/python3
# coding=utf-8 a = 1 print(a) print(type(a)) print(id(a)) a = "One" print(a) print(type(a)) print(id(a)) </code>
And the output is like this:
//output
1
<class 'int'>
139113568
One
<class 'str'>
3073583584
//output ended

In the next blog, we will learn about it in more detail.

 

Variables, Objects, and Values

Variables

In Python, everything is an object. To start with, you need to remember a few things:

\1.\ Variables, functions and even code are objects.

\2.\ Every object has an ID, type, and value.

ID stands for identification of a particular instance of an object. This ID cannot change in the lifetime of that object.

\3.\ Type identifies a class of an object. It cannot change for the life of the object.

 

\4.\ Value is the content of the object and mutable objects can only change the value. Immutable objects cannot change the value.

\5.\ Every variable in Python is a first class object. What looks like a simple variable actually is something more complex.

Let us see what these terms mean.

<code>
#!/usr/bin/python3
def main():
x = 1
print(x)
print(id(x))
print(type(x))
x = 2
print(x)
print(id(x))
print(type(x))
x = 1
print(x)
print(id(x))
print(type(x))
if __name__ == "__main__":
main()
</code>
Here is the output:
<blockquote>
1
10455040
class 'int'
2
10455072
class 'int'
1
10455040
class 'int'
</blockquote>

As you see, changing values of “x” does not affect the immutable objects and the unique identifier of object “1” remains the same.

 

What has been changed is simply the reference of the variable. First, we referred “1” (immutable integer object) to “x” (variable) and then change it. The ID and type remain the same.

 

Remember, numbers, strings, and “tuples” are immutable. Lists, dictionaries, and other objects are mutable (changeable), but it depends. Let us see a very brief example where it is explained in the comment section. The output is given along with it.

<code>
#!/usr/bin/python3
# in python everything is object
# a variable is a reference to an object
# each object has an identity or an ID x = 1
print(type(x))
print(id(x))
# class 'int'
# 139113568
# number, string, tuple -> immutable
# list, dictionary -> mutable
x = 1
y = 1
print(type(x))
print(id(x))
print(type(y))
print(id(y))
if x == y:
print("True")
else:
print("False")
if x is y:
print("True")
else:
print("False")
# see the last two lines, both are true
# class 'int'
# 139113568
# class 'int'
# 139113568
# True
# True
a = dict(x = 1, y = 1)
print(type(a))
print(id(a))
b = dict(x = 1, y = 1)
print(id(b))
if a == b:
print("True")
else:
print("False")
if a is b:
print("True")
else:
print("False")
# see the last two lines, one is true but the id is not same so it is
false
# class 'dict'
# 3072650252
# 3072692524
# True
# False
for i in range(0, 3):
print(i, "=", id(i))
# 0 = 139113552
# 1 = 139113568
# 2 = 139113584
</code>

We see the output inside the code. You notice that every output is commented out so that when we run this code, it will never affect the main script. There are a lot of values.

 

Integers, strings, tuples, lists, and finally dictionaries. Now we will understand what they actually are and how they work.

 

Using Numbers

Using Numbers

In Python, there are two kinds of numbers. One is an integer and the other is a float. We have built-in methods in Python that can change an integer to a float and change a float to an integer. I hope you will understand the code below. The output is self-explanatory. Read the comment also.

<code>
#!/usr/bin/python3
def main():
x = 3
print(x)
print(id(x))
print(type(x))
print("*********")
x = 3 /2
print(x)
print(id(x))
print(type(x))
print("*********")
x = round(42 / 9)
print(x)
print(id(x))
print(type(x))
print("*********")
# we want to round it up x = 42 // 9
print(x)
print(id(x))
print(type(x))
print("*********")
# how many digits we want to round to x = round(42 / 9, 3)
print(x)
print(id(x))
print(type(x))
print("*********") x = 43 % 7 print(x) print(id(x)) print(type(x)) print("*********") x = int(34.78)
print(x)
print(id(x))
print(type(x))
print("*********")
x = float(23)
print(x)
print(id(x))
print(type(x))
print("*********")
if __name__ == "__main__":
main()
</code>
And here is the output we get from this code:
<blockquote>
3
10455104
class 'int'
*********
1.5
140223146811728
class 'float'
*********
4
10455136
class 'int'
*********
5
140223146823568
class 'int'
*********
4.667
140223146811968
class 'float'
*********
1
10455040
class 'int'
*********
34
10456096
class 'int'
*********
23.0
140223146811968
class 'float'
*********
</blockquote>

As you see in the output, each number has a class and an ID. For numbers, this ID is immutable. So if you assign the same number (suppose it is 1) to two different variables, like this: a = 1 and b = 1; the ID of “a” and “b” is the same.

 

String

In Python string is an immutable object and can be written within double quotes or single quotes. Consider this code:

<code>
#!/usr/bin/python3
def main():
strings = "I love you."
print(strings)
anotherStrings = "I love you but\nI don't know how much you love me." print(anotherStrings)
if __name__ == "__main__":
main()
</code>
And here is the output:
<blockquote>
I love you.
I love you but
I don't know how much you love me.
</blockquote>

 

As you see, we used a backslash to get a new line. And we got an exact break where we needed it. There is also raw string output. See this code:

 style="margin:0;width:980px;height:154px"><code>
#!/usr/bin/python3
def main():
strings = "I love you."
print(strings)
anotherStrings = "I love you but\nI don't know how much you love me." print(anotherStrings)
rawStrings = r"I love you but\nI don't know how much you love me." print(rawStrings)
if __name__ == "__main__":
main()
</code>

 

And here is the output:

<blockquote>
I love you.
I love you but
I don't know how much you love me.
I love you but\nI don't know how much you love me.
</blockquote>

The last statement is called a raw string, where a backslash is not working anymore and we get a raw output. And it is used in a regular expression. We will discuss it in detail in our regular expression blog. 

 

We can insert an integer into the middle of a string. I show you both the methods used in Python 2 and Python 3 but remember, you better stick to the construct used in Python 3.

 

Let us first see the Python 2 code:

<code>
days = 8
lyrics = "%s days a week is not enough to love you." %days print(lyrics)
</code>
The output is like this:
<blockquote>
8 days a week is not enough to love you.
</blockquote>

Let us now see the Python 3 code:

<code>
days = 8
lyrics = "{} days a week is not enough to love you."
print(lyrics.format(days))
</code>
The output:
<blockquote>
8 days a week is not enough to love you.
</blockquote>

What is the major difference between these two constructs? The difference is in the latest version of Python; we treat the string as an object.

 

Hence a “lyrics” object used a method called format() and passed a parameter that it wanted to format into it. In the line print(lyrics.format(days)) we used a period (“.”), to call the method format() which is built-in in the string class.

 

In your coding life, you need to use plenty of strings and some of them might have multiple line breaks. You cannot use backslash “n” each time. 

 

There is a trick you can use in Python to use multiple new lines.

<code>
newLines = """\
first line
second line
third line
more to come...
"""
print(newLines)
</code>
In the output the lines break up automatically.
<blockquote>
first line
second line
third line
more to come...
</blockquote>

Now you can use a single quote instead of double quotes. You can use no backslash at the beginning, but that will generate a space at the beginning of the line.

 

What are Type and ID

Python is an object-oriented programming language. Everything is an object here. Every object has a unique identification, which is known as ID. Let us open our terminal in Linux or, if you have Windows or Mac, open the Python Shell and test this code:

<code>
x = 10
x
10
type(x) <class 'int'>
id(x)
10455328
y = 10
y
type(y) <class 'int'>
id(y)
10455328
a = dict(name='sanjib')
a
{'name': 'sanjib'}
type(a) <class 'dict'>
id(a)
139984318683592
b = dict(name='sanjib')
b
{'name': 'sanjib'}
type(b) <class 'dict'>
id(b)
139984318683720
a == b
True
a is b False
</code>

 

Here we first assign an integer value “10” to the variable “x” and later assign the same value to “y”. Later we check the ID of two variables and found that the ID is the same. We said this in the previous section.

 

Now you see the output. We can check whether two objects assigned to two different variables is the same or not by writing this way:

<code>
x == y
True
x is y
True
</code>

 

Here it is evident that both the variables “x” and “y” are pointed to the same integer object, “10”. So the value is the same and the variables are also the same.

 

But it did not happen in case of a dictionary object that we had written just after that. The dictionary “a” and “b” have the same value, but since dictionary objects are mutable, it changes the ID.

<code>
a = dict(name='sanjib')
a
{'name': 'sanjib'}
type(a) <class 'dict'>
id(a)
139984318683592
b = dict(name='sanjib')
b
{'name': 'sanjib'}
type(b) <class 'dict'>
id(b)
139984318683720
a == b
True
a is b False
<code>

It says the dictionary ID changes, though two variables have the same values. When we check it logically, it says, yes, the value of two variables is same, but since the ID is different they are different objects. 

 

As a beginner, you may find this concept a little bit strange. But later, as you progress, you will find this concept is extremely helpful. A dictionary object needs to be changed for programming purposes. If two dictionary objects have the same ID, we cannot change them.

 

Logical Values

Logical Values

Let us consider another shell script for testing logical values: True and False.

<code>
a, b = 0, 1
a == b False
a < b
True
a > b False
a = True
a
True
type(a)
<class 'bool'>
id(a)
10348608
b = True
b
True
type(b) <class 'bool'>
id(b)
10348608
</code>

Here we see there are “bool” classes and the “==” operator represents the test for quality between two values. Since “a” has a value of 0 and “b” has a value of 1, the output is “False”. Is “a” less than “b”?

 

Yes. So the output comes out as “True”. These “True” and “False” represent “bool” classes. And it is “immutable”, so if two variables are both “True” they have the same ID.

 

Tuples And Lists.

Python has many sequential types (lists of things). Let us consider this code:

<code>
x = (1, 2, 3, 4)
print(x)
print(type(x))
</code>
It has output like this:
<blockquote>
(1, 2, 3, 4)
class 'tuple'
</blockquote>

 

So it is of the class “tuple” and it has a list of things. Remember, a tuple is immutable.

You cannot insert or update it. But you can iterate through it like this:

<code>

for i in x:

print(i)

</code>

It will give all the numbers you have inside the tuple.

On the contrary, “list” is another sequential type that is mutable and you can change it as necessary. Consider this code:

 

<code>
a = [1, 2, 3, 4]
print(a)
print(type(a))
</code>
It has output like this:
<blockquote>
[1, 2, 3, 4]
class 'list'
</blockquote>

You can insert or update it as you need. Suppose you want to append the “tuple x” in this list and you also want to insert the “tuple x” in the beginning. So the full code looks like this:

<code>
#!/usr/bin/python3
# tuple
x = (1, 2, 3, 4)
# list
a = [1, 2, 3, 4]
# appending tuple x to list a.append(x)
print(a)
# inserting tuple x in the first position a.insert(0, x)
print(a)
# Now iterating the final list a
for i in a:
print(i)
</code>
And the output is like this:
<blockquote>
[1, 2, 3, 4, (1, 2, 3, 4)] # after appending
[(1, 2, 3, 4), 1, 2, 3, 4, (1, 2, 3, 4)] # after inserting
# When we iterate the list 'a' the output looks like this
(1, 2, 3, 4) 1 2 3 4
(1, 2, 3, 4) </blockquote>
In Python, a string is also a sequential type and you can iterate through it. Consider this code:
<code>
strings = "This is a string."
for WeWillIterateThroughIt in strings:
print(WeWillIterateThroughIt)
</code>
A string is a sequential type. Consider this code:
<code>
strings = "string."
print(strings[1:3])
</code>
It means the string goes like this:
0 = s
1 = t
2 = r
3 = i
4 = n
5 = g

So strings[1:3] means the sequence starts from position 1 and it goes up to position 3, excluding the 3rd position. It means it stops at 2nd position. So the output is as expected:

  • <blockquote>
  • tr
  • </blockquote>

 

Dictionary

Dictionary

Python has another very strong aggregate type of values: a dictionary. It is a class, as usual. It is more like an associative array or hash in other languages.

Consider this code:

<code>
#!usr/bin/python3
EnglishDictionaries = {'bare':'jejune', 'anger':'dudgeon', 'abuse':'vituperate', 'howl':'ululate'} print(EnglishDictionaries)
# getting in a nmore human readable form for keys in EnglishDictionaries:
print(keys, "=", EnglishDictionaries[keys]) </code>
And the output is:
<blockquote>
{'abuse': 'vituperate', 'bare': 'jejune', 'howl': 'ululate', 'anger':
'dudgeon'}
abuse = vituperate
bare = jejune
howl = ululate
anger = dudgeon
</blockquote>
Now we can sort this dictionary in an alphabetical order like this:
<code>
EnglishDictionaries = {'bare':'jejune', 'anger':'dudgeon', 'abuse':'vituperate', 'howl':'ululate'}
for keys in sorted(EnglishDictionaries.keys()): print(keys, "=", EnglishDictionaries[keys])
</code>
And we get a nice clean output in alphabetical order:
<blockquote>
abuse = vituperate
anger = dudgeon
bare = jejune
howl = ululate
</blockquote>
We can also write dictionary another way using a construct of the class dictionary.
Consider this code:
<code>
synonyms = dict(bare='jejune', anger='dudgeon', abuse= 'vituperate', howl= 'ululate')
</code>

 

We have just changed the variable name but used the same pair of words. Now we can sort them as before to get the same result. Remember one thing: when you use dict() function, you should not write keys within quotes but string values should be quoted as I did. Since the dictionary is mutable, you can insert key-value pairs into it, like lists.

 

Object

Object

Python is an object-oriented language. We will discuss it later in detail. Let us say there is a class or blueprint and from this class or blueprint we can get many types of objects. Take the Human class. It is a very complex class indeed! It has many kinds of properties; many kinds of actions are performed by this class.

 

When we create an object or instance of this class, this object or instance can carry forward every single trait of this class. Remember, there has always been a good human being and a bad human being.

 

Let us assume a Human class has two types of humans: one is good and the other is bad. In reality, it is not so simple. But to begin with our learning, we start with a less complex scenario.

 

Consider the code below:

<code>
#!/usr/bin/python3
class Human:
def __init__(self, kind = "Good"):
self.kind = kind
def whatKind(self):
return self.kind
def main():
GoodHuman = Human()
print(GoodHuman.whatKind())
BadHuman = Human("Bad")
print(BadHuman.whatKind())
if __name__ == "__main__":
main()
</code>
And here is the output:
<blockquote>
Good
Bad
</blockquote>

In the above code, the object is the instance of a class and encapsulates every property and method of the class or blueprint. In the above class, we assume a sort of blueprint where every human being is good. So in the initialization method, we write this code:

<code>
class Human:
def __init__(self, kind = "Good"):
self.kind = kind
def whatKind(self):
return self.kind
</code>
Here, “self” means a reference to the object. And the next parameter defines the kind of human objects we want to create.
What does this line mean?
<code>
def whatKind(self):
return self.kind
</code>
It returns the value of what kind of human object we want to create. The next steps are quite self-explanatory as it goes:
<code>
def main():
GoodHuman = Human()
print(GoodHuman.whatKind())
BadHuman = Human("Bad")
print(BadHuman.whatKind())
if __name__ == "__main__":
main()
</code>

When we create our first object, “good human”, we need not pass any value as “good” as the default value that has already been passed implicitly through the initialization process. But when we want to create “BadHuman”, we need to pass the value explicitly and it returns that value.

 

Conditionals

Conditionals

In Python, there are two types of conditionals. They are conditional executions and conditional values or conditional expressions. In conditional executions, we execute or check the condition of the statement.

 

We know that between two values there could be three types of conditions. It is either less than or greater than or it is equal. Write this code:

<code>
def conditionals_exec():
a, b = 1, 3
if a < b:
print("a is less than b")
elif a > b:
print("a is greater than b")
else:
print("a is equal to b")
conditionals_exec()
</code>
The output is:
# a is less than b

 

The output is obvious. Now you can change the value and test the code. Now try to rewrite the above statement in a different way. We can say x is either less than y or greater than y. Otherwise, it is obvious that they are equal.

<code>
def conditional_values():
a, b = 1, 2
statements = "less than " if a < b else " not less than."
print(statements)
conditional_values()
</code>

These functions can be written more conveniently and neatly with the main()

functions now:
<code>
def main():
print("This is main function.")
conditionals_exec()
conditional_values()
def conditionals_exec():
a, b = 1, 3
if a < b:
print("a is less than b")
elif a > b:
print("a is greater than b")
else:
print("a is equal to b")
def conditional_values():
a, b = 1, 2
statements = "less than " if a < b else " not less than."
print(statements)
if __name__ == "__main__": main()
</code>
If we run this program now, the output will be:
# This is main function.
# less than
# a is less than b
Now we can change the place of conditional_values(), and conditionals_exec() and the output will change accordingly:
# This is main function.
# a is less than b
# less than

Loops

“While loop” is the simplest form of a loop in Python. But you need to understand it properly. Otherwise, it can end up eating up your memory running the infinity loop. Usually, most of the jobs are done by “for loop”. But in some special cases, you need to use “while loop”. A basic understanding is important.

 

While Loops

While Loops

In plain English, we often say, “While it is true it keeps on running. While it is not true it stops.” Logically, the same thing happens here. While a statement is true, the process is going on. You need a mechanism to stop that process. That is important. Otherwise, that statement will eat up your memory.

Consider this code:

<code>
b = 1
while b < 50:
print(b)
b = b + 1
</code>

What does it mean? It means, the statement “b < 50” is true until the suite or block of code is true inside it. Inside the block we wrote “b = b + 1” and before the beginning of the while loop, we defined the value of b as 1. So in each step b progresses by adding 1 to its value and finishes at 49. In the output, you will get 1 to 49.

 

Let us move further. Consider this code:

<code>
#!/usr/bin/python3
# simple fibonacci series
# sum of two numbers define the next set a, b = 0, 1
while b < 50: print(b, end=' ') a, b = b, a + b
</code>
The output is quite obvious:
<blockquote>
1 1 2 3 5 8 13 21 34
</blockquote>
For the beginners, let us write this code in a more readable way and it will give a different output altogether:
<code>
#!/usr/bin/python3
a, b = 0, 1
while b < 30:
print(b, end=' ')
a = b
b = a + b
</code>

Let us explain the steps one by one to understand it properly.

The loop starts at 1. In the first step, the value of “a” is 1. In the next step value of “b” is 2. 

Now the value of “a” is 2 so the value of “b” is 4. Now the value of “a” is 4 so the value of “b” is 8 (4+4).

Now the value of “a” is 8 so the value of “b” is (8 + 8) = 16. Now the value of “a” is 16.

What will be the value of b? It will be 16 + 16 = 32. But 32 is greater than 30. So it will come out from the code suite of the while loop. The output of the above code will be:
<blockquote>
1 2 4 8 16
</blockquote>

 

For Loops

For Loops

The most common loop used in Python is for a loop. In fact, essentially almost all kinds of looping jobs can be done through the “for” loop. 

 

There is a reason of course. With the help of for loop, we can iterate through Python objects and we can iterate through most of the Python objects. Let us see one example:

<code>
#!/usr/bin/python3
songs = open('file.txt')
for lines in songs.read():
print(lines, end='')
</code>
And the output of the song goes like this:
<blockquote>
Yo, girl you touched me hard
your loneliness has made me weep
I am a sooo stupid nerd
I thought about the words, I could not keep So I weep
A stupid nerd
</blockquote>

 

We have a song written over in a file called “file.txt” and we just iterate through this file. We could have iterated through line by line as they are indexed. Consider this code where we just used "enumerate()" function and index value:

<code>
# enumerate
songs = open('file.txt')
for index, lines in enumerate(songs.readlines()):
print(index, lines, end='')
</cede>
And the output is like this:
<blockquote>
0 Yo, girl you touched me hard
1 your loneliness has made me weep
2 I am a sooo stupid nerd
3 I thought about the words, I could not keep
4 So I weep
5 A stupid nerd
</blockquote>

 

Now, what does this function “enumerate()” mean? Dictionary says: enumeration is a kind of numbering which is a numbered list. Let us consider this line of code:

<code>
strings = "This is a string."
# now we are going to find how many 's' is inside this string for index, s in enumerate(strings):
if s == 's':
print("Hi I am 's' and I am located at position {}".format(index))
</code>
And we have an output:
<blockquote>
Hi I am 's' and I am located at position 3
Hi I am 's' and I am located at position 6
Hi I am 's' and I am located at position 10
</blockquote>

 

This is extremely useful. You can search for any character inside any string. In Python, functions or subroutines are extremely important for reusability of codes.

 

We can call a function several times and pass many arguments or parameters to get different effects. Now we are going to pass one parameter inside the loops() function. Consider this code below:

<code>
#!/usr/bin/python3
def main():
loops(0)
loops()
loops(3)
def loops(a = 4):
for i in range(a, 6):
print(i, " ")
print("*************")
if __name__ == "__main__":
main()
</code>

What does this code mean? In loops() function, we have passed one parameter a and assigned a value 4. It is the default value. So that in the future if we forget to pass any argument the code will not break.

 

 We have called that function three times inside the main() function, but with three different values, and one of them is NULL. That is, we have not passed an argument.

 

Now it is obvious that you can play around with this code. You can pass two arguments inside loops() function and control the range() function to get different values.

 

[Note: You can free download the complete Office 365 and Office 2019 com setup Guide.]

 

Regular Expressions

Regular Expressions

Searching and replacing with regular expressions is equally easy and very simple in nature. To do that we will tweak our old code a little bit. We use the “re” module and it does the simple jobs. 

 

Using the “re” Module

If you want to use the “re” module, the first step is importation. We need to import the module first and write it on the top of the code. Consider this code where we have a text file called “file.txt” and it is stored in our “primary” folder.

<code>
#!/usr/bin/python3
import re
def main():
ReplaceWord()
DEmarcationLine()
MatchAndReplaceWord()
def ReplaceWord():
try:
files = open("../primary/file.txt")
for line in files:
# you can search any word print(re.sub('lenor|more', "#####", line), end=' ')
except FileNotFoundError as e:
print("File was not found:", e)
def MatchAndReplaceWord():
try:
files = open("../primary/file.txt")
for line in files:
# you can search any pattern that can match and then replace with this word
match = re.search('(len|neverm)ore', line)
if match:
print(line.replace(match.group(), "#####"), end=' ')
except FileNotFoundError as e:
print("File was not found:", e)
def DEmarcationLine():
print("*************")
if __name__ == "__main__":
main()
</code>
Before we have the output, let us see what is written inside the file. The “file.txt” in “primary” folder has these lines:
<blockquote>
first line lenore
it is nine, second line and dine
third line and nevermore over
and fourth
fifth pine line lenore
and the tremor
here is more line
and a new line
i love you
where you are staying now?
i don't know
</blockquote>

As you see, these are not very meaningful sentences. Our primary concern is very simple. We write down some nonsense lines and later try to work upon it with the use of the “re” module. Now we run the code and here is the output:

<blockquote>
first line #####e
it is nine, second line and dine
third line and never##### over
and fourth
fifth pine line #####e
and the tremor
here is ##### line
and a new line
i love you
where you are staying now?
i don't know *************
first line #####
third line and ##### over
fifth pine line #####
</blockquote>

All the words “lenore” and “nevermore” have been replaced by five hashtags: “#####”.

We use two methods of “re” module that we import and write on the top of the code.

 

These methods are “re.sub()” and “line.replace()”. We have supplied the old string and the new word. We have given five hashtags but you could have given any other word, of course.

 

Reusing With Regular Expressions

Regular Expressions

You have already seen how we can search and replace words in a file with the help of regular expression. Now we will try to reuse the code so that we can use them again and again. Additionally, we will also try to write them in a more readable way.

Let us first write the steps. What we want to achieve is very important. Let us have a clear idea first and the best way is writing it down.

 

\1.\ We need to open a file and put it into the “try block” to avoid getting any nasty error message. Beginners may find this “try block” quite intimidating.

 

I have not explained it before and suddenly started using it. I have done it intentionally. It is explained in the next blog, “Exceptions, Catching Errors.”

 

But before that, I want you to write to them and get habituated to a concept that looks complex. Once you learn this “try block,” please revisit this code again. You will find it extremely easy! Moreover, as you progress, you will find that using “try block” is always a good habit.

 

\2.\ Get the pattern of the words that we want to search and, using flags, we can ignore case.

\3.\ Use that “re” module search method to see if that pattern matches with our line.

\4.\ Now if it matches, then replace it with new words.

 

Consider this code below and read the comments. In comments, I briefly explain what I am going to do.

<code>
#!/usr/bin/python3
import re
def main():
CompilerAndReplaceWord()
def CompilerAndReplaceWord():
try:
files = open("../primary/file.txt")
# you can search any pattern that can match ignoring the upper or lower case
pattern = re.compile('(len|neverm)ore', re.IGNORECASE) for line in files:
# re module search that pattern in a line
if re.search(pattern, line):
# we found that patetrn and now it is time to replace them
with a new string
print(pattern.sub("######", line), end=' ') except FileNotFoundError as e:
print("File was not found:", e)
if __name__ == "__main__":
main()
</code>
And in the output it replaces all the words “lenore” and “nevermore” with six hashtags. To do that, it also checks the upper and lower case and finally replaces them all.
<blockquote>
first line ######
third line and ###### over
fifth pine line ######
i don't know ######
</blockquote>

 

Searching with Regular Expressions

Searching

Regular expressions are a very powerful method of matching patterns. A regular expression is a small language in itself and it can be very simple and very complex. 

It is implemented in Python with “re” module. Consider this code:
<code>
#!/usr/bin/python3
import re
def main():
FindWord()
DEmarcationLine()
MatchWord()
def FindWord():
try:
files = open("../primary/file.txt")
for line in files:
# you can search any word
if re.search('lenor|more', line):
print(line, end=' ')
except FileNotFoundError as e:
print("Fiel was not found:", e)
def MatchWord():
try:
files = open("../primary/file.txt")
for line in files:
# you can search any pattern that can match this word match = re.search('(len|neverm)ore', line)
if match:
print(match.group())
except FileNotFoundError as e:
print("Fiel was not found:", e)
def DEmarcationLine():
print("*************")
if __name__ == "__main__":
main()
</code>

Here we search a file called “file.txt” that has words like “lenor” or “more” and that also matches some words that end with “ore”.

 

We have defined two functions to search that and we used the “re” module. Let us first see what is the content inside “file.txt”. There are some misleading words and lines just to test our search.

<blockquote>
first line lenore
it is nine, second line and dine
third line and nevermore over
and fourth
fifth pine line lenore
and the tremor
here is more line
and a new line
i love you
where you are staying now?
i don't know
</blockquote>
After running our code we have found this search result.
<blockquote>
first line lenore
third line and nevermore over
fifth pine line lenore
*************
lenore
nevermore
lenore
</blockquote>

 

It is a very simple regular expression example. It is beyond our scope to teach regular expression here but we can at least have some idea. I strongly recommend you move further. Search for “regular expression” on the Internet.

 

You will find a lot of tutorials. Learning and understanding regular expression is very important. Whether you become a web developer, an ethical hacker, or a Python programmer; regular expression will help.

 

Exceptions, Catching Errors

Catching Errors

I hope you have already written a lot of codes. If you had really done that, you would have encountered one or two errors. There are two distinguishable kinds of errors. The first is “SyntaxError”. It means you have an error in your syntax. Consider this code:

<code> for i in range(10) print(i) SyntaxError: invalid syntax </code> As you see, I forgot to use “:” in for loop. It is a syntax error.

 

Another error is “Exceptions”. It means you write code perfectly. There are no syntactical errors. But you forget to define a variable. Let us consider these lines of code:

<code>
10 * x
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module> 10 * x
NameError: name 'x' is not defined
10 / 0
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module> 10 / 0
ZeroDivisionError: division by zero
'2' + 2
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module> '2' + 2
TypeError: Can't convert 'int' object to str implicitly
inputs = input("Please enter a number.") Please enter a number.
inputs + 2
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module> inputs + 2
TypeError: Can't convert 'int' object to str implicitly
inputs = input("Please enter a number.") Please enter a number.12
inputs - 10
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module> inputs - 10
TypeError: unsupported operand type(s) for -: 'str' and 'int'
int(inputs) - 10
2
</code>

As you see, there are a lot of different kinds of errors. And in the last line, we have come out from the error and gotten a perfect output. In the last error, we get a “TypeError”. We tried to subtract an integer from a string object. In the last step, we converted that string input integer and the subtraction took place smoothly.

 

It is always good to catch those errors and get a nice output. The “try block” phrase has been used before. Now comes the time when we learn how we use those blocks to catch errors. Write down the code below in your text editor and save it as “http://CatchError.py”.

<code>
#!/usr/bin/python3
def main():
FileRead()
DemarcationLine()
LineStrip()
DemarcationLine()
CheckFileExtension()
def ReadFile(filename):
files = open(filename)
lines = files.readlines()
for index, line in enumerate(lines):
print(index, "=", line)
def StripFile(filename):
files = open(filename)
for lines in files:print(lines.strip())
def RaisingError(filename):
if filename.endswith(".txt"):
lines = open(filename)
for line in lines:print(line.strip())
else:
raise ValueError("File must end with .txt")
def FileRead():
try:
ReadFile("../primary/files.txt") # path is okay, it reads file except IOError as e:
print("Could not open file:", e)
def LineStrip():
try:
StripFile("primary/files.txt")
except IOError as e:
print("Could not open file:", e) # it will give error def CheckFileExtension():
try:
RaisingError("../primary/file.rtf")
except IOError as e:
print("Could not open file:", e)
except ValueError as e:
print("Bad Filename:", e)
def DemarcationLine():
print("******************")
if __name__ == "__main__":
main()
</code>
Run this file and you get this output:
<blockquote>
Could not open file: [Errno 2] No such file or directory: '../primary/files.
txt'
Could not open file: [Errno 2] No such file or directory: 'primary/files.
txt'
Bad Filename: File must end with .txt
</blockquote>

As an exercise, try to write this code with “Try” and “Except” and catch if there is any error.

<code>
#!/usr/bin/python3
def main():
GetARangeOfNumber()
def GetARangeOfNumber():
for index in IteratingStepByStep(1,123, 7):
print(index, end=' ')
def IteratingStepByStep(start, stop, step):
number = start
while number <=stop: yield number number +=step if __name__=="__main__": main() </code>
Functions
Let us first define the function and try to know why function is being used in Python.
Consider this code:
<code>
#!/usr/bin/python3
def main():
print("This is main function.")
if __name__ == "__main__":
main()
</code>
And the output is:
<blockquote>
This is main function.
</blockquote>

 

What does that mean? First of all, let us understand what function does mean.

A function is used in any programming language to reuse code. Programmers are lazy and so they don't want to write again and again. And it is not a good idea to write the same thing again and again. So the concept of reusability comes in and we use a function to do that.

 

You may consider a very simple example. Suppose we want to use a demarcation line again and again. Will you write like this again and again?

<code>
print("*************")
</code>
Or you will write a function and call it when it is necessary? Like this:
<code>
def DemarcationLine():
print("*********")
DemarcationLine():
DemarcationLine():
DemarcationLine():
</code>

 

Each time you call the function “demarcation line()” it will print a demarcation line. Now let us come to the first question. It is always a good practice to write functions inside the main() function and you can call them any time. The flow control doesn’t necessarily follow downward. You can test it:

<code>
def AnotherFunction():
print("I am another function.")
def TestFunction():
print("I am going to call another function.")
AnotherFunction()
TestFunction()
<code>
It will print without any problem and give you this output:
<blockquote>
I am going to call another function.
I am anotheer function.
</blockquote>
Now we will write the above code differently.
<code>
def TestFunction():
print("I am going to call another function.")
AnotherFunction()
TestFunction()
def AnotherFunction():
print("I am another function.")
</code>

 

A little bit of change in the position. We have not defined AnotherFunction() before TestFunction() and for that reason, it will give an error output:

<blockquote>
I am going to call another function.
Traceback (most recent call last):
File "/home/hagudu/PycharmProjects/FirstPythonProject/functions/defining_ http://functions.py", line 17, in <module>
TestFunction()
File "/home/hagudu/PycharmProjects/FirstPythonProject/functions/defining_ http://functions.py", line 15, in TestFunction
AnotherFunction()
NameError: name 'AnotherFunction' is not defined
</blockquote>

 

So each time you call a function inside another function, you need to define it first. But this problem can be solved if you define main() function first. Now consider this code:

<code>
#!/usr/bin/python3
def main():
TestFunction()
def TestFunction():
print("I am going to call another function.")
AnotherFunction()
def AnotherFunction():
print("I am another function.")
if __name__ == "__main__":
main()
</code>
And here is the output:
<blockquote>
I am going to call another function.
I am another function.
</blockquote>

 

Now see, we did not bother about the position because all the functions are under main() function. Much more flexibility is now being added when you are using a main() function like this. Another great advantage of using function is passing parameters or arguments through it.

<code>
#!/usr/bin/python3
def main():
PassingParameters(1,2,3)
def PassingParameters(argument1, argument2, argument3):
print("Here is our arguments:", argument1, argument2, argument3)
if __name__ == "__main__":
main()
</code>
And the output is:
<blockquote>
Here is our arguments: 1 2 3
</blockquote>

 

We have passed three parameters or arguments and get the output as expected. But what happens if we forget to pass an argument? We don't want to get any nasty error message. We can manage that in two ways:

<code>
#!/usr/bin/python3
def main():
PassingParameters(1)
def PassingParameters(argument1, argument2 = 4, argument3 = 6):
print("Here is our arguments:", argument1, argument2, argument3)
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
Here is our arguments: 1 4 6
</blockquote>

 

It is called passing default values. We have passed two default values and when we actually call the function, it takes that default value. Now we can override these default values any time. Consider this one:

<code>
#!/usr/bin/python3
def main():
PassingParameters(1, 10, 14)
def PassingParameters(argument1, argument2 = 4, argument3 = 6):
print("Here is our arguments:", argument1, argument2, argument3)
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
Here is our arguments: 1 10 14
</blockquote>

 

We have overwritten the default values by passing new values and the output has changed accordingly. We can write this code this way also:

#!/usr/bin/python3
def main():
PassingParameters(1)
def PassingParameters(argument1, argument2 = None, argument3 = 6):
if argument2 == None:
print("Here is our arguments:", argument1, argument2, argument3)
else:
print("Here is our arguments:", argument1, argument2, argument3)
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
Here is our arguments: 1 None 6
</blockquote>
What happens if we pass a new value for argument2? Consider this code:
<code>
#!/usr/bin/python3
def main():
PassingParameters(1, 12)
def PassingParameters(argument1, argument2 = None, argument3 = 6):
if argument2 == None:
print("Here is our arguments:", argument1, argument2, argument3)
else:
print("Here is our arguments:", argument1, argument2, argument3)
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
Here is our arguments: 1 12 6
</blockquote>

In the next section, we will see how lists of arguments work in a function.

 

Return Values

Return Values

In Python, a function can return any value. It can return any type of data: string, integer, object—anything. Let us return an object. Consider this code:

<code>
#!/usr/bin/python3
def main():
for index in ReturnValues():
print(index, end=" ")
def ReturnValues():
#return "Returning string."
#return 56
return range(10)
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
0 1 2 3 4 5 6 7 8 9
</blockquote>

We have returned range() object and got the value in our main() function.

 

Generate Functions

Generate Functions

In Python, we can generate functions. Let us explain it by step-by-step. Consider this code first:

<code>
#!/usr/bin/python3
def main():
RangeFunctions()
def RangeFunctions():
for i in range(10):
print(i, end=' ')
if __name__ == "__main__":
main()
</code>
And the output is quite obvious:
<blockquote>
0 1 2 3 4 5 6 7 8 9
</blockquote>

 

You have probably found that the function RangeFunctions() has a limitation. It stops at 9, although the range is mentioned as 10. What can I do to include this number?

 

Let us write RangeFunctions() this way:

<code>
#!/usr/bin/python3
def main():
for index in RangeFunctions(0, 10, 1):
print(index, end=' ')
def RangeFunctions(start, stop, step):
i = start
while i <=stop: yield i i +=step if __name__=="__main__": main() </code>
And here is the output:
<blockquote>
0 1 2 3 4 5 6 7 8 9 10
</blockquote>

 

Here we have used the “yield” keyword. It is done because we have imagined that the code will progress step-by-step like we play a tape. After yielding one step it will stop and start from there and again start and go one step. You can just start from any point or stop at any point and progress by any step.

 

If we write like this:

for index in RangeFunctions(15, 1025, 102):
print(index, end=' ')
The output will be:
15 117 219 321 423 525 627 729 831 933.
As you have seen, we can set the value of any argument as default. So we can write this function like this:
<code>
def AnotherRangeFunctions(start = 0, stop, step = 1):
i = start
while i <=stop: yield i i +=step </code>
And we may try to get the output by:
<code>
for index in AnotherRangeFunctions(25):
print(index, end=' ')
</code>

But it gives us an error message:

File "/home/hagudu/PycharmProjects/FirstPythonProject/functions/generate-functions.py", line 18 def AnotherRangeFunctions(start = 0, stop, step = 1):

 

SyntaxError: non-default argument follows default argument

Python does not support this. Can we solve this problem so that we can pass any number of arguments and control it without having any error message?

 

Consider this code:

<code>
def AnotherRangeFunctions(*args):
numberOfArguments = len(args)
if numberOfArguments < 1: raise TypeError('At least one argument is required.')
elif numberOfArguments == 1:
stop = args[0]
start = 0
step = 1
elif numberOfArguments == 2:
# start and stop will be tuple (start, stop) = args
step = 1
elif numberOfArguments == 3:
# all start and stop and step will be tuple (start, stop, step) = args
i = start
while i <=stop: yield i i +=step </code>

Write down every line and take notes side-by-side. Add comments where you feel that an explanation is necessary.

 

Lists of Arguments

Arguments

In Python sometimes you need an arbitrary number of arguments and you have to name them. Let us write this code:

<code>
#!/usr/bin/python3
def main():
PassingListsOfArguments(1, 2, 3, 5, 7, 45, 98, 56, 4356, 90876543) PassingAnotherListsOfArguments(1, 2, 3, 5, 7, 45, 98, 76, 987654, 3245, 2345, 98760)
def PassingListsOfArguments(arg1, arg2, arg3, arg4, *args):
print(arg1, arg2, arg3, arg4, args)
def PassingAnotherListsOfArguments(param1, param2, *params):
print(param1, param2)
for index in params:
if index == 76:
x = 10
y = index + x
print("We are going to add 10 with", index, "and the new value
is:", y)
continue
print(index, end=' ')
if __name__ == "__main__":
main()
</code>
And the output goes like this:
<blockquote>
1 2 3 5 (7, 45, 98, 56, 4356, 90876543)
1 2 3 5 7 45 98 We are going to add 10 with 76 and the new value is: 86
987654 3245 2345 98760
</blockquote>

In our code, *args or *params mean lists of arguments. You can pass any number of arguments through them.

 

In code def PassingListsOfArguments(arg1, arg2, arg3, arg4, *args): means you need to pass four arguments first. 

 

That is compulsory. After that, the number of arguments may vary. But the arbitrary number of arguments comes out as “tuple”. See the output of this function:

1 2 3 5 (7, 45, 98, 56, 4356, 90876543) The latter part is obviously a tuple and you can iterate through it.

 

Named Arguments

Named Arguments

Sometimes it is important to use named arguments in Python. And we get those named arguments in a dictionary format. Consider this code:

<code>
#!/usr/bin/python3
def main():
NamedArguments(name = 'Sanjib', address = 'Pluto', hobby = "Gardening")
def NamedArguments(**kwargs):
for key in kwargs:
print(key, "=", kwargs[key])
if __name__ == "__main__":
main()
</code>
And the output:
<blockquote>
hobby = Gardening
name = Sanjib
address = Pluto
</blockquote>

 

As it is a dictionary output, it is not ordered. You can sort it alphabetically. Let us consider a fairly long code where we can use every kind of passing argument.

<code>
#!/usr/bin/python3
def main():
NamedArguments(name = 'Sanjib', address = 'Pluto', hobby = "Gardening")
DemarcationLine()
AnotherNamedArguments('Hi', 1235, 1,2,3, one = 1, two = 2, three = 3)
def NamedArguments(**kwargs):
for key in kwargs:
print(key, "=", kwargs[key])
def AnotherNamedArguments(arg1, arg2, *args, **kwargs):
print(arg1, arg2)
for index in args:
print(index, end=' ')
DemarcationLine()
for keys in kwargs:
print(keys, "=", kwargs[keys])
def DemarcationLine():
print("********")
if __name__ == "__main__":
main()
</code>
Here is the output:
<blockquote>
hobby = Gardening
address = Pluto
name = Sanjib
********
Hi 1235
1 2 3 ********
three = 3
two = 2
one = 1
</blockquote>

 

Classes

Classes

If you are a complete beginner, you are probably hearing for the first time about “object-oriented programming and class.” Let us give a brief introduction to object-oriented programming (OOP).

 

Object-Oriented Methodology

It is based on real-world programming. An object is a representation of a real-world entity. If there is an object, there must be a class or blueprint behind it. In that class, the behavior of that object is designed or described in detail.

 

These details consist of all the properties and actions that the object performs. There could be many types of objects coming from different classes and they might have relationships.

 

It could be very complicated, but you can always break those objects from one another and make some changes. The advantage of object orientation is that when you work on a part of a big, complicated project, the other part remains unaffected.

 

Our goal is simple. We want to join different objects to create big, complicated software. At the same time, we want to make the relations of those objects as loose as possible.

 

A car object is built of many other objects like a tire, wheel, engine, accelerator, etcetera. If you get a flat tire does the engine stop? They are interrelated and depend on one another. But finally, you can work on them individually without affecting the other. That is object orientation.

 

Consider an object, “good human”. This object must be different from another object, “BadHuman”. Both come from the “Human” class. Now, these two objects might have interrelationships and data interactions. Can you imagine how many kinds of properties and methods there are in the “Human” class?

 

It could be very complex. Imagine a situation where a “bad human” does something ugly. At the same time, a “good human” does something good. Whoever does whatever thing, life goes on and that is also object-oriented.

 

The Foundation of Object Orientation

Object Orientation

Object orientation is a type of methodology used for building software applications. An object-oriented program consists of classes, objects, and methods. The object-oriented methodology in software development revolves around a single concept called the object.

 

You can develop software by breaking the application into component objects. These objects interact with each other when the whole application is put together. An object is a combination of messages and data. The object receives and sends messages and those messages contain data or information.

 

You (an object) interact with your television (another object) via messages sent through a remote controller (another object). Consider another real-world example of a football. Football has a boundary. It has a specifically defined property like bouncing. You can direct or apply a few specific actions by kicking it or throwing it.

 

An object has a state. It may display behavior. It has a unique ID.

The difference between an object and a class is subtle but important. Whereas a class is an abstract concept, an object is a concrete entity. From a class, objects with specific properties can be created or instantiated. That is why an object is often called an instance of a class.

 

One of the major features of object-oriented programming is “polymorphism.” Polymorphism is the capability of something to assume different forms. In object-oriented programming, polymorphism is the property that a message can mean different things depending on the objects receiving it.

 

The message “Accelerate” means one thing if it sent to an object “OldCar”. But it means a different thing if it is sent to the object “NewCar”. It is a natural concept that can be applied to objects. It also means that similar objects often accept the same message but do different things.

 

Consider a web page. It is an object. There are billions of such objects around us. When you send a request to an object like a web page, you actually apply a verb “GET” to a noun “WebPage”. Now every “WebPage” object does not behave the same way when the “GET” verb is applied.

 

Someone opens up a PDF file, someone simply shows some texts and pictures and someone may harm your computer. When you double-click a file, it may execute if it is an executable file.

 

Or it may open up in a text editor if it is a text file. The message is the same. That is “Double-Click”. But the behavior displayed by the file object depends on the object itself.

 

This is a polymorphism. You will learn it by heart as you progress through this blog. The advantage of Python classes is that they provide all the standard features of object-oriented programming.

 

It has the class inheritance mechanism. That allows multiple base classes. A derived class can override any methods of its base class or classes, and a method can call the method of a base class with the same name.

 

Objects can contain arbitrary amounts and kinds of data. Finally, remember, in Python, everything is an object. It means there is an abstraction or encapsulation behind it. You need to understand the abstraction first and then you create your own abstraction.

 

Understanding Classes and Objects

Classes and Objects

You cannot understand a theory unless you implement that concept into the real world. Let us see what we have learned.

  • \1.\ Classes are when you create your own object.
  • \2.\ A class is a blueprint for an object.
  • \3.\ An object is an instance of a class.

Let us see how we can build a class and later create a few instances from it. Consider this code:

<code>
#!/usr/bin/python3
class Robot:
def __init__(self):
pass
def WalkLikeARobot(self):
print("walks like a robot.")
def CareLikeARobot(self):
print("takes care like a robot.")
robu1 = Robot()
print(type(robu1))
print(id(robu1))
robu2 = Robot()
print(type(robu2))
print(id(robu2))
del robu2
def main():
robu = Robot()
print(type(robu))
print(id(robu))
if __name__ == "__main__":
main()
</code>

 

In this code, we have a class definition of “Robot”. Here “class” is the keyword. Next to it is a “:” sign, which means a class definition will follow a suite or block of codes. After we have defined the class “Robot”, we have three methods.

And they are :

def __init__(self):
pass
def WalkLikeARobot(self):
print("walks like a robot.")
def CareLikeARobot(self):
print("takes care like a robot.")

 

The first one is a special method. When a class is instantiated, this method will be called first. “__init__” means initialization. The class is initialized. Two other methods follow it.

 

Those methods are self-explanatory. Methods are action verbs. When we create a robot object and we call those methods, we actually tell them to do something. In our class, we defined what they will do.

 

In this code, we created three robot objects. And finally, we did not tell them to do anything. We have just seen how they are different from one another. We have tested their type and ID. Look, each object has a different ID. So this is a major point. Each object or instance created from a class has its own individuality.

 

Now see the output:

<blockquote>
<class '__main__.Robot'>
140445354614624
<class '__main__.Robot'>
140445354668160
<class '__main__.Robot'>
140445354668160
</blockquote>

 

The next lines of code are a little bit longer but I strongly suggest that you write them on your own text editor and run the program to see that you get the same output.

<code>
#!/usr/bin/python3
class Robots:
def __init__(self):
pass
def WalkLikeARobot(self, style):
self.style = style
return self.style
def CareLikeARobot(self):
print("takes care like a robot.")
class Humans:
def __init__(self, nature = "good"):
self.nature = nature
def GoodHumanBeing(self):
print("need not repeat, a good human being is always", self.nature)
def BadHUmanBeing(self):
self.nature = "need not repeat, bad human being is always bad." print(self.nature)
def WalkLikeARobot(self, style):
self.style = style
return self.style
def main():
robu = Robots()
robu.CareLikeARobot()
print(robu.WalkLikeARobot("walks like a robot"))
GoodMan = Humans()
print(GoodMan.nature)
GoodMan.GoodHumanBeing()
BadMan = Humans()
BadMan.nature = "bad"
print(BadMan.nature)
BadMan.BadHUmanBeing()
print(BadMan.WalkLikeARobot("he is human but walks like a robot"))
if __name__ == "__main__":
main()
</code>

In the above snippet of code, we have two classes. One is “Robot”, that we wrote earlier. The other class is “Human”. In the “Human” class, we have defined this special method like this:

  • def __init__(self, nature = "good"):
  • self.nature = nature

 

What does this mean? It means when we create a human instance of this class, we assume that the nature of human object will by default be good. Unfortunately, it does not happen in the real world.

 

Keeping that in mind, we also write this line: “self. nature = nature”.

It means self-nature or the nature of the instance will be good if we do not explicitly mention that it is “Bad” or something else.

 

In the following steps, when we create a bad human instance, we explicitly change nature. Remember, each method is the action part of that object. An object is a noun and it does something.

 

In any software application, it follows the same rule. An example of polymorphism is also there. In both classes, “Robot” and “Human”, we have defined a method:

def WalkLikeARobot(self, style):
self.style = style
return self.style

 

When we apply this same verb to the different Robot and Human objects, it displays different behavior. If you run this code, it gives us output like this:

<blockquote>
takes care like a robot.
walks like a robot
good
need not repeat, a good human being is always good bad
need not repeat, bad human being is always bad.
he is human but walks like a robot
</blockquote>

 

When a Robot instance walks like a robot, it displays: walks like a robot; but when an instance of Human walks like a robot, it displays: he is human but walks like a robot. This is nothing but a simple example of polymorphism. When the same verb applies to two different objects, depending on the nature of the object it gives different output.

 

Actually, we change this behavior by passing two different arguments. Suppose, instead of a single argument, we pass a dictionary of values. See how the power is magnified. Consider a simple code below:

<code>
print(type(BadMan.WalkLikeARobot(dict(one=1, two=2))))
st = BadMan.WalkLikeARobot(dict(one=1, two=2))
for keys in sorted(st):
print(keys, st[keys])
ws = BadMan.WalkLikeARobot({'one':56, 'two':2})
for keys in sorted(ws):
print(keys, ws[keys])
</code>
Here is the output:
<blockquote>
<class 'dict'>
one 1
two 2
one 56
two 2
</blockquote>

You can add more key, value pairs to this dictionary and run this code to see what happens.

 

Write Your Own Game, “Good Vs Bad”

So far we have learned many things. I hope you have written the codes and tested them and it executed perfectly.

 

Now the time has come to write a simple game in Python. It is a game called “Good Vs Bad.” The game is simple. But as a beginner, you may find this code a bit longer. Write it down. Try to add more features.

 

If you are in a Linux environment, save this file as “http://good-vs-bad.py” and change the file executable by running this command:

Sudo chmod +x http://good-vs-bad.py
And then run it on your terminal like this:
./ http://good-vs-bad.py

 

If you are in Windows, run the IDLE and save the file as “http://good-vs-bad.py”. Press F5 and play the game. In the background, the code shows and you may play the game on Python Shell.

The code is like this:
<code>
#!/usr/bin/python3
class Robots:
def __init__(self):
pass
def WalkLikeARobot(self, WalkingStyle): self.WalkingStyle = WalkingStyle return self.WalkingStyle
def CareLikeARobot(self):
print("takes care like a robot.")
class Humans:
def __init__(self, nature = "good"):
self.nature = nature
def GoodHumanBeing(self):
print("need not repeat, a good human being is always", self.nature)
def BadHUmanBeing(self):
self.nature = "need not repeat, bad human being is always bad." print(self.nature)
def WalkLikeARobot(self, WalkingStyle): self.WalkingStyle = WalkingStyle return self.WalkingStyle
def main():
robu = Robots()
# robu.CareLikeARobot()
# print(robu.WalkLikeARobot("A robot walks like a robot and nothing happens."))
GoodMan = Humans()
# print(GoodMan.nature)
# GoodMan.GoodHumanBeing()
BadMan = Humans()
# BadMan.nature = "bad"
# print(BadMan.nature)
# BadMan.BadHUmanBeing()
# print(BadMan.WalkLikeARobot("he is human but walks like a robot"))
# when a bad man wlaks like a robot many things happen WhenABadManWalksLikeARobot = BadMan.WalkLikeARobot(dict(change = 'he becomes a monster inside',
act = 'he kills fellow people',
feel = 'he enjoys torturing animals',
care = 'he cares for none',
look = 'he looks a normal human being', state = 'finally he destroys himself'))
# there are lot of actions that take place
print("What happens when a Bad Man walks like a Robot?")
change = input("Tell us what kind of change may take place inside him?\n Choose between 'monster' and 'angel',"
"and type here...>") WhenABadManWalksLikeARobot['change'] = change reward = 0
if change == 'monster':
print("You have won the first round:", change)
reward = 1000
print("You have won ", reward, "points.")
print("What does he do? :", WhenABadManWalksLikeARobot['act']) change = input("Now tell us what the monster feels inside while killing people?\n Choose between 'great' and 'sad',"
"and type here...>") WhenABadManWalksLikeARobot['change'] = change if change == 'great':
print("You have won the second round:")
reward = 10000
print("You have won ", reward, "points.")
print("What he feels inside? :", WhenABadManWalksLikeARobot ['feel'])
change = input("Tell us does the monster care for anyone?\n Choose between 'yes' and 'no',"
"and type here...>") WhenABadManWalksLikeARobot['change'] = change if change == 'no':
print("You have won the third round:")
reward = 100000
print("You have won ", reward, "points.")
print("What he feels inside? :", WhenABadManWalksLikeARobot ['care'])
change = input("Tell us does the monster look like a normal human being?\n Choose between 'yes' and 'no',"
"and type here...>") WhenABadManWalksLikeARobot['change'] = change if change == 'yes':
print("You have won the fourth round:")
reward = 1000000
print("You have won ", reward, "points.")
print("What does he look like? :", WhenABadManWalksLike ARobot['look'])
change = input("Tell us what happens to the monster finally? Does he destroy himself\n Choose between 'yes' and 'no',"
"and type here...>") WhenABadManWalksLikeARobot['change'] = change if change == 'yes':
print("You have won the fifth round:")
reward = 100000000
print("You have won Jackpot.", reward, "points.")
else:
print("You have changed the course of game. It ends here. You have lost", reward - 100000, "points.")
else:
print("You have changed the course of game. It ends here. You have lost", reward - 1000, "points.")
else:
print("You have changed the course of game. It ends here.
You have lost", reward - 100, "points.")
else:
print("You have changed the course of game. It ends here. You have lost", reward - 10, "points.")
else:
print("You have changed the course of game. It ends here and you have won no point.")
if __name__ == "__main__":
main()
</code>
And the output on your Python Shell looks like this:
<blockquote>

Since I wrote the code, I won the game. But there are a few tricks. In those tricky parts, if you failed and supplied wrong inputs you would lose.

 

Primary Class and Object

Primary Class and Object

Now primary class and object should no longer be difficult. You can write a Human class and pass one default argument like “kind” in the initialization process. You can set it as “good”. Now if you want to create a good human being you need not pass any extra argument.

 

In the next step, when you apply a verb like “BeingHuman()” to the good human being, it is by default good. If you want to create a bad human being, you can change that default argument and make it bad.

<code>
#!/usr/bin/python3
class Human:
def __init__(self, kind = "good"):
self.kind = kind
def BeingHuman(self):
return self.kind
def main():
good = Human()
bad = Human("bad")
print(good.BeingHuman ())
print(bad.BeingHuman ())
if __name__ == "__main__":
main()
</code>
The output is quite obvious:
<blockquote>
good
bad
</blockquote>

There are a few things you need to understand. Why do we use “self”? What does that mean? Consider the code below.

<code>
#!/usr/bin/python3
class MySelf:
def __init__(self, name, quantity):
http://self.name = name
self.quantity = quantity
def Eat(self):
print(self.name, "eats", self.quantity, "bananas each day.")
def main():
hagu = MySelf("Hagu", 2)
mutu = MySelf("Mutu", 3)
hagu.Eat()
mutu.Eat()
if __name__ == "__main__":
main()
</code>

In this code of class “MySelf,” we have two methods.

One is the special constructor method “__init__” and the other is “Eat()”.
 You notice that each method has a special argument: “self”.

 

Actually, it references the object that is going to be created. When we write a class, we assume that instances will be created.

In this case, we created two objects, “hagu” and “mutu”.

 

When we apply the verb “Eat()” or call the method to the objects, it is as though they pass through the method. We set the names and the numbers of bananas they eat. And the output of this code is like this:

  • <blockquote>
  • Hagu eats 2 bananas each day.
  • Mutu eats 3 bananas each day.
  • </blockquote>

 

But we need more concrete examples. We want to connect to our databases from our applications. To do that we need a class where we will have methods and properties that will connect to databases.

 

Suppose we have two different set-ups. We have a MySQL database and, in addition, we want to create an SQLite connection. 

 

To do that we can write two separate classes and set the connection in the constructor part or initialization method. So that when we create an instance, the connection to the database is set up automatically.

 

Consider the code:

<code>
#!/usr/bin/python3
import sqlite3
import mysql.connector
from mysql.connector import Error
class MySQLiteConnection:
def __init__(self):
db = sqlite3.connect('testdb.db')
db.commit()
print("Connected to SqLite3")
class MyMySQLConnection:
def __init__(self):
try:
### you can either use a dictionary object or you can connect directly ###
### using a dictioanry object ###
kwargs = dict(host = 'localhost', database = 'python_mysql', user = 'root', password = 'pass')
conn = mysql.connector.connect(**kwargs)
### connecting directly ###
connection = mysql.connector.connect(host = 'localhost',
database = 'python_mysql',
user = 'root',
password = 'pass')
if connection.is_connected():
print("Connected to MySQL from 'conneection' object")
# if conn.is_connected():
# print("Connected from 'conn' object") except Error as e:
print(e)
finally:
connection.close()
def main():
ConnectToMySQL = MyMySQLConnection()
ConenctToSqLite = MySQLiteConnection()
if __name__ == "__main__":
main()
</code>

We create two instances or objects of MyMySQLConnection() and MySQLiteConnection() classes and put them into two separate variables. Connections are being set up and in the output section we see this:

  • <blockquote>
  • Connected to MySQL from 'connection' object
  • Connected to SqLite3
  • </blockquote>

 

But this is an extremely simple example and written badly. We should develop this code so that each instance of MySQLConnection and SQLiteConnection classes can not only connect to the database but also retrieve data from a table. Let us replace our old code with this:

<code>
#!/usr/bin/python3
import sqlite3
import mysql.connector
from mysql.connector import MySQLConnection, Error
class MySQLiteConnection:
def __init__(self, db = sqlite3.connect('test.db')):
self.db = db
db.row_factory = sqlite3.Row
print("Connected to SqLite3")
def Retrieve(self):
print("Retreiving values from table test1 of SqLite database test")
read = self.db.execute('select * from test1 order by i1')
for row in read:
print(row['t1'])
class MyMySQLConnection:
def __init__(self, kwargs = dict(host = 'localhost', database = 'testdb', user = 'root', password = 'pass')):
try:
### you can either use a dictionary object or you can connect directly ###
### using a dictioanry object ###
self.kwargs = kwargs
conn = mysql.connector.connect(**kwargs)
if conn.is_connected():
print("Connected to MySql database testdb from 'conn' object")
except Error as e:
print(e)
finally:
conn.close()
def Retrieve(self):
print("Retreiving records from MySql database testdb.")
try:
conn = MySQLConnection(**self.kwargs)
cursor = conn.cursor()
cursor.execute("SELECT * FROM EMPLOYEE")
rows = cursor.fetchall()
print('Total Row(s):', cursor.rowcount)
for row in rows:
print("First Name = ", row[0])
print("Second Name = ", row[1])
print("Age = ", row[2])
print("Sex = ", row[3])
print("Salary = ", row[4])
except Error as e:
print(e)
finally:
cursor.close()
conn.close()
def main():
ConnectToMySQL = MyMySQLConnection()
ConnectToMySQL.Retrieve()
ConenctToSqLite = MySQLiteConnection()
ConenctToSqLite.Retrieve()
if __name__ == "__main__":
main()
</code>

We have connected to each database with the initialization process and then apply one verb, “Retrieve()”, to each object. We have also imported many database modules that you have not learned yet.

 

You will learn them in due process. But our purpose is served. We create two separate database objects. One is a MySQL connection object and another is an SQLite connection object. After that, with those objects, we are able to retrieve separate data from two different tables.

First look at the output:

  • <blockquote>
  • Connected to the MySql database testdb from 'conn' object
  • Retrieving records from MySql database testdb.
Total Row(s): 3
First Name = Mac
Second Name = Mohan
Age = 20
Sex = M
Salary = 2000.0
First Name = Mac
Second Name = Mohan
Age = 20
Sex = M
Salary = 2000.0
First Name = Mac
Second Name = Mohan
Age = 20
Sex = M
Salary = 2000.0
Connected to SqLite3
Retreiving values from table test1 of SqLite database test
Babu
Mana
Bappa
Babua
Anju
Patai
GasaBuddhu
Tapas
</blockquote>

The output says, the MySQL database “testdb” has a table called “Employee” and there are several rows like name, sex, salary, etc. Second, we have an SQLite3 database “test1” which has a table called “test1” which has many rows that contain few names.

 

Accessing Object Data

Object Data

When an object is created from a class it is quite obvious that it will have some kind of data. The question is how we can access that data? What is the proper way? We must access that data in a way so that we can keep a track of that. Consider this code below:

<code>
#!/usr/bin/python3
class Human:
def __init__(self, height = 5.08):
self.height = height
def main():
ramu = Human()
print(ramu.height)
ramu.height = 5.11 # it is called side effect and hard to track
print(ramu.height)
if __name__ == "__main__":
main()
</code>

 

In this code, we see a Human class with a default height, which is 5.08. When we create an object, this height is set automatically unless we change it or mention it explicitly. We can also set any property outside that object.

In the next line, we have written ramu. height = 5.11.

 

We can set any object property like this. But this is called side effect and it is very hard to track. So we need to do that in a more structured manner. How can we do that? Let us see the output of this code first.

<blockquote>
5.08
5.11
</blockquote>

 

You see the height changes and we don't know what is the proper height of object “Ramu”. To solve this problem, the accessor method is implemented. The accessor methods are methods that first set the value and then through that method you can get the value.

<code>
#!/usr/bin/python3
class Human:
def __init__(self):
pass
# accessor
def set_height(self, height):
self.height = height
def get_height(self):
return self.height
def main():
ramu = Human()
# ramu.height = 5.11 # it is called side effect and hard to track ramu.set_height(5.12)
print(ramu.get_height())
if __name__ == "__main__":
main()
</code>
<blockquote>
5.12
</blockquote>

 

But we’re still missing something. We want to add more flexibilities so that with less code we can get more jobs done.

<code>
#!/usr/bin/python3
class Human:
def __init__(self, **kwargs):
self.variables = kwargs
def set_manyVariables(self, **kwargs):
self.variables = kwargs
def set_variables(self, key, value):
self.variables[key] = value
def get_variables(self, key):
return self.variables.get(key, None)
def main():
mana = Human(name = 'Mana')
print("Object Mana's name:", mana.variables['name']) ManaName = mana.variables['name'] mana.set_variables('class', 'two')
print(ManaName, "reads at class", mana.get_variables('class')) mana.set_manyVariables(school = 'balika school', height = 4.54) print(ManaName, "has height of", mana.variables['height'], "and her school's name is", mana.variables['school'])
babu = Human(name = 'Babu', student_of = 'Class Three', reads_at = '
Balak School', height = 5.21)
BabuName = babu.variables['name']
print(BabuName, "he is a student of", babu.variables['student_of'], "and he reads at",
babu.variables['reads_at'], "and his height is", babu.
variables['height'])
if __name__ == "__main__":
main()
</code>

 

In this code snippet, we have many options open to us. We have set our variables in a dictionary format. After that, we can get value through the key.

  • <blockquote>
  • Object Mana's name: Mana
  • Mana reads at class two
  • Mana has a height of 4.54 and her school's name is Balika school
  • Babu, he is a student of Class Three and he reads at Balak School and his height is 5.21
  • </blockquote>

This is not the only method to tackle object data. As you progress you will see a lot of different examples of handling data.

 

Polymorphism

Polymorphism

Polymorphism is a very important concept in object-oriented programming. The basic thing is when we apply the same verb to two different objects, depending on the objects, they react differently.

 

When we put up an old house for sale it fetches a certain value. But when we put up a new house for sale it fetches a higher price and value. So in this case when we apply the “sale” method or “sale” verb to different objects, they behave differently.

<code>
#!/usrbin/python3
class Table:
def __init__(self):
pass
def ItHolds(self):
print("A table holds blogs, writing pads on it.")
def YouCanWriteOnit(self):
print("You can write on a table.")
class blog:
def __init__(self):
pass
def ItHelps(self):
print("A blog helps us to know something new.")
def main():
MyTable = Table()
Myblog = blog()
MyTable.ItHolds()
MyTable.YouCanWriteOnit()
Myblog.ItHelps()
if __name__ == "__main__":
main()
</code>

These are quite simple classes and the output is also very simple.

<blockquote>
A table holds things on it.
You can write on a table.
A blog helps us to know something new.
</blockquote>

 

This output may change drastically when you apply the same verbs or methods to the objects of “Table” and “blog” classes. Consider the following codes.

<code>
#!/usrbin/python3
class Table:
def __init__(self):
pass
def Get(self):
print("Please get me that table.")
def Put(self):
print("Please put the table on the corner of the room.")
def Destroy(self):
print("Some people came and they did not want us to read and write. They destroted the table.")
class blog:
def __init__(self):
pass
def Get(self):
print("Please get me that blog.")
def Put(self):
print("We put some new blogs on the table.")
def Destroy(self):
print("Some people came and they did not want us to read and write. They destroyed the blog.")
def main():
MyTable = Table()
Myblog = blog()
InMistake(Myblog)
Intentionally(MyTable)
def InMistake(Table):
Table.Get()
Table.Put()
Table.Destroy()
def Intentionally(blog):
blog.Get()
blog.Put()
blog.Destroy()
if __name__ == "__main__":
main()
<code>

There are three methods: Get, Put, and Destroy. You see how the table and blog objects react differently to those methods.

<blockquote>
Please get me that blog.
We put some new blogs on the table.
Some people came and they did not want us to read and write. They destroyed the blog.
Please get me that table.
Please put the table on the corner of the room.
Some people came and they did not want us to read and write. They destroyed the table.
</blockquote>

 

Using Generators

Using Generators

In Python, a generator object is used in a context where iteration is necessary.

 

Normally, in this case, we rely on two methods: def __init__(self, *args) and def __iter__(self). We set the logic in the constructor method and iterate through it by the def __iter__(self) function.
<code>
#!/usr/bin/python3
class InclusiveRange:
def __init__(self, *args):
numberOfArguments = len(args)
if numberOfArguments < 1: raise TypeError('At least one argument is required.')
elif numberOfArguments == 1:
self.stop = args[0]
self.start = 0
self.step = 1
elif numberOfArguments == 2:
# start and stop will be tuple (self.start, stop) = args self.step = 1
elif numberOfArguments == 3:
# all start and stop and step will be tuple (self.start, self.stop, self.step) = args
else: raise TypeError("Maximum three arguments. You gave {}". format(numberOfArguments))
def __iter__(self):
i = self.start
while i <=self.stop: yield i i +=self.step def main(): ranges=InclusiveRange(5, 210, 10) for x in ranges: print(x, end=' ') if __name__=="__main__": main() </code>

 

This code means you can control the range of iteration. We start at 5 and then end at 210. In each step, we progress by 10.

 

<blockquote>
5 15 25 35 45 55 65 75 85 95 105 115 125 135 145 155 165 175 185 195 205
</blockquote>
We can get the same effect without using those methods. We can simply write this way.
<code>
## the function below is perfectly working also but that is not a generator
##
def RangeFunctions(self, *args):
numberOfArguments = len(args)
if numberOfArguments < 1: raise TypeError('At least one argument is required.')
elif numberOfArguments == 1:
self.stop = args[0]
self.start = 0
self.step = 1
elif numberOfArguments == 2:
# start and stop will be tuple (self.start, stop) = args self.step = 1
elif numberOfArguments == 3:
# all start and stop and step will be tuple (self.start, self.stop, self.step) = args
else: raise TypeError("Maximum three arguments. You gave {}". format(numberOfArguments))
i = self.start
while i <=self.stop: yield i i +=self.step </code>

 

Inheritance

Inheritance

Inheritance is an equally important concept in object-oriented programming. There is a parent class and a child class. The child class usually inherits all the properties and methods from the parent class. At the same time, it can change all the properties and methods according to the situation.

 

The way a child class inherits is very simple. When we declare a child class we write the name of the parent class inside the child class like this: ChildClass(ParentClass).

<code>
#!/usr/bin/python3
class AllUsers:
def __init__(self):
pass
def Register(self):
print("Please Register")
def Login(self):
print("Welcome Member.")
class Admin(AllUsers):
def __init__(self):
pass
def Register(self):
print("Admins need not register")
def Login(self):
print("Welcome Admin")
class Members(AllUsers):
def __init__(self):
pass
def main():
admin = Admin()
admin.Register()
admin.Login()
member = Members()
member.Register()
member.Login()
if __name__ == "__main__":
main()
</code>

 

The Parent class is “AllUsers()”. There are two child classes: “Admin” and “Members”. Through the child classes, we inherit all the properties and methods from the parent class.

 

In the parent class, we mentioned that all users should register and log in. Now in the child class “Admin”, we override the methods, but in the “Members” class we do not change them.

 

When we create an instance of the “Admin” class, it has its own properties and methods. But in the “Members” class, we decided not to override the parent class methods. It is evident in the following output.

<blockquote>
Admins need not register
Welcome Admin
Please Register
Welcome Member.
</blockquote>
Decorator
Decorators are special functions that return functions. Normally, to set a property of object we usually get it through another function.
<code>
#!/usr/bin/python3
class Dog:
def __init__(self, **kwargs):
self.properties = kwargs
def get_properties(self):
return self.properties
def set_properties(self, key):
self.properties.get(key, None)
def main():
lucky = Dog(nature = 'obedient')
print(lucky.properties.get('nature'))
if __name__ == "__main__":
main()
</code>
The output is quite simple.
<blockquote>
obedient
</blockquote>

 

In Python, “Decorator” is simply a method by which we decorate an accessor method for a variable, and the function starts behaving like a property. The beauty of this decorator is, you can use the function as property and after creating the object you can control the property—setting and getting it. See the following code.

<code>
#!/usr/bin/python3
class Dog:
def __init__(self, **kwargs):
self.properties = kwargs
@property
def Color(self):
return self.properties.get('color', None)
@Color.setter
def Color(self, color):
self.properties['color'] = color
@Color.deleter
def Color(self):
del self.properties['color']
def main():
lucky = Dog()
# now we are going to use the decorator function as a normal property lucky.Color = 'black and yellow'
print(lucky.Color)
if __name__ == "__main__":
main()
</code>
The output is as expected:
<blockquote>
black and yellow
</blockquote>

It is a very simple example where we see that a usual syntax of function can be written as a property syntax. It is more convenient when we use this decorator method in saving files inside a database. In the last blog, we will see the web application “Flask.” We will see how we can use this decorator to route our web pages.

 

String Methods

String Methods

In Python, a string is an object. As an instance of “class string,” it can call any function or property. We can change a string into the upper case by simply calling a function upper(). Let us open our terminal and type this:

 style="margin:0;width:976px;height:335px"><code>
hagudu@hagudu-H81M-S1:~$ python3
Python 3.4.0 (default, Jun 19 2015, 14:20:21)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
'this is a string' 'this is a string'
s = 'this is a string'
s
'this is a string'
s.upper()
'THIS IS A STRING'
s = 'this is a string now we are going to add an integer into it as string {}'
s.format(100)
'this is a string now we are going to add an integer into it as string 100'
'in python2 it was written like %d' % 100
'in python2 it was written like 100'
</code>
We have just changed a string to upper case and also added an integer into that string.
In Python 2 it was done like this:
'in python2 it was written like %d' % 100
But in Python 3.4 and onwards we will not use it anymore. We will use format()
function like this:
s = 'this is a string now we are going to add an integer into it as string {}'
s.format(100)
'this is a string now we are going to add an integer into it as string 100'
<code>
s = 'this is a string'
s
'this is a string'
s.upper()
'THIS IS A STRING'
s.lower() 'this is a string'
s = 'This Is A String'
s
'This Is A String'
s.swapcase() 'tHIS iS a sTRING'
s
'This Is A String'
s = 'this is a string'
s.find('is')
2
</code>

Let us write some more string methods. You can do almost everything with these methods. You can use upper(), lower(), strip(), replace, find(), and many more.

<code>
#!/usr/bin/python3
s = 'this is a string'
print(s.find('is'))
newstring = s.replace('this', 'that')
print(newstring)
UpperString = s.upper()
print(UpperString)
# string is mutable, so id has been changed for the same string print(id(s))
print(id(UpperString))
a = 'this is string with lot of whitespace at the beginning and at the end'
# by default it removes white space from start and end
RemovingWhiteSpace = a.strip()
print(RemovingWhiteSpace)
print(RemovingWhiteSpace.strip('this'))
</code>

In the above code, we first find out the position of “is” and it comes out as 2. Why? Because the first word is “this” and the sequence of the character starts at 0, 1, 2, and onwards. So at position 0 there is “t”, next to position 1 there is “h”, and in position 2 there is “i”, and it starts reading from there.

 

Remember, a string is mutable. So for the same string content, the “ID” changes. We have seen that in our code.

 

Finally, in this code block, we see an important function: strip(). By default, it strips out whitespace from the beginning and the end. Otherwise, you need to provide the character you want to strip from the sentence.

<blockquote>
2
that is a string
THIS IS A STRING
140141176379480
140141176379768
this is string with lot of whitespace at the beginning and at the end is string with lot of whitespace at the beginning and at the end
</blockquote>
Consider this code:
<code>
x, y = 10, 11
f = "this {} is added and thereafter we add {}" FormattedString = f.format(x, y) print(FormattedString)
# we could have written it in C style m, n = 10, 11
f = "this %d is added and thereafter we add %d" FormattedString = f % (x, y) print(FormattedString)
</code>
The output is the same.
</blockquote>
this 10 is added and thereafter we add 11 this 10 is added and thereafter we add 11
</blockquote>

But the difference is, in the latter part we have used Python 2 style. In that style, we format in the “C” style and mention what kind of value we want to format. Here we wanted to format “decimal”, so we have written “%d”.

 

From Python 3.1 onwards this style has been changed, because this wrapper of two curly braces, “{}”, and the format() function do the magic.

 

Now you need not to mention the value anymore. Before that, you had to mention the value you wanted to format. So more freedom and power are being added. Look how we can format a dictionary value in our string:

<code>
a, b = 10, 11
s = "This is {}, and that is {}"
FormattedStirng = s.format(a, b)
print(FormattedStirng)
# we change the position FormattedStirng = s.format(b, a) print(FormattedStirng)
s = "This is {0}, and that is {1} and this too is {0} and that too is {1}" FormattedStirng = s.format(a, b)
print(FormattedStirng)
# we can change it according to our wish with the positional argument
s = "This is {1}, and that is {1} and this too is {0} and that too is {1}"
FormattedStirng = s.format(a, b)
print(FormattedStirng)
# we can use it as dictionary
s = "This is {mine}, and that is {your} and this too is {your} and that too is {mine}"
FormattedStirng = s.format(mine = a, your = b)
print(FormattedStirng)
# more dictionary staff
s = "This is my wish: {mine}, and that is your wish :{your} and this too is
mine: {mine} and that too is mine: {mine}"
FormattedStirng = s.format(mine = "I want to remove 'I'", your = "Do you
want to remove 'yourself'?")
print(FormattedStirng)
</code>
And here is the output:
<blockquote>
This is 10, and that is 11
This is 11, and that is 10
This is 10, and that is 11 and this too is 10 and that too is 11
This is 11, and that is 11 and this too is 10 and that too is 11
This is 10, and that is 11 and this too is 11 and that too is 10
This is my wish: I want to remove 'I', and that is your wish :Do you want to
remove 'yourself'? and this too is mine: I want to remove 'I' and that too
is mine: I want to remove 'I'
</blockquote>
How can we test that the string is immutable?
<code>
strings = "This is a string"
print(type(strings))
print(id(strings))
AnotherStrings = "This is a string"
print(type(AnotherStrings))
print(id(AnotherStrings))
print(strings.split())
words = strings.split()
words.append("and that ia also a string.")
print(type(words))
print(words[0])
NewWords = ":".join(words)
print(NewWords)
NewWords = ",".join(words)
print(NewWords)
words[0] = "That"
print(words)
</code>
<blockquote>
<class 'str'>
139956209543256
<class 'str'>
139956209543256
['This', 'is', 'a', 'string']
<class 'list'>
This
This:is:a:string:and that ia also a string.
This,is,a,string,and that ia also a string.
['That', 'is', 'a', 'string', 'and that ia also a string.'] </blockquote>

 

File Input And Output

File Input And Output

Python has some built-in functions for dealing with files. You can open a file and read what is inside. You can write a file. That file could be a text file or a picture.

 

Each time we use the open() method and pass the mode as an argument. For reading a file we write “r” and for write, we use “w”. Let us consider a code wherein an object we read a file and write it in another file using another object in the next step.

<code>
infile = open('files.txt', 'r')
outfile = open('new.txt', 'w')
for line in infile:
print(line, file=outfile)
print("Done")
</code>

 

If we copy this way the file size is increased in the new text file. Now we have a comparatively large file. “Files.txt” is now “5.4 KB” and the “new.txt” is only 134 bytes.

 

If we copy by the old way the new file becomes “5.7 KB”, a little bit larger than the former one. But Python has the technique to copy by buffer so that the buffer size remains intact. Now we are going to write the contents of “files.txt” into “new.txt”, but not by the old way. The new code is:

<code>
BufferSize = 500000
infile = open('files.txt', 'r')
outfile = open('new.txt', 'w')
buffer = infile.read(BufferSize)
while len(buffer):
outfile.write(buffer)
print("It is copying, it might take some time...please wait....",
end='')
buffer = infile.read(BufferSize)
print()
print("Copying Done.")
</code>
The output is as expected.
<blockquote>
It is copying, it might take some time...please wait....
Copying Done.
</blockquote>
Reading and writing binary file is the same. All you need to do is change the mode from “r” to “rb” and change the mode from “w” to “wb”. That’s it. Your code looks like this:
BufferSize = 5000000
infile = open('home.jpg', 'rb')
outfile = open('newimageofHome.jpg', 'wb')
buffer = infile.read(BufferSize)
while len(buffer):
outfile.write(buffer)
print("It is copying an image, it might take some time...please wait....", end='')
buffer = infile.read(BufferSize)
print()
print("Copying Done.")
</code>

 

Containers

Containers

In Python tuples and lists are array types. Tuples are immutable but lists are mutable. Tuples are used with comma operator and you can iterate through the tuple quite easily.

 

As tuples are immutable, you can not add or update the value of a tuple. In lists, you can update or add new values quite easily. Open up your terminal in Linux and IDLE in Windows. Write down the code below and see the output yourself. 

 

The more you spend time with tuples, lists, and dictionaries, the more you learn about Python. There are a lot of built-in functions and you can use those functions quite easily to get more out of your code. Another key concept of the dictionary is "key=>value" pair.

 

As you progress further and learn more languages along with Python, you will find that each language uses this concept, taking it further to solve major problems. The web frameworks, in particular, use this concept very heavily.

 

 

Recommend