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:

INPUT: Get data from a keyboard or any file or any source.

OUTPUT: Display data on screen or send it to any file, device or any other source.

MATHEMATICS: Do some basic mathematical operations like add, subtract, multiply or divide. It can be complex also. It depends on your application.

CONDITIONAL EXECUTION: Check that the conditions are properly met. Like “if that is true then do something else/do some other thing.”

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.

 

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 to 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 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

Indentation and 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 “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 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 “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, Objects

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 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 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. It is cumbersome.

 

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 is 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, 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 a 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 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.

 

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 “re” module and it does the simple jobs. A regular expression is a big topic. We try to understand the basic things so that we can use it in our future projects.

 

Using “re” Module

If you want to use “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 “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 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 with Regular Expressions

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 “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 a 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

Lists of 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. A 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 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 an 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 a 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 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

Accessing 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 the 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 from 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 “Admin” class, it has its own properties and methods. But in “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 a 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 the position 0 there is “t”, next to position 1 there is “h”, and in the 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 “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.

 

Database

Database

Database operations in Python are fairly simple. For the small amount of work, the built-in SQLite3 is quite competitive. You can easily maintain it by creating, retrieving and updating and deleting it.

 

The basic term is “CRUD.” “C” stands for creating, “R” stands for retrieve, “U” for the update, and “D” for delete. With any database, you generally perform these actions.

 

Let us start with SQLite3.

There is a large library inside the Python home. All the functions and properties of SQLite3 are stored there, so you can easily import them and use them for your project. Consider this code:

<code>
#!/usr/bin/python3
import sqlite3
def main():
db = sqlite3.connect('test.db')
db.row_factory = sqlite3.Row
db.execute('drop table if exists test1')
db.execute('create table test1 (t1 text, i1 int)')
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Babu', 1))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Mana', 2))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Bappa', 3))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Babua', 4))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Anju', 5))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Patai', 6))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('GasaBuddhu', 7))
db.execute('insert into test1 (t1, i1) values (?, ?)', ('Tapas', 8))
db.commit()
DatabaseRead = db.execute('select * from test order by i1')
for row in DatabaseRead:
# print(dict(row))
print(row['t1'])
# print(row['t1'], row['i1'])
# print(type(row))
if __name__ == "__main__":main()
</code>

If you run this code, you will see a list of names I just added. As you see, we have connected with a database, “test”. Next, we added a table with two columns. The first column is the id integer and we keep the ID of each name inside it. The second column is the placeholder of the text. We keep a few names there.

 

You can write the same code and test it. It will give you the same result. Once you run the code, you will find that a file “test.db” has been created inside your project.

 

MySQL for Big Project

 MySQL for Big Project

SQLite3 is good for a small amount of work. But for a big project, it is better to opt for a database like MySQL. To work with MySQL in Python3 you need to download and install MySQL connector.

 

The download and installation part is quite easy. In Python2 you can by default import MySQL Connector. But for Python3, you need to download the file. Open Welcome to Python.org and search for MySQL Connector.

 

Download the file and run “http://setup.py”.

Once you download and install the MySQL Connector module it is fairly simple and easy to connect to any MySQL database. Consider this code where we simply connect to a MySQL database and have a printout “connected.” 

 

If MySQL or any database operation is completely new to you, it is better to learn about the simple database operations and database query language. In Windows or Linux, installing PHPMyAdmin is very easy. Just install it and you need not to write all the SQL code to build a database and all the tables.

 

Let us assume that we have a database called “python-MySQL”. In that database, we have some tables. Now we are going to connect to that database first.

<code>
#!/usr/bin/python3
import mysql.connector
from mysql.connector import Error
def ConnectionTest():
### connecting to MySQL Database ###
try:
### you can either use a dictionary object or you can connect directly ###
### using a dictioanry connection 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 conn.is_connected():
print("Connected from 'conn' object")
except Error as e:
print(e)
finally:
connection.close()
if __name__ == "__main__":
ConnectionTest()
</code>

It will give us a printout “Connected from a conn object”. It means the database connection has been set up. Now it is time to retrieve the value from the table.

 

