Python

Best way to learn Python

In this article, we’ll talk about the most efficient way to learn Python. Of course, this article will be really subjective, as it is only based on my personal experience.

I’ve started learning Python from it’s 3.4 version. I’ve never actually worked with previous versions, although I coded a little bit just to satisfy my curiosity. Still, the difficulty of every subject here is based on my experience with Python 3.4, the results may vary if you work with other versions.

Python is a high-level, object oriented, interpreted programming language. It was created by Guido van Rossum, and its source code is available under the GNU General Public License.

It’s a great language for the beginner-level programmers and supports the development of a wide range of applications from simple text processing to big web applications and even games.

This language has a lot of awesome features:

  • It’s easy to learn, as there are few keywords and it has a simple structure and a clearly defined syntax.
  • It’s easy to read, as Python code is more clearly defined and visible to the eyes.
  • Its code is fairly easy to maintain.
  • It has a broad standard library that is very portable and cross-platform compatible with UNIX, Windows and Macintosh.
  • It has an interactive mode which allows interactive testing and debugging of snippets of code.
  • It can run on a wide variety of hardware platforms and has the same interface on all platforms.
  • You can add low-level modules to the Python interpreter. These modules enable programmers to add to or customize their tools to be more efficient.
  • Python provides interfaces to all major commercial databases.
  • Python supports GUI applications that can be created and ported to many system calls, libraries and windows systems, such as Windows MFC, Macintosh, and the X Window system of Unix.
  • Python provides a better structure and support for large programs than shell scripting.

Also, it supports functional programming, which is a huge plus for me at least, and it can be used as a scripting language or be compiled to build big applications too.

It provides high-level dynamic data types and supports dynamic type checking. It also supports automatic garbage collection.

1. Environment Set Up

First of all, we’ll talk a little bit about how to set up your development environment. I am currently working in a Linux Mint 17.2, which is basically an Ubuntu 14.04. On this platform, I just run sudo apt-get install python3 and, at the time this article was written, this will install Python 3.4.3. Other ways to install Python, and support for other platforms can be found at https://www.python.org/.

If the set up is right, if you open a console and run python3 you should see something like this:

$ 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.
>>>

This is the Python REPL (read–eval–print loop). This is an interactive language shell. You can write Python code there and execute it. Let’s see:

$ 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.
>>> print("hello world!")
hello world!
>>> for i in range(10):
...   print(i)
...
0
1
2
3
4
5
6
7
8
9
>>>

2. An Extensive Introduction

If you don’t know anything about programming, codecademy has a great course about Python, which will show you the basics, both about the language and about programming.

Now, what I’d do first, If I am new to the language, but I know at least a little bit about programming, is to find a more extensive introduction to Python. I wrote what I think is an extensive, but concise example of Python here. In that example you’ll find:

  • An introduction to the language, which gives an overview about it’s implementations, it’s purposes, it’s pros and some cons.
  • An introduction to the code, and the available ways there are to execute scripts.
  • An overview of variables, primitive types (str, bool, int, float, long, complex), operators and data structures, with some examples and good practices which will give you an idea of how to work with data in Python.
  • An extensive explanation of flow control structures, where the example actually starts to get interesting with a decimal to binary numbers translator and an example of how to read and write data to a file.
  • A good introduction to functions, which is basically the core of Python. This section will talk about some awesome features Python’s functions provide, and some “gotchas” you should keep in mind.
  • A talk about classes, which is the core of object oriented programming.
  • And at last, a good, complete example which will make use of most of the subjects it talks about.

After you read that example you will be able to do some really awesome stuff, like:

fibonacci.py

_cache = {
    0: 0,
    1: 1
}

def fibonacci(i):
    if i < 0:
        return None
    if i not in _cache:
        _cache[i] = fibonacci(i - 1) + fibonacci(i - 2)
    return _cache[i]

There we defined a function that given an integer, it returns the number present in that position of the fibonacci sequence. We know the fibonacci sequence goes like (0, 1, 1, 2, 3, 5, 8, …) so if you ask for the number in the position 6 (having in mind that the first position is zero) it would return an 8.

The algorithm is so simple and yet so beautiful. We first defined a dictionary which we’ll use as cache (that’s why it’s called _cache), with a couple default values, and then a function that receives an argument i, which first checks if i is not a key in our cache, if it is it returns the content in our cache, if it isn’t, it does a recursive call to get the two numbers in the sequence before the one that is being asked for and adds them.

