|Jens Chickpea Pancakes
||Learning Python Part II
Learning Python Part I
It is late in de evening on June 30, and I am just about to start a new adventure. I will teach myself Python. It is not that dramatic since I learned many programming languages over the years, so this is nothing special. Nevertheless, I will document my first steps into this journey in this blog. For this topic, I will have different blog-format. I will blog several days in the same blog post. I call it “day” here below, but it is more of half an hour or an hour each time.
Day 1. June 30, 2019. Downloading Phyton for Windows.
Deciding on what Phyton to learn is not that easy. There is version 2 and version 3 of Python. I understand that many people are using version 2. I will try to go with version 3 because it sounds like it is the latest version. It can be that this decision will haunt me, but that will do. I will have to deal with that then.
Downloading the language took 3 seconds!
While installation is running, and that took a long time, I started wondering if GIMP is using 2 or 3? Before I found an answer to this question, the installation had finished. That took about 4 minutes.
The installation pointed me to an online tutorial. How nice! I started reading it, and it turns out that the name of the language comes from the British BBC show Monte Pythons Flying Circus. I vaguely remember seeing this as a kid, so I have another to-do task on my list, to watch MPFC episodes again. Back at the time, there were many jokes I could not comprehend from the show. I am not native English speaking. I was taught English at school, and I was not at the language level that I could appreciate jokes in a foreign language when I was at that age.
The Python installer is asking if it should disable the path length limit. That is cool. Yes, please do. With that, MAX_PATH is set beyond 260 characters limit.
After installation of the Python programming language, I still had the tutorial web page open. Just for the sake of it, I bookmarked it, and then without reading any more, I tried pressing Windows + R and then CMD + Enter, and there I write python and hits Enter.
It is alive.
Day 2, July 1, 2019
Started reading chapter 3 of the introduction. I notice that strings are immutable. That makes me think of XSL. Lists, on the other hand, are mutable. It is possible to modify items of a list. At that same moment, when I thought that it would be cool to make the Fibonacci series function, the tutorial had an example of the Fibonacci series.
So this is interesting. It is possible to multi assign variables. Ok. That worked fine. Then I entered the while loop on the next line. As long as a is less than 100, it would print values. Then I hit enter and got an error message. Cool! The body of the while loop is indented. I am not used to that. Perhaps there will be some begin/end later on when getting to the real stuff?
Then I tried to continue to enter lines as if I had not noticed, but then I started wondering if it had forgotten about the variable a so I tried to print a, and it produced a result. At that time, I had not figured out that the body had to be indented. I am still wondering if this is a thing.
Since I did not yet know about indentation, I tried using semicolons to separate commands. That looked like it was working.
Okay, the values are still active, so when I enter a new while loop, it started from the previous a value. That stuff with end has to sink in another time.
Ok fine, I started experimenting. First I initialized a and b both to 0. That failed because 0 plus 0 stays zero.
Then I thought I entered the example, but I turned the print and the assignment lines around. The result was that the assignment took place first, and then it was printed. With that, I overshot the maximum of 1000. When turning the print and the assignment around it stopped right after 987 because then it was over 1000 and it stopped.
Then it was time for chapter 4. The for-statements looked similar to Perl. You always operate on lists. It is stricter than Perl. Alright. Then printing items in a list with indices is done like so:
Huh? Loop statements may have an else clause. Now I need to have a break from this…
Day 3, July 3, 2019. My birthday!
Last time it ended in a bit of confusion. I have to reread that with loop statements having else clauses. The else-statement of a for-loop is executed if the loop was exhausted. So I continue with chapter 4.
Now we are done with the warming up. Next hurdle was the function definitions. At this point in the documentation, there was nothing said about anonymous functions. Perhaps they show up later if lambda calculus possible in Phyton. So, for now, a function has a name. Arguments are sent by reference to the function. The position of the argument list is significant. It is possible to have default value arguments so that if not needed, they are initialized with the default value, evaluated only once.
It is possible to supply arguments as key-value pairs. It is called keyword arguments. Keyword arguments may only be the last in the argument list, and then the position is irrelevant.
Day 4, July 5, 2019. Continuing with Phyton after birthday party.
- A function may receive a simple argument. That is specified as an identifier in the function specification. Fine.
- Then it can receive a list of items. That is specified as an identifier preceded by an asterisk. The items may be separated by a comma in the function call, but in the function itself, the list is stored in the variable preceded by an asterisk. In other languages, you would have something like curly brackets to indicate that here starts a list of something. This was difficult to understand because it is explained in the next section. We will see.
- The function can receive a list of key-value pairs forming a dictionary. So you call the function with key-value pairs separated with commas, and they are magically collected in the function. Nice.
Of course, when using a starred argument, it works as a variable-length argument list to a function.
Next up was unpacking argument lists. I do not understand it.
First, we produce a list from a range from 3 to but not including 6. That is fine.
Then we define a list with the items 3 and 6 and call this args. Then we produce a list from a range, but the range is taken by unpacking the items in args and sending them to the range function as two separate arguments. Ooh ok. I can grasp that. So now we have two uses of a star? Or is this the same use? So a star in front of an identifier lumps together things. A function can receive such lump, or you can send such a lump to a function. Is that it?
Next up Lambda expressions. Small anonymous functions. I wonder why they have to say that the functions are small?
The first example shows how a regular function generates a lambda function as a result. So the regular function takes an argument and returns a lambda function that adds the argument of the regular function to an argument of the lambda. So when the regular function is called with say 42 as an argument, the result is a function that adds 42 to what you like. So then calling the result with 1 adds 42 so the result is 43. Cool.
The first line of functions is a documentation string. This is patronizing.
Then it was time for coding style. Point one, yuck. I am not allowed to use tabs??? I have a tabbed personality. This is odd. Anyhow, let us see how this progress.
It is time for chapter 5, data structures.
List comprehensions are interesting. It is possible to define a list using square brackets, but the list is defined with a for-statement and possibly ending with an if statement. They also show how to do it with a lambda function.
This is advanced stuff. There are a couple of constructions we barely learned:
For example range(4) produces a list of elements [0, 1, 2, 3]. So for i in range(4) makes i loop over these elements one by one. For each turn that i is getting a value from 0 to 3, it is used in an inner list comprehension. In that inner comprehension, a list is created based on picking out element i from each row of the matrix. And the result is that the matrix is transposed. That is clever and very elegant.
And when finished, they present an even shorter and efficient way to transpose matrixes: list(zip(*matrix)).
Then I was reading about tuples. Empty tuples are written with an open and closing parenthesis. A tuple with one element is written with one element followed by a comma and then nothing more. That is odd!?
There is also a set datatype. The creators of the language saved the curly bracket for sets. It is possible to do set algebra as well. That is cool.
Then they talked about dictionaries and for dictionaries they use curly brackets as well. This is fine because all items in the dictionary have key-value pairs., It is also possible to create a dictionary from a list of tuples sent to a dictionary constructor. This can also be used with list comprehensions.
This was how far I reached my Phyton quota for today.
Day 4, July 6 of 2019.
The tutorial went on describing the comparison of sequences giving me the same feeling, as described here above. Will I learn to appreciate it or will I deal with it as if it did not exist?
Then it was time for modules. I read this “cursively.” It is not so that I skipped it, but it is stuff you need to know about, and later I will need to look up specific things of this. It is possible to import modules in different ways. It is possible to execute a module as a script, cool. Will look up that if I need it. There is a form of compilation taking place so that it makes it possible to load modules quicker, from a cache. It is possible to load directly from the cache without the source document. Modules can be organized in packages.
There is a bit of yadda yadda here. I will go back and dive more into that when I got dirty hands.
Chapter 7. Input and Output. It is possible to refer to variables via place holders in strings, via a short form notation. The placeholders got the variable names in curly brackets, and that is how to refer to the literal values.
Day 5, July 8 of 2019.
My printer, a Canon ip4500, is broken. I used several hours on trying to get the printer head to come alive again, but this has failed. I am giving up on that. In the process, I lost some time on Phyton. Now I have 20 minutes before heading to bed. But hey ho, here we go.
Formatting strings are all exciting, but I am used to many of the concepts from my knowledge of other languages. I think I read this cursively and go on with 7.2 reading and writing files.
Here they introduce a command with so that with open(…) when done for whatever reason, including error condition, the file is closed.
It is funny because try-finally blocks are introduced as a side note here. The with statement is shorter than try-finally blocks. So that means there exist try-finally blocks, that is nice to know. I click the “try”-link, and it sends me back to chapter 6, but I find nothing explicit about try blocks here. When I click the finally link it sends me forward in the tutorial to chapter 8 about the try statement. I will not read about that just yet. I go back to files. This when I thought I try the with statement link and it also points me to the future.
Python knows JSON!!! That is interesting. It knows JSON so well it can serialize and deserialize to and from JSON. That is clever. Oh, lists and dictionaries can be serialized. Arbitrary classes require a bit of extra effort. Then they have more serialization methods as well: pickle. I just try to remember this and I will come back to this if I need it.
Next chapter! Error and Exceptions. Nope. I head for bed.
Day 6, July 9 of 2019.
It had a slow start on this evening. Started by trying to get the printer alive but it is dead. I have to realize that it is dead.
So now I am starting to read about errors and exceptions, chapter 8. The syntax of the error handling is very similar to how it is done in other languages, for example, c#. There is a “try,” and it defined a block and in the case of Phyton, defining a block is done with indentation. The block ends with an except-statement that defines the type of error that the except will trigger. It is possible to have several different types of triggering the same handler, as a comma-separated list. It is also possible to have different handles for different types by adding more except statements after each other.
Day 7, July 10 of 2019.
It is tempting trying a couple of rounds cleaning the dead printer, but I will not do that. Dead is dead. Instead, it is time to continue on the subject of try … except in Phyton. I wonder where the error object is defined? In C# you either define an error object to be instantiated at the catch. When doing so, it is possible to get all sorts of additional data out of the exception object in the error handler. How is this working here?
It is the same here. Cool.
In C#, you “throw,” here you “raise.” Fine.
It is possible to define your own exception classes but to do that you first have to read the chapter about classes, that is the next chapter, and since we have not read the chapter about that yet we cannot define our own exception class can we?
They solve this by giving a simple exception-template class without explaining what a class is.
Python also has a finally clause, like other languages.
And then it was time for classes, chapter 9. It is interesting that in the chapter of classes, there is a person writing the text for me. He will make occasional use of Smalltalk and C++ terms. Can it be so that the “I” is presenting himself? “Hi, I am Joe Doe.” We will see if he reveals his name. Nice to meet you, I am Jens.
At the very point you think that the tutorial will start talking about classes it starts to talk about scopes and namespaces. That is cool, but why could that not be introduced earlier?
Again it is Joe Doe talking to me about scopes. He describes a namespace system that is pretty forward. It is similar to how you would expect it to be in other programming languages. A scope is a textual region where a namespace is directly accessible. I don’t understand that. Textual? No idea what that is. Then Joe goes on giving a list from the innermost scope step by step to the outermost scope. The search for a name starts at the innermost place going outwards.
Ooh, oooh no. Attempt to use a global variable without “importing it” with the nonlocal statement will create an on-the-fly local variable. Don’t like that because I want to be told that something is bad upfront. Will I be given a hint? Will find out later.
The stuff about textual probably means the innermost scope. What it has to do with texts remains to see.
Day 8, July 16 of 2019
Oh dear, I had a break from Phyton. If this a trend then Phyton will be no success with me. Let's hope this is not a trend.
I am still in chapter 9 about classes. I have been reading about the scope, and it is not sticky information in my case. I think I will move on without a thorough grip on the namespaces.
So we urgently move on to the classes. The section about classes is saying that the function definition inside a class normally has a peculiar form of the argument list. That is the word that they are using. Started reading about this and Woah, it was time to go to bed already. How could this happen?
Day 9, July 18 of 2019
Anyhow here I am again. And yes, I am reading about classes. Come on, Python. Let me be amazed by classes!
There is a class definition. Fine.
A definition needs to be executed before it has any effect. Hmm… I start to realize that everything in Phyton has a timeline. A compiling language has no timeline. You start compiling, and the compiler finds out what your intentions were and then before anything is running your intentions has taken a form, and that form can be variables, classes, and STUFF. A program in a compiled environment is starting with a landscape that is already populated. Here, there is nothing of that. There is a timeline. Once upon the time, we executed a class definition, and then a class was defined.
Perhaps I got compiling languages ground into my mind, and that has to let loose. Anyhow, we continue with the feast. Next up is class objects! A class object supports two kinds of operations: attribute reference and instantiation. So far, so good.
Attribute references are borrowed from the handling of scopes. You give a name of the scope, dot and then something in that scope and so on until you enter the name of a class or variable. You can with this notation change values of these. I start to think about how you do private in Python, but that is perhaps for later.
Functions… Oh no, it is time for bed again, and I am having such a great time.
Day 10, July 19 of 2019
I am on it again. I got half an hour at least. Let’s see how far we get on the functions of classes.
So when referencing a function, you receive a function object. I suppose it is a thing that we can use by calling the function in the object.
The class itself is something similar. It is a thing without parameters, and Joe wants us to “pretend” that the class object is a parameterless function that returns a new instance of the class.
It feels like Phyton is making use of this in my feeling modern view of a function. So the function with or without a name is a function object in Phyton. That object is the thing that can do calculations. You assign the function object to a name in the namespace to make a function with a name. In this line of thinking, an object is just also a function object. It has its own namespace internally, and with that, it can store variables and also more local functions and classes in that class.
Sometimes it is necessary to initialize the state of the class before using it. For this, there is a method with the cool name __init__. Functions in a class are called methods.
Perhaps “self” is a predefined identifier indicating instantiation of the current class. The tutorial talks in an example about that, the self can be received in the function as an argument. I do not understand that. If it is predefined why send it to itself as an argument. If it is not predefined, then why do I need to send it to oneself?
Next, we look into instance objects. It feels like the matter that has been explained in the previous sections are explained again?
Here comes the timeline idea again. A data attribute springs into life as soon as it is assigned to. It will exist until it is deleted.
Well, this is different to a compiled language. The variable you declare on beforehand, and there is no way of getting rid of them. The variable exists in scope and is placed there by the compiler on beforehand, and you cannot remove it. Here in Python, it doesn’t exist until you assigned to it, and you can remove it afterward. This was explained before when variables were introduced, but here it is explained again.
Then what about method objects?
Oh darn, I did not pay attention to the examples. I realized this when they said that x.f() is equivalent to MyClass.f(x), what?
First, they define a class called MyClass. Inside this class they got a function f taking an argument to be self (and I did not know if that was a predefined identifier, still don’t know). Then they instantiate MyClass to x.
There is a sentence in the tutorial: “In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s instance object before the first argument.” Okay.
Then they go on saying that if you don’t understand this, looking at examples perhaps clarify the matters. Perhaps I am overly sensitive here, but the language is stripped of curly brackets and snobbisms, and then out of the blue it slaps you in the face.
So the instant object is always inserted as the first argument, no matter what. I could see in an example that self was the first argument, but the text did not talk about it, or did it?
I am reading it again. A method is not just a function, it is special such as that the instance object is passed as the first argument. So you can call it anything, but it is the first argument, and it is “self.” WHY, why not just implement a predefined name in the namespace and have it assigned to the instance of the object?
Ok, I see it now. This is what you are doing. You send self as an argument to the method. All over the place, I will have that argument. Thanks, Joe Doe.
When defining a variable, uh – assigning it into existence, in the class, it is shared over all instances of the class.
Tucked away in the chapter “random remarks” we can read that data hiding is impossible unless you are using extensions from other languages.
Other languages are making a huge point of the data hiding facilities. Data hiding comes in flavors of all sorts and yet, here it is not present. It feels like this is a little hurdle for a little more professional organizations. I might be wrong.
Also, a random note is that “self” can be called anything, but you should not. So if I should not, then why force me to add it as an argument? It could be a predefined identifier in the namespace that upon entering the function had the self-value set.
Just before chapter inheritance, I decided to go to bed.
Day 11, July 20 of 2019
I am still on this journey of learning Python. Perhaps it is only me myself and I that will ever read this again, but that does not matter. I just let this happen, and I write along with how I learn the language.
We were at inheritance.
So it is possible to define a class and let it inherit a base class. So this is done by giving the keyword class, then the name of the current class and within parenthesis the base class name.
In Python, the things you can do with the derived class very well meet my expectations.
There are two functions isinstance() and issubclass(). Good.
Multiple inheritances are achieved by placing commas between the base class names. It sounds simple, but it is not. I think I can accept that.
But, but? Was there not a clause in the random chapter that any form of hiding is not supported in Python? Oh, private variables are not available.
There is some kind of hack. “Name mangling.” How can this be such a popular programming language? I am clueless. So apparently, you can add two leading underscores to an identifier, for example, id, and that is then textually replaced internally with _classname__id where the class name is the current class name. With this, you can have id in both the own class as well as in a subclass, and they are now not to be confused.
It feels like now we handled the boring part of Python. It is time to shine. For example, with iterators. When creating a class and defining two methods __iter__ and __next__ it is possible to use the for loop on that object.
This is a class that can provide values. We are in the chapter classes, but apparently, generators can be non-class constructions – regular functions - as well.
Actually, I don’t understand that stuff with yield with the help of this explanation. It feels like it is time for bed.
Day 12, 22 July 2019
Yesterday no Python. It is not entirely true. I looked at a YouTube about someone installing VS Code to program in Python. The surprising thing was that the entire movie was about how that person modified the settings. He changed colors, icons, and all sort of things before I lost interest and looked at something else. The good thing though is that there is a VS Code program and at some point, I will try it. Intellisence is the way to go.
Here I am again, stoked to do some Python bashing. We were at generators. Sorry if it feels like I am bashing Python. That is not my intention.
We are at generators because they are powerful tools for creations iterators. Huh? Why are we not at chapter iterators in such case?
My understanding is that it is possible to start up a for loop and what not and at some point in the loop, you can call the yield statement. This statement returns the value at that calculation but retains the state of the loop. All is frozen. This generator can then be called in a for loop, and each time a new iteration needs a value, the frozen function springs into life and makes another turn until it yields again.
This is clever. I suppose it is possible to do this in a multithreaded manner, although the text is not talking about multithreading. Actually so for nothing in Python is talking about multithreading. I look forward to that.
Now it is time for Generator Expressions!
There is not much explanation in this section. There are examples. I find it a bit counterproductive to learn something from example only, especially while reading the tutorial. Learn by example, is fine elsewhere. Generator expressions are similar to list comprehensions. The list comprehension was really heavy stuff. Cool man! So here we do the same but use round brackets instead of square brackets. Is that it? The function is simple by nature followed by for etc. No, I don’t get it. I will need to come back to this at a later stage.
With this, I finished chapter 9. Chapter 10 is a brief tour of the standard library.
It is possible to get information about the library directly from the command line with the command dir(library name) and help(library name). Consequently, I wonder how to get a list of available libraries, but that is perhaps talked about later in chapter 10?
There is a regular expression module! It is called re. I love regular expressions.
It is possible to compress and uncompress with a number of standard formats such as gzip, zipfile etc.
At the end of chapter 10, there is a section about “batteries included.” There are some examples here that are really useful. I mean this sincerely. I can see the effort that is going into this approach is substantial. It can be that here is a key to the success of Python?
Chapter 10 was quick. It looks promising.
Chapter 11, Brief tour of the standard library – part 11.
I see there is a threading module!
Chapter 12, Virtual Environments and Packages.
There is a command to manage packages called pip. I tried it, it did not work. There is another better documentation for pip. I will try that later.
And then I came to chapter 13. What now?
A logically minded person would think that this is it. This is the final chapter. So did I. I was pleased with that this was the end. When I clicked the next button, it felt like I fell off the edge of a flat earth when I came to chapter 14. So while at it, I clicked next again, and again. There is a bunch of chapters after chapter 13, so there is plenty of fun still ahead of us.
Chapter 13 is a list of useful links to other resources on the Internet about Python. I spent a great time reading articles and texts on these links. It looks promising. Some of the questions I raised are already answered. I think I will go back and answer my own questions sometimes.
With this came day 12 of Python to an end. It was a long day!
Day 13, 23 July 2019.
Now it is time for chapter 14.
This is a short chapter. It talks about the interactive interpreter. I guess I will not use that per se so much.
Now it is time for chapter 15.
This chapter talks about the internal representation of floating numbers. Since I have been programming for at least 35 years, this is no surprise actually. Next chapter.
Chapter 16. Appendix.
This chapter talks about how to start phyton in different ways. I will need to come back to this. This information feels un-sticky at this time.
Woohoo, I read all the chapters. Kind of.
I was born 1967 in Stockholm, Sweden. I grew up in the small village Vågdalen in north Sweden. 1989 I moved to Umeå to study Computer Science at University of Umeå. 1995 I moved to the Netherlands where I live in Almere not far from Amsterdam.
Here on this site I let you see my creations.
I create, that is my hobby.