In this database, we have two tables. One is of “authors” and the other is “blogs”. MySQL Connector class has all the functions needed to perform any task to those tables. You can fetch all the records. You can decide how many blogs or how many authors you would like to fetch. The following code shows you both. But a few parts have been commented out.

 

To test this code you need to have a database first. Name it “python-MySQL”. Next, you need to have two tables called “authors” and “blogs”. You also need to fill up those tables.

 

It is always better to search online and download a ready-made MySQL database and tables. They are available. It is highly suggested that you search for MySQL Connector and see what you find.

 

In the following code, please go through the commented sections also. That says a lot about how you can retrieve your records and show them to the world.

<code>
#!/usr/bin/python3
import mysql.connector
from mysql.connector import Error
def RetrieveValues():
try:
kwargs = dict(host = 'localhost', database = 'python_mysql', user = 'root', password = 'pass')
conn = mysql.connector.connect(**kwargs)
### shows you how to query data from a MySQL database in Python by using MySQL Connector/Python API
# such as fetchone() , fetchmany() , and fetchall() ###
if conn.is_connected(): cursors = conn.cursor() cursors.execute('SELECT * FROM authors')
# row = cursors.fetchone()
# output (1, 'Bel and the Dragon ', '123828863494')
######
# now we try to get all the blogs
# row = cursors.fetchall()
# print(type(row))
# output <class 'list'>, so we can use for loop
# for blogs in row:
# print(blogs)
# it will give us list of all the blogs
######
### now we give the size of how many blogs we want to get ###
# HowManyblogs = 8
# row = cursors.fetchmany(HowManyblogs)
# for blogs in row:
# print(blogs)
# we get the output of 8 blogs
row = cursors.fetchall()
for blogs in row:
print(blogs)
except Error as e:
print(e)
finally: conn.close()
if __name__ == "__main__":
RetrieveValues()
</code>

 

We have used the try and error method so that if the connection fails, it would not show an ugly “Error” message on your project. Second, this method is quite direct. You can also use a configuration file to do the same thing. 

 

It is strongly advisable to use a configuration file (we say “config file”). The configuration file has all the things necessary to connect to the database. We can write in the configuration file like this and save it as “mysql_config.ini”.

<code>
[mysql]
host = localhost
database = YourDatabaseName
user = root
password = pass
</code>
Let us see how this “.ini” file can be parsed through our Python code. We save this file as “MySQL_Connector.py”.
<code>
#!/usr/bin/python3
from configparser import ConfigParser
def ReadingMySQLConfig(filemame = 'mysql_config.ini', section = 'mysql'):
parser = ConfigParser()
parser.read(filemame)
db = dict()
if parser.has_section(section):
items = parser.items(section)
for item in items:
db[item[0]] = item[1]
else:
raise Exception('{0} not found in the {1} file'.format(section,
filemame))
return db
</code>

 

You see that we have imported the necessary modules for parsing the configuration file and finally we have used that configuration file to connect to the database.

 

And in the above code of “MySQL_Connector.py” we have included that “mysql_config.ini” file in this line—def ReadingMySQLConfig(filemame = 'mysql_config.ini', section = 'mysql'):—as an argument.

How we can use this configuration file to test our connection is shown below.

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def Connect():
kwargs = ReadingMySQLConfig() MyConnection = MySQLConnection(**kwargs) try:
if MyConnection.is_connected():
print("Connected")
except Error as e:
print(e)
finally:
MyConnection.close()
if __name__ == "__main__":
Connect()
</code>

 

Now we have decoupled our code more. We are able to divide it into small segments so that our connection code looks extremely small and organized. But you can always connect to your MySQL database like below.

<code>
#!/usr/bin/python3
# -*- coding: utf-8 -*-import mysql.connector
from mysql.connector import Error def connect():
""" Connect to MySQL database """
try:
conn = mysql.connector.connect(host='localhost',
database='YourDatabase',
user='root',
password='YourPassword')
if conn.is_connected():
print('Connected to MySQL database')
except Error as e:
print(e)
finally:
conn.close()
if __name__ == '__main__':
connect()
</code>

 