And, of course, you also have the knowledge to do that example with a non recursive solution, like this:

fibonacci.py

def fibonacci2(i):
    second_last = 0
    last = 1
    for index in range(2, i + 1):
        aux = second_last + last
        second_last = last
        last = aux
    return last

If you are already familiar with these subjects, and you are looking to deepen your knowledge about the language, you should skip to the next steps.

If not, you should read that example, and complement it with some research. Stack Overflow is a question and answer site for professional and enthusiast programmers, here you can find some explanation about the concepts you are not familiar with. For example if you want to know what a variable is, in Stack Overflow’s search box you type what is a variable? and one of the answers in the result will be this one. If the responses are too technical or advanced, you can try other similar questions and maybe even read as many answers as you can until you actually understand what they mean.

At this point, I would also create a profile in GitHub and read about git, which is a version control system. You can use git to save your code (projects, exercises, etc.) and it will also provide a history of changes and some really useful stuff. Having a GitHub account will let you share your code with friends and colleagues and they may even be able to help you or guide you when you are blocked out or anything. A facebook post is not the best way to share code.

Of course, there are alternatives to GitHub, for private repositories, for example, GitLab would be my first choice, althoug some people prefer Bitbucket (I’ve never actually used it, but people say it’s awesome).

3. Some Functions

At this point you should have some strong basis of the language, so you should work on those functions to know how to work with them properly, as they are a really powerful tool and the core of Python. In essence, functions are procedures that return a value based on some given arguments. In Python, functions are first-class objects. This means that functions can be assigned to a variable, they can be defined inside another functions, they can be passed as parameters (higher-order functions), and they can return other functions (also, higher-order functions).

I’ve actually learnt a lot about Python at tutorials point, and here you can find a basic but great example about functions. Most tutorials at tutorials point are based on Python 2.7, but most of the knowledge you’ll get there can be applied to more recent versions of Python, and of course, tutorials about conversions can be found almost everywhere.

My Python Decorators Tutorial will show you how powerful functions are in Python, and how you can extend their behavior without actually modifying them. Before it jumps into decorators, it will explain functions in a more detailed way. It will also explain how and why functions are first-class objects in Python, which is the main reason they are awesome.

Another useful example to practice with functions is this example about the built-in function map, which is a really useful built-in function to transform iterable objects. Strictly speaking, a map function, is a function that accepts a function and an array as arguments, and applies the given function to each element of the array, returning another array with the result of each transformation. So, in other words, a map applies a transformation to each element of an array and returns the results.

Now we have a strong knowledge about functions, we can solve more complex problem. For example, if we wanted to write a function that returns the lowest common multiple of n numbers, where n is not a fixed integer, we could do something like this:

lcm.py

from functools import reduce

def greatest_common_divisor(a, b):
    if b == 0:
        return a
    return greatest_common_divisor(b, a % b)

def _lowest_common_multiple(a, b):
    return a * b // greatest_common_divisor(a, b)

def lowest_common_multiple(*args):
    return reduce(_lowest_common_multiple, args)

Here we are using reduce from functools (if you are not familiar with this function wikipedia has a good explanation about it) to combine de results of applying _lowest_common_multiple to the arguments received. That _lowest_common_multiple function, receives 2 arguments, and as you see it calls greatest_common_divisor to divide a * b, and greatest_common_divisor is a recursive function which uses the Euclidean algorithm to return the greatest common divisor.

So, with this utility we can do things like:

lowest_common_multiple(6, 1, 6) # 6
lowest_common_multiple(2, 4, 6) # 12
lowest_common_multiple(10, 8) # 40
lowest_common_multiple(5, 9, 3, 7) # 315

4. Data Structures

Now we know functions, I would strongly recommend to deepen your knowledge of data structures, although in the example given at the beginning of this article they are pretty well explained. The most used data structures in Python are lists and dictionaries, read my Python Dictionary Example, which explains in detail how to define a dictionary, the best way to read from it, how to write data to it and some useful built-in functions and keywords.

Also, an example about a not so used data structure will come in handy, as it explains how arrays in Python work just as lists do. It will show you something actually new, but that is very familiar to you at this point. Also, the practice is never enough.