Now the time has come to retrieve records from the database. We are able to connect to the database. Now, there should not be any trouble fetching records from the tables of the database. We have two built-in methods in our Python library.

The methods are “fetchmany()” and “fetchall()”.

The first method, “fetchmany()”, gives you the liberty to decide how many rows you are going to fetch. Let us see the code:

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from Databases.python_mysql_dbconfig import read_db_config def iter_row(cursor, size=10):
while True:
rows = cursor.fetchmany(size)
if not rows:
break
for row in rows:
yield row
def query_with_fetchmany():
try:
dbconfig = read_db_config()
conn = MySQLConnection(**dbconfig)
cursor = conn.cursor()
cursor.execute("SELECT * FROM EMPLOYEE")
# EMPLOYEE is the table name
for row in iter_row(cursor, 10):
print(row)
except Error as e:
print(e)
finally:
cursor.close()
conn.close()
if __name__ == '__main__':
query_with_fetchmany()
</code>
The method “fetchall()” brings all the records from a table.
<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from Databases.python_mysql_dbconfig import read_db_config def query_with_fetchall():
try:
dbconfig = read_db_config()
conn = MySQLConnection(**dbconfig)
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()
if __name__ == '__main__':
query_with_fetchall()
</code>

You see how we can fetch the records as our requirements. Now let us try to test the insertion process. In our CRUD application, the first “C” stands for “Create.” Here the word “Create” means nothing but the insertion of new records. Through MySQL Connector it is quite simple. All you need is that the connection must be on. After that, you need to insert your records.

 

Here is the code. We have a “blog” table in our database and we are going to insert two records into it. One is the title of the blog and the other is the ISBN code of the blog.

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def Insertblogs(blogs):
query = "INSERT INTO blogs(title, isbn) VALUES(%s, %s)"
try:
kwargs = ReadingMySQLConfig() MyConnection = MySQLConnection(**kwargs) if MyConnection.is_connected():
cursor = MyConnection.cursor()
cursor.executemany(query, blogs)
MyConnection.commit()
except Error as e:
print(e)
finally:
MyConnection.close()
def main():
blogs = [("Testblog", 1236547890)]
Insertblogs(blogs)
print("Inserted one blog")
if __name__ == "__main__":
main()
</code>

 

We have successfully inserted one blog title and ISBN code. The next process will be updating that title and ISBN code. That is also very easy. All you need is the unique ID of the blog. Once you have provided the unique ID of the blog, you can update it easily.

<ocde>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def Updateblogs(blog_id, title):
kwargs = ReadingMySQLConfig()
data = (title, blog_id)
query = "UPDATE blogs SET title = %s WHERE id = %s"
try:
MyConnection = MySQLConnection(**kwargs)
cursor = MyConnection.cursor()
cursor.execute(query, data)
MyConnection.commit()
except Error as e:
print(e)
finally:
MyConnection.close()
def main():
for id in range(1, 25):
if id == 3:
Updateblogs(id, "I Have A Dream")
print("One blog has been updated")
elif id == 4:
Updateblogs(id, "Laravel 5 Unfolded")
print("One blog has been updated")
elif id == 5:
Updateblogs(id, "Play With Python")
print("One blog has been updated")
if __name__ == "__main__":
main()
</code>

 

We have successfully updated three blogs which have unique IDs of 3, 4, and 5, respectively. Finally, we will see how we can delete a record. To delete a record, once again you need the unique ID.

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def Deleteblogs(blog_id):
kwargs = ReadingMySQLConfig()
query = "DELETE FROM blogs WHERE id = %s"
try:
MyConnection = MySQLConnection(**kwargs)
cursor = MyConnection.cursor()
cursor.execute(query, (blog_id,))
MyConnection.commit()
except Error as e:
print(e)
finally:
MyConnection.close()
def main():
id = 87
Deleteblogs(id)
print("Deleted ", id, "number of blog from blogs")
if __name__ == "__main__":
main()
</code>

In this code, this line—“cursor.execute(query, (blog_id,))”—is extremely important. You probably notice that we have used a “,” separator after the “blog_id”. It is your task to find out why this comma separator has been used. The only clue is it is related to either “tuples” or “lists”. It is your task that you find out what is the actual reason.

 

Like every modern version of relational databases, MySQL also allows you to keep a binary large object inside it. Normally when you write numbers or strings they do not take up much space. But what about the images?

 

Let us assume that we have an author table where we need to keep images for the authors. We may also want to keep the cover pictures of the blogs in our blog table.

 

Normally this image or any binary large object is called, in short, “BLOB”. Let us update our author table with an image and see how it works.

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def ReadFile(filename):
with open(filename, 'rb') as f:
images = f.read()
return images
def UpdateImage(author_id, filename):
kwargs = ReadingMySQLConfig()
data = ReadFile(filename)
query = "UPDATE authors SET photo = %s WHERE id = %s"
args = (data, author_id)
try:
MyConnection = MySQLConnection(**kwargs)
cursor = MyConnection.cursor()
cursor.execute(query, args)
MyConnection.commit()
except Error as e:
print(e)
finally:
MyConnection.close()
def main():
id = 47
UpdateImage(id, "/home/hagudu/Pictures/ss.jpg")
print("Image of author ID", id, "has been updated.")
if __name__ == "__main__":
main()
</code>

The code is fairly simple. At least at this stage, you should find it simple. The steps are like this:

\1.\ Read the file with the help of the “with” keyword and store it in a variable and return it. We pass the parameter through the function. See the first function: “ReadFile(filename)”.

 

\2.\ The second function is crucial because it passes the same file name as one of the parameters. It also connects to the database and commits. See the second function: “UpdateImage(author_id, filename)”.

 

\3.\ Finally, we call the second function and pass the path of the image file as an argument so that our Python code reaches there and retrieves the image by opening it and finally committing to the database.

 

Now we are going to retrieve one image from the database and write it on our local disk. In the previous code we have read the file. Now it is time to write the file on our disk. The code is almost similar except for a few changes.

<code>
#!/usr/bin/python3
from mysql.connector import MySQLConnection, Error
from MySQL_Connector.mysql_config import ReadingMySQLConfig def WriteFile(data, filename):
with open(filename, 'wb') as files:
files.write(data)
def ReadImage(author_id, filename):
kwargs = ReadingMySQLConfig()
query = 'SELECT photo FROM authors WHERE id = %s' try:
MyConnection = MySQLConnection(**kwargs) cursor = MyConnection.cursor() cursor.execute(query, (author_id,)) photo = cursor.fetchone()[0] WriteFile(photo, filename)
except Error as e:
print(e)
finally:
MyConnection.close()
def main():
id = 47
ReadImage(id, "/home/hagudu/Pictures/ss1.jpg")
if __name__ == "__main__":
main()
</code>
Module

 

In Python when you leave the shell or terminal or Python interpreter, the script is lost. After all, you don’t write programs to lose at the end of the day. It may be a simple calculator program. But you want to use it again. Another important thing is you need to use your one code in your other code. You may want to use other people’s code also.

 

To solve this dilemma, the concept of “module” comes in.

You write a simple calculator program and save the file as “http://cal.py”. If you are in the root directory of your project you can easily use your calculator in your other program. Once you write a Python code and save it with a name, that name becomes a module.

 

In this case, “cal” becomes a module. Now you can “import” that “cal” module into any other code or module. In the large Python library, there are tons of modules. You can always import them and use them. Consider the code below. In this code, we have imported three modules. The first is “sys” or system-specific module.

 

The second one is “os” or operating system–specific module
​ and the third one is “urllib” which means a library that is URL-specific. 
​You notice that we write "urllib.request".

 

The “dot” notation means we actually call something called “request” from the Python URL library. Actually, the web architecture primarily depends upon two things: request and respond. Here we are going to request something from a URL.

<code>
#!/usr/bin/python3
import sys, os, urllib.request
def main():
print("This is Python Version : {}.{}.{}".format(*sys.version_info))
# os module print(http://os.name) print(os.getenv('PATH')) print(os.getcwd())
#urllib module
page = urllib.request.urlopen('http://arshinagar.in/')
for line in page:
print(str(line, encoding='utf-8'), end='')
if __name__ == "__main__":
main()
</code>