At codility you can find some really fun and awesome exercises to practice your functions, data structures, programming skills and algorithm knowledge. Keep in mind that some of the tasks are actually pretty hard, so you may take a while to solve them. If you actually have no idea of what to do there, you should practice more, maybe read about a couple subjects and then try again.

There are a lot of exercises in codility where we can train our skills with arrays and dictionaries, but I will talk about three here.

The first one is Odd Ocurrences in Array. The problem says something like:

A non-empty zero-indexed array A consisting of N integers is given. The array contains an odd number of elements, and each element of the array can be paired with another element that has the same value, except for one element that is left unpaired. Write a function that, given an array A consisting of N integers fulfilling the above conditions, returns the value of the unpaired element.

I’m sure there are more than one ways to solve this problem, but the one solution I came up with was this one:

codiliti.py

def solution(array):
    my_dict = {}
    for i in array:
        my_dict[i] = my_dict.get(i, 0) + 1
    for key, value in my_dict.items():
        if value % 2 > 0:
            return key
    return None

Codility does not test our validation skills, so the last statement, the one that says return None will never execute. As you may know at this point, dictionaries are indexed, so they are a good option when you want to check some data that you will infer from iterating over an array without adding time complexity to your solution. And that’s what I did, I iterate over the array, and increase a counter for every number I find in the array, at last I iterate over the dictionary and return the number that appeared an odd number of times.

In this solution I’m abusing of the get and items methods that dictionaries provide, and the fact that they are indexed.

The second problem, Tape Equilibrium, says something like this:

A non-empty zero-indexed array A consisting of N integers is given. Array A represents numbers on a tape. Any integer P, such that 0 < P < N, splits this tape into two non-empty parts: A[0], A[1], …, A[P − 1] and A[P], A[P + 1], …, A[N − 1]. The difference between the two parts is the value of: |(A[0] + A[1] + … + A[P − 1]) − (A[P] + A[P + 1] + … + A[N − 1])|.

In other words, it is the absolute difference between the sum of the first part and the sum of the second part. Write a function that, given a non-empty zero-indexed array A of N integers, returns the minimal difference that can be achieved.

Again, I’m sure there is more than one solution, but I came out with this one:

codiliti.py

def solution(array):
    first_part = array[0]
    second_part = sum(array[1:])
    min_absolute_difference = abs(first_part - second_part)
    for i in range(1, len(array) - 1):
        first_part += array[i]
        second_part -= array[i]
        new_absolute_difference = abs(first_part - second_part)
        if new_absolute_difference < min_absolute_difference:
            min_absolute_difference = new_absolute_difference
    return min_absolute_difference

I create my first and second parts of the tape. The first one is only the head of the array, the second one is the sum of the tail. Then I iterate over the array, until the element before the last one, and subtract from the second part and add to the first part. I have a variable called min_absolute_difference which is updated every time I find a difference smaller than the actual value and after I iterate over the whole array, I return it. As you see, I’m exploiting the capabilities of slicing arrays and a couple built-in functions.

The third and last exercise I’ll talk about is Missing Integer, and it says something like:

Write a function that, given a non-empty zero-indexed array A of N integers, returns the minimal positive integer (greater than 0) that does not occur in A.

I solved this problem using an algorithm that uses dictionaries like in the first exercise:

codiliti.py

def solution(array):
    my_dict = {}
    max = 0
    for i in array:
        my_dict[i] = True
        if i > max:
            max = i
    for i in range(1, len(array) + 1):
        if not my_dict.get(i):
            return i
    return max + 1

As you see, I am using the dictionary as a buffer to store the values I’ve already found in the array, and by the way I register the maximum value present in the array in question. Then, I iterate over a range from 1 to the length of the array plus one, and return the first number in that range that is not a key in my dictionary. If none of those elements is absent in the dictionary, then I return the maximum value of the array plus one. Here I’m only using dictionaries because they are indexed.

5. Object Oriented

At this point, you would actually be capable of writing a really interesting program, but if it gets too big, maybe classes would be a nice way to make your program more modular. Of course, you can always solve that problem with modules, but still, a deep knowledge of classes will come handy.