You see that in the first part of the code we have used the “sys” module and wanted to know the version of Python our system is using. The second part is all about the operating system. It gives us the name, path, and many other things. And in the last part, we are requesting a web page.

 

Let us see the output in a Linux Debian distribution like Ubuntu first. The first line is the version and the second line is about the operating system, which is “POSIX”. The third line is the environment path and the fourth line is the actual path where this file is stored.

 

From the fifth line, you see the “urllib.request” starts working in and fetches the whole index page from a website. I have used my friend’s website. I do not print out the whole HTML output, as it would take lots of space. Go through each line and see how different modules work.

<blockquote>
This is Python Version : 3.4.3
posix
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/
usr/local/games
/home/hagudu/PycharmProjects/FirstPythonProject/modules
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8 />
<meta name=viewport content="width=device-width" /> <meta name=viewport content="initial-scale=1.0" /> <meta name=HandheldFriendly content="true"/> <link rel=profile href="XFN 1.1 profile" />
<link rel=pingback href=http://www.arshinagar.in/xmlrpc.php /> <title>Arshinagar &#8211; Just another WordPress site</title>
<link rel=alternate type=application/rss+xml title="Arshinagar &raquo; Feed" href=http://www.arshinagar.in/feed/ />
<link rel=alternate type=application/rss+xml title="Arshinagar &raquo; Comments Feed" href=http://www.arshinagar.in/comments/feed/ />
//the details are removed for brevity
Process finished with exit code 0
</blockquote>
Now we can try this same code in Windows and compare the output.
<blockquote>
This is Python Version : 3.4.4
nt
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\
Microsoft SQL Server\90\Tools\binn\
D:\pthon-files-fromwindows
</blockquote>

In this output you see the Python version has been changed. The operating system is not “posix” anymore.

It is “nt” now. The environment path and the file path are also poles apart. I removed the “urllib.request” module output for concision.

 

We can see more module examples here.

<code>
#!/usr/bin/python3
import sys, os, urllib.request, random, datetime def main():
print("This is Python Version : {}.{}.{}".format(*sys.version_info))
# random module print(random.randint(1, 1000)) x = list(range(25)) print(x) random.shuffle(x)
print(x)
random.shuffle(x)
print(x)
random.shuffle(x)
print(x)
PresentTime = datetime.datetime.now() print(PresentTime)
print(PresentTime.year, PresentTime.month, PresentTime.day, PresentTime. hour, PresentTime.minute, PresentTime.second, PresentTime.microsecond)
if __name__ == "__main__":
main()
</code>

Each time you run the code, you get a new number as the “random” module always produces new numbers. To get more ideas, you need to go through the Python Standard Library in the official Python website or download the Python 3.4.4 documentation.

 

It is available in many file types, including simple text file or PDF. The “DateTime” module page in Python Standard Library in the documentation looks like this:

 

Now you can go back to your old codes and see them again in a new light. Now you will easily understand why we have used the MySQL Connector module or Configuration Parser module.

 

Debugging, Unittest Module

Debugging

Now you have progressed a lot. In the process of coding, you must have found or seen many types of errors. It is quite obvious. The seasoned programmers also make mistakes.

 

You have also learned to catch your errors. But the situation may come when you need to update your code. It might happen. You need to modify or add a few lines to your code.

 

It may either work or it may fail. In your new lines of code, there could be “syntactical” errors. There could be “runtime” errors. Usually, the Python interpreter tries to guide you in such cases. Generally, it points out where the error has occurred. But not always.

 

In such cases, the “unittest” module comes to your help.

In the Python standard library, you get a lot of information about this module. You may also search the Internet about the “nose” tool, which does something similar. The basic concept is, you have a code repository somewhere and you have a separate unit testing schedule. It is an automated test.

 

Suppose we have a folder called “MyTest/brain and soul”. Inside this folder, we have a Python file called “http://saytimedate.py”. It is a very simple file that will tell us the version of Python and the present time and date.

 

To get that output, we need two modules: “sys” and “DateTime”. We have two methods to get those outputs. To get the output, all we need to do is call them under “main()” function. We do exactly that.

 

At the same time we have two separate methods that begin with the word “test”.

The methods are “test_PyVar()” and “test_main()”.
<code>
#!/usr/bin/python3
# coding=utf-8 import sys, datetime def PyVer():
print("This is Python Version : {}.{}.{}".format(*sys.version_info)) def PyTime():
PresentTime = datetime.datetime.now() print(PresentTime)
print(PresentTime.year, PresentTime.month, PresentTime.day, PresentTime. hour, PresentTime.minute,
PresentTime.second, PresentTime.microsecond) #print(obj)
def main(): PyVer()
PyTime()
def test_Pyvar():
PyVer()
def test_Main():
PyTime()
if __name__ == "__main__":
main()
<code>
When you run this code, your main() function calls the two methods defined inside it. And the output below is what is expected.
</blockquote>
This is Python Version : 3.4.2
2016-04-22 23:30:30.435691
2016 4 22 23 30 30 435691
</blockquote>

 

Now, in a completely separate folder, we would like to run the “unittest” module and see whether this code passes or fails. Since we have already run the code and gotten a successful output, we can safely say that this code will pass the test.

The name of our unit testing code is “http://TestUnitTest.py” and the code looks like this:
<code>
#!/usr/bin/python3
# coding=utf-8
import MyProject.BrainAndSoul.saytimedate import unittest
class SayTiemDate(unittest.TestCase):
def setUP(self):
pass
def test_Version(self): self.assertEqual(MyProject.BrainAndSoul. saytimedate.PyVer(), MyProject.BrainAndSoul.saytimedate.test_Pyvar())
def test_Time(self): self.assertEqual(MyProject.BrainAndSoul. saytimedate.main(), MyProject.BrainAndSoul.saytimedate.test_Main())
if __name__ == "__main__":
unittest.main()
</code>

What does this code say? As you see, there are two methods: “test_Time()” and “test_ Version()”. We have not passed any argument. Both the methods call one default method from the “unittest” module. And that is “assertEqual()”.

 

Through this method, we have passed two methods that we have defined earlier in the “MyTest/brain and soul” folder. Inside that folder, we have a Python file called “http://saytimedate.py”. We are now comparing two methods through our “unittest” module.

 

Finally, it gives a nice output like this if everything runs properly.

<blockquote>
Testing started at 8:58 PM ...
This is Python Version : 3.4.2
This is Python Version : 3.4.2
Process finished with exit code 0
</blockquote>

 

When you run the code it looks like the following image in your “PyCharm” IDE. If we run that code again we may get an output like this:

<blockquote>
This is Python Version : 3.4.2
2016-04-23 05:47:23.608853
2016 4 23 5 47 23 608853
2016-04-23 05:47:23.608951
2016 4 23 5 47 23 608951
This is Python Version : 3.4.2
This is Python Version : 3.4.2
Ran 2 tests in 0.001s
OK
Process finished with exit code 0
</blockquote>

Now for testing purposes, we change our source code and make some mistakes intentionally to see whether our “unittest” module fails or not. If there is an error, the output will change and give an error message something like this:

<blockquote>
This is Python Version : 3.4.2
2016-04-23 05:51:45.994547
2016 4 23 5 51 45 994547
This is Python Version : 3.4.2
This is Python Version : 3.4.2
E.
ERROR: test_Time (__main__.SayTiemDate)
Traceback (most recent call last):
File "/home/ss/FirstPythonProjects/PlayWithPython-master/MyTest/ http://TestUnitTest.py", line 17, in test_Time
self.assertEqual(MyProject.BrainAndSoul.saytimedate.main(), MyProject. BrainAndSoul.saytimedate.test_Main())
File "/home/ss/FirstPythonProjects/MyProject/BrainAndSoul/saytimedate.py", line 20, in main
PyTime()
File "/home/ss/FirstPythonProjects/MyProject/BrainAndSoul/saytimedate.py", line 15, in PyTime
print(obj)
NameError: name 'obj' is not defined
Ran 2 tests in 0.001s
FAILED (errors=1)
Process finished with exit code 1
</blockquote>