Read this article about classes, it explains how easy it is to write a class in Python, how an instance of a class is an object but in Python a class is also an object, which let’s you do some real fun stuff. It will talk about inheritance, and best practices and standards that the community defined to tell users of you API that some members are not meant to be accessed from outside (private members).

Also, this article about object oriented programming, is a more advanced tutorial about classes and objects in Python, if you read mine before, you could skip a couple sections and stop where you see something that doesn’t ring a bell.

At this section, you can find some good exercises for beginners and even for advanced programmers. Some of them where actually written for Java, but you can solve them in Python, the result should finally work the same. Of course, to actually become good at anything, you should put it in practice for real. Maybe you should start a project at this point. An application that solves some kind of problem that you don’t want to do it manually.

I, for example, when I learnt scala, made an application that took care of my accounts. I input how much money I make, how much I spend, in what, and it does some calculations that I don’t want to do and tells me how much money I can save, how much I should be able to save, when will I run out of cash, and some other useful information.

With classes in hand, you can start doing some really interesting stuff. You can, by example, start working with threads. A really extensive example about threading and concurrency can be found here. This threading tutorial will give you an overview of the deprecated _thread module, which is no longer used after Python 2.4. Then it will walk you through the newer threading module.

You’ll see how to extend a thread, how to get thread’s information, what is and how can you create a daemon thread, how to join threads and some concurrency utilities, like events, locking, limiting concurrent access, and thread locals. Threads are processes which run in parallel to other threads. In a utopian scenario, if you split a big process in 2 threads, these threads will run in parallel so it would take half the time.

IBM also provides a really detailed example about threading with Python here, it may bee a little too advanced, but if you got this far I’m sure you can get pass this article.

With this knowledge about functions, objects and threads in hand, there is a lot of things we can do now some more interesting things, like asynchronous programming. Let’s see:

asynch.py

from threading import Thread
from time import sleep
from types import FunctionType

import datetime


def asynchronous_task(callback: FunctionType):
    sleep(3)
    callback()

start_time = datetime.datetime.now()
t1 = Thread(target=asynchronous_task, args=[lambda: print("first task is done")])
t2 = Thread(target=asynchronous_task, args=[lambda: print("second task is done")])

t1.start()
t2.start()

t1.join()
t2.join()

end_time = datetime.datetime.now()
print("job done in {}".format(end_time - start_time))

You have 2 threads here, which are executing tasks in parallel, we can say they are asynchronous as they receive callbacks so we can run them, tell them what to do when they finish and continue with our execution on the main thread. When we run the script we’ll see:

second task is done
first task is done
job done in 0:00:03.003682

As you see, the script is taking a little more than 3 seconds to run, which proves these tasks are being run in parallel as they are both sleeping for three seconds.

Once you get the hang of threads, you can learn the basics of sockets with this tutorial, which will explain in detail sockets, it’s perks and best practices. Sockets are behind any kind of network communications done by your computer.

We all know that, when you type a url in your browser, it’s connecting to a server somewhere in the world which receives a request, returns a response and then the connection is closed. All of this is made through sockets, always. It doesn’t matter if your are communicating through HTTP, UDP or whatever, there is a socket behind every one of those protocols.

Once you read this article you should jump into network programming and learn how to write a p2p messenger and a simple chat room.

Then, as you are getting into big applications, I would recommend reading this article about logging, which is necessary, as print is not the best option to show information about your program. When you have an application that it is not you the one that uses it, most of the time you’ll need something that tells you what the application is doing, how, how long does it take it, if it fails and if it does why. The logging module provides a pretty straight forward solution to this problem, and you will find that it is quite easy to make your application log.

After you’ve done all of this, you will find it very easy to integrate with a big web framework as Django, and you can use this article as a cheat sheet. The article will walk you through the basics of this complete web framework, and with a little more research in Django’s docs you will be able to build your first full, productive web application with Python. Django is an open source web framework which solves most common problems of a web application development.

It has some very useful features like an auto generated admin page and an ORM. It’s a high-level framework, so we just need to focus on the actual core logic of our business and let Django take care of mappings, filters and such. It works by defining some standards that, if you follow them, will make the application’s development so much easier and faster.

A good alternative, more lightweight but also minimal, to Django is Flask, I found out that Flask is easy to setup, runs fine. Here you can find a benchmark that compares some response times of a lot of Python frameworks in some interesting scenarios. You’ll find that Django and Flask behave almost the same, even Flask wins in a couple scenarios.