Now you can try to run more unit testing modules. Here is another example where the test is successful.

 

Socket and Networking

Networking

This blog is kind of an introduction to the advanced concepts of Python. Since this is the final blog, I would like to tell you about where you can go from here. You can either build web applications with the help of Python or you can do some security networking stuff.

 

Finally, like me, you can choose the interesting path of ethical hacking. All these things and more you can do through Python.

 

Let us see how we can apply our basic knowledge of Python in socket and networking. Write down this code on your IDE and see what output you get.

<code>

# coding=utf-8 import socket print(socket.gethostbyname("Sanjib Sinha")) print(socket.gethostbyname("http://www.sanjib.pythonanywhere.com"))

</code>

 

The output is like this in my machine. You can test any other website to get its address. This is the tip of the iceberg. Lots of things are inside. It is better for you to see everything that is inside than for me to tell you, as I feel you should concentrate on trying to write basic concepts of Python more and more.

<blockquote>
192.0.78.12
50.19.109.98
Process finished with exit code 0
</blockquote>

 

In the further study of the relationship between ethical hacking and Python 3, you’ll find these socket and networking concepts extremely useful. Let us move further to Part Three of the blog, where we’ll learn about anonymity.

An ethical hacker should always remain anonymous. Why? Let us see.

 

Importing Nmap Module

Nmap (Network Mapper) is a security scanner. It was originally written by Gordon Lyon (also known by his pseudonym Fyodor Vaskovich). This tool is particularly used to discover hosts and services on a computer network.

 

While finding the hosts and services it creates a “map” of the network. For this reason, it has been widely called ‘Nmap’ or you can also call it ‘Network Mapper’. It is regarded as an essential tool in your pursuit to be a good and competent ethical hacker.

 

To get the best results, Nmap usually sends specially crafted packets to the target host and then analyzes the responses and finds what ports are open. It also assesses the vulnerability of a computer network. 

 

This software widely used by hackers has a number of features. It actually probes computer networks, discovering hosts and services. It also detects the operating system and it decides the vulnerability of the systems by finding the open ports.

 

Python actually extends these features so that you can easily do more advanced service detection, vulnerability detection, and other things. Let us first check whether ‘Nmap’ module of python has already been installed in our system or not by issuing a simple command on the terminal. nmap

 

It gives us a long listing which is very important. Many things you can learn from this listing as it says about the version, usages and at the end, it also says where you can get the manual for more reading.

Nmap 6.40 ( Nmap: the Network Mapper )

Usage: nmap [Scan Type(s)] [Options] {target specification}

 

TARGET SPECIFICATION:

Can pass hostnames, IP addresses, networks, etc.
Ex: Go ahead and ScanMe!, http://microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254
-iL <inputfilename>: Input from list of hosts/networks
-iR <num hosts>: Choose random targets
--exclude <host1[,host2][,host3],...>: Exclude hosts/networks
--excludefile <exclude_file>: Exclude list from file

HOST DISCOVERY:

-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers <serv1[,serv2],...>: Specify custom DNS servers
--system-dns: Use OS's DNS resolver
--traceroute: Trace hop path to each host

 

SCAN TECHNIQUES:

-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
-sU: UDP Scan
-sN/sF/sX: TCP Null, FIN, and Xmas scans
--scanflags <flags>: Customize TCP scan flags
-sI <zombie host[:probeport]>: Idle scan
-sY/sZ: SCTP INIT/COOKIE-ECHO scans
-sO: IP protocol scan
-b <FTP relay host>: FTP bounce scan

 

PORT SPECIFICATION AND SCAN ORDER:

-p <port ranges>: Only scan specified ports
Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
-F: Fast mode - Scan fewer ports than the default scan
-r: Scan ports consecutively - don't randomize
--top-ports <number>: Scan <number> most common ports
--port-ratio <ratio>: Scan ports more common than <ratio>

 

SERVICE/VERSION DETECTION:

-sV: Probe open ports to determine service/version info
--version-intensity <level>: Set from 0 (light) to 9 (try all probes)
--version-light: Limit to most likely probes (intensity 2)
--version-all: Try every single probe (intensity 9)
--version-trace: Show detailed version scan activity (for debugging)