6. Getting Serious

Now, if you’ve got this far, you are probably starting to think about writing a big project, like a product, that you may be able to sell or at least make popular. You might be thinking about looking for a job to use these new skills. You would recommend having Python’s docs in speed dial, get the hang of Stack Overflow and prepare yourself to learn a lot. Every project, every new project you face, has something new to teach you.

If it’s big you may learn how important it is to make modular and testable code. If it gets really popular you will learn about concurrency and performance. If it’s open source you will learn about reading someone else’s code, and writing code that is readable by anyone (this one is REALLY important) (that’s my first bold text in this article, that’s how important readable code is).

A good activity to get really fluent with a language is to see some GitHub projects written in it and try to understand what they are doing and how are they doing it. Maybe, if it’s an open source project, you could contribute to it, an example of a contribution of mine is this pull request I made for a web socket client which didn’t have support for Scala 2.11, so I implemented it as I was learning Scala myself, the issue is this one. The process can be pretty long, it gets worse if you and the owner of the project are in different timezones, but once it gets done it is really awesome to see people use a tool you contributed to.

I think at this point I have no more guidance to give. Keep in mind that by doing you learn. The more you read, the more prepared you are to face new problems, so sit down, open google and start researching. The most stupid idea, the most stupid problem you can think of, I can guarantee that if you write a program that solves it, you will learn something new from it.

Spend time updating you knowledge, join a programming community, if you are from Argentina, for example, there is PyAr, which is a pretty big, nerd, awesome community.

A programming community has a lot to give you, you will know whenever a new update is coming, a new big useful framework/library gets released, a good convention is near and more. It will help you keep updated and interested, you will be able to socialize with awesome, really smart and experienced people, and even help newbies (it sounds like an insult, but I don’t see it that way) get to speed. You should never underestimate a community.

7. Conclusion

Python is, in my humble opinion, the perfect language for the beginners level of programmers. If I had to tell someone which language should he/she use to learn programming from scratch, I would automatically say “Python!”. Also, it really is powerful, you can write web applications that will perform just as good as in any other language, you just have to keep in mind the existence of the GIL and try not to do long blocking operations inside it, which is not a difficult task once you get the hang of the language.

So, that’s it. Python is one of my favourite languages, it’s actually my second favourite. I have a lot of fun coding with it, I think it’s really versatile and powerful. I hope you have fun with it too. Thanks for reading!

Sebastian Vinci

Sebastian is a full stack programmer, who has strong experience in Java and Scala enterprise web applications. He is currently studying Computers Science in UBA (University of Buenos Aires) and working a full time job at a .com company as a Semi-Senior developer, involving architectural design, implementation and monitoring. He also worked in automating processes (such as data base backups, building, deploying and monitoring applications).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Herbert Dupree II
7 years ago

I am new to Python and use Windows 10. From the syntax shown, it reminds me of BASIC and Visual Basic (not .NET version). Am i on target to equate Python to a modern version of Visual Basic? VB.Net is closer to C# because of common language interests by Microsoft. Thanks

Sebastián Vinci
Sebastián Vinci
7 years ago

I’m not familiar at all with VB, as I only worked with it for one year on high school, I don’t remember much of it. As far as I know, Python was inspired by ABC Language and SETL and grabbed some functional programming features from List, Haskell and Standard ML. There are other languages in that influence list which you can check at Wikipedia (https://en.wikipedia.org/wiki/Python_(programming_language)#History). If any of those languages look like VB, then Python will probably do so. Sorry if I can’t be of any more help.

Herbert Dupree
7 years ago

After re-reading the article on Python from WikiPedia, there seems to be an indirect correlations with Visual Basic, even though the article doesn’t make that point. ABC, which is the starting point for Python, is a competitive version of BASIC, the predecessors to Visual Basic (again not the .NET version as that is a lot closer to the C branch of languages). I think it’s time for another class on the subject.

Edgar
Edgar
7 years ago

Good post! Only a couple of suggestions, the term “primitive types” could be confused because everything is an object.
Also, could be useful mentioning the differences between concurrent and parallel processing.
In the asynch.py script the argument says “callback: FunctionType”.
Thank you!

Back to top button