SCRIPT SCAN:

-sC: equivalent to --script=default
--script=<Lua scripts>: <Lua scripts> is a comma separated list of directories, script-files or script-categories
--script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
--script-args-file=filename: provide NSE script args in a file
--script-trace: Show all data sent and received
--script-updatedb: Update the script database.
--script-help=<Lua scripts>: Show help about scripts.
<Lua scripts> is a comma separted list of script-files or script-categories.

 

OS DETECTION:

-O: Enable OS detection

--osscan-limit: Limit OS detection to promising targets

--osscan-guess: Guess OS more aggressively

 

TIMING AND PERFORMANCE:

Options which take <time> are in seconds, or append 'ms' (milliseconds),
's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).
-T<0-5>: Set timing template (higher is faster)
--min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
--min-parallelism/max-parallelism <numprobes>: Probe parallelization
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies probe round trip time.
--max-retries <tries>: Caps number of port scan probe retransmissions.
--host-timeout <time>: Give up on target after this long
--scan-delay/--max-scan-delay <time>: Adjust delay between probes
--min-rate <number>: Send packets no slower than <number> per second
--max-rate <number>: Send packets no faster than <number> per second

 

FIREWALL/IDS EVASION AND SPOOFING:

-f; --mtu <val>: fragment packets (optionally w/given MTU)
-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
-S <IP_Address>: Spoof source address
-e <iface>: Use specified interface
-g/--source-port <portnum>: Use given port number
--data-length <num>: Append random data to sent packets
--ip-options <options>: Send packets with specified ip options
--ttl <val>: Set IP time-to-live field
--spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
--badsum: Send packets with a bogus TCP/UDP/SCTP checksum

 

MISC:

-6: Enable IPv6 scanning
-A: Enable OS detection, version detection, script scanning, and traceroute
--datadir <dirname>: Specify custom Nmap data file location
--send-eth/--send-ip: Send using raw ethernet frames or IP packets
--privileged: Assume that the user is fully privileged
--unprivileged: Assume the user lacks raw socket privileges
-V: Print version number
-h: Print this help summary page.

 

EXAMPLES:

nmap -v -A Go ahead and ScanMe!
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80

 

SEE THE MAN PAGE FOR MORE OPTIONS AND EXAMPLES

You can get more about Network Mapper on the internet. Please follow these links.

 

Nmap: the Network Mapper

Other Platforms (BSD, Solaris, AIX, AmigaOS) Nmap Network Scanning

If in your ‘Linux’ version of default operating system you don’t get this listing you can install ‘Nmap’ by issuing a simple command. sudo apt-get install map

 

In your virtual machine, if you run Kali Linux, you’ll find that ‘Nmap’ has already been installed. Now after this installation part is over we can very quickly have a short python script to see how our ‘Nmap’ module is working.

 

 You’ve already learned how to use ‘nano’ text editor on your terminal. So open it up with this command: sudo nano http://test.py

 

It will first ask for your root password and then open up the nano text editor on your terminal. Write a short script like this:

#!/usr/bin/python
import nmap
nm = nmap.PortScannerAsync()
def callback_result(host, scan_result):
print ('------------------')
print (host, scan_result)
nm.scan('127.0.0.1', arguments="-O -v", callback=callback_result)
while nm.still_scanning():
print("Waiting ")
nm.wait(2)
nm1 = nmap.PortScanner()
a = nm1.nmap_version()
print (a)
If you run your ‘http://test.py’ script, you’d get this output:
Waiting
------------------
('127.0.0.1', None)
(6, 40)

It’s your localhost address. But we are interested in the remote target. Run up the Kali Linux in your Virtual Box and open the ‘Tor’ browser. Search ‘what is my IP address’. It will give you an anonymous IP address all the time. Each time you search that IP address changes.

In your case, it may come out as x.x.xx.xxx ISP: Some Internet LTD

 

It’s usually too far from your original location! Anyway, you can test the IP and see the result. But it’s a good practice to test the IP of Nmap: the Network Mapper

Recommend