Socrates in a Starbucks
Close your eyes and imagine a philosopher. What does your imaginary philosopher look like?
Chances are it is a bald(ing) gray-haired and bearded man, slumped in a chair with a penetrating gaze—shelves of books in the background; a smoking pipe in his hand, perhaps. The sweet smell of coffee and old paper fills the air. He’s ready to discuss Hegel or Derrida with you. Hard questions galore.
You may (or may not) be surprised to learn that this image of philosophers is outdated and a gross misrepresentation of what contemporary philosophers look like and what they do.
First, they’re not all men, obviously; plenty of philosophers are women nowadays. Second, they’re more likely to be sitting in a local Starbucks, MacBook Air in their lap, sipping matcha latte, than in a mahogany-colored library smoking pipes.
Third, and most relevant for this story, not all of them dabble in German idealism or French poststructuralism (or any other Eurocentric ism). Some of them prefer spending their time writing and debugging code in their favorite programming language.
I am one of such philosophers.
Philosophy is a broad discipline, with a greater number of distinct specializations than there are bird species in the Galapagos, so it’s not that surprising that some of them are into computers. As a matter of fact, many contemporary philosophers specialize in the philosophy of computer science, where they examine different philosophical questions arising from the practice of computation and its tools.
For example, do both hardware and software exist? Some philosophers say computer programs are purely abstract entities, subsisting on electric circuits provided by hardware, and thus have no independent existence.
Man meets the snake
I am not one of these philosophers, however. I do not specialize in computer science or ask these kinds of questions. My expertise is in the philosophy of education and critical thinking.
But, I developed a love for code because I believe coding skills are essential for intellectual development. Over the past several years, as I’ve learned Python, I realized that understanding how computer code works can be immensely beneficial for developing critical thinking skills. I believe this is both a timeless and a timely claim. Coding taps into centuries-old philosophical efforts to think better; the current gallop of AI necessitates expanding our thinking toolkit.
I have not always believed this. I spent most of my life oblivious to computer programming and never considered it as a tool for thinking. However, once I discovered it as an adult, I immediately saw how it can help us to think clearly and reason better.
If you’ve never written a line of code, this article is for you.
I wish to do two things here: first, to convince you that computer programming is inseparable from critical thinking; second, to persuade you to start learning more about it. I’ll do it by showing you a bit of Python programming and commenting on some interesting aspects of code.
If you choose to follow me on this intellectual effort (or, should I say adventure?), you will reap immense intellectual benefits. Trust me on this.
What is Python and how to use it?
Python is considered one of the easiest programming languages, for several reasons. First, it is free to use; you don’t have to buy anything.
Second, its commands resemble ordinary English. For example, if you want to print something on the screen, you write:
and the computer prints the words in the parentheses on the screen.1
Simple, right?
This is because Python is, basically, an interpreter. It takes human commands expressed in an English-based syntax and simplifies (compiles) them to a more basic set of commands, which are again simplified further, all the way to the binary code that communicates the commands to the electric circuit board on your computer.
In more ways than one, it is like an ordinary language, with precise rules of grammar. However, it is a language that helps us communicate with the electric circuit board, not with another human being, which makes it a bit more peculiar. Unlike human beings, computers can’t understand nuance, read between the lines, or use their intuition. For computers, unless programmed otherwise, ‘bird’ and ‘Bird’ are two completely different words.
Thus, one of the most important things to remember when starting with coding is that words and symbols matter. If you forget a single quotation mark or add an extra space, the code will not work and you will get an error message.
Here’s what happens if you omit the closing quotation:
So, remember that, and don’t get frustrated if this happens a lot in the beginning. Fortunately, it is often easy to find these mistakes (‘debug’ the code), and there are plenty of tools at our disposal (see the picture above - the error message tells you exactly what’s wrong with the code).
Now, let’s start by explaining where we run Python code and how we see its results. There are many ways you can run Python. You can install it on your computer and use an application (such as VS Code) to run it, or you can use your internet browser (Chrome, Firefox, Safari, or any other) to run the code in a specially designed environment (think a website) called a Jupyter notebook.
We will use this second method because it is much simpler and faster (you don’t need to install anything on your computer, all the code runs on the cloud).
Let me show you how to do it. First, search for ‘Google Colab’ in your browser.
The first link that appears will look like this:
Google Colab is Google’s environment for creating Jupyter notebooks. ‘Jupyter’ is an acronym for the three programming languages you can use here: Julia, Python, and R. We will use Python, of course.
Notebook is a name for something that will look like an interactive Word page to you. It’s like a webpage in which you can write and execute code. You’ll see some examples soon.
Click on it. If you have a Google account it will either sign you in automatically, or it will ask you to sign up for one. If you don’t have a Google account, open one and sign in.
Once you’re in Google Colab, you can do some research by yourself first, to learn more about this platform. Once you’re done, you can open a new notebook in the same way you’d open a new blank Word document, by going to the top left corner and clicking on the ‘File’ command:
Once you do that a new notebook will open. It will be called ‘Untitled’ by default, but you can click on the name and change it:
Make sure to keep the ‘.ipynb’ domain, it determines the type of the file in the same way that ‘.doc’ does.
This is now your notebook, in which you will write and execute code, and write any other text you wish.
The body of the notebook consists of two types of cells, ‘code’ and ‘text’ cells (you can open each by clicking on the + Code
or + Text
commands at the top. Code cells are used for code and text cells for plain text.
Let’s go ahead and open a code cell. Type in the famous introductory command and then either click on the white triangle in the black circle or use Command/Ctrl + Enter on your keyboard to run the code.
When executed, your cell will produce output like this:
Congratulations, this is your first line of Python code!
Python is a powerful and versatile language with many new things to learn. Once you start learning, you will embark on a possibly life-long journey of mastering it, so take your time, and don’t rush. Make sure to understand what you’re doing before you move on to more complex practices. Here’s a great blog with beginner-friendly lessons, if you want to learn more.
We will start simple, and you will learn enough to understand why coding is important for developing your critical thinking skills.
Types of data
One of the first things you’ll notice when you start coding in Python is that there are different kinds of data Python works with, and different operations we can perform on these data types.
For example, we can use numbers (integers like 5, 7, 19, or real numbers, AKA floats like 5.5, 7.3, 19.6), letters of the alphabet (like ‘a’, ‘x’, ‘p’, or whole words like ‘Alice’). These are simple data types.
One of the simplest operations is defining some variable and setting it to some value. For example, let’s say we want to make an Instagram account for Alice and we get some information from her. We can then do this:
Here, in the first line, we created a variable (literally, a varying value) called name
and assigned it the value ‘Alice’
. We use the single equality sign, =
as the assignment operator. In the second and third lines, we defined two additional variables, one of which is also a word, and the other a number. Note that if your variable has two words, you have to connect them with an underscore, like in the eye_color
example.
Notice that when we define variables we use letters without quotation marks, but when we wish to assign some name to that variable we use quotation marks to tell Python that the data type here is a string (the name for a word- or letter-like data value). When we use numbers (either integers or floats), we don’t use quotation marks, unless we want them as strings (which we may want to, but not now).
It is important to be careful about how to define these values because each data type can be manipulated differently with different operations. Check what happens if we use multiplication on a number defined as an integer in one case, and defined as a string in another:
The asterisk *
here is a symbol for multiplication. In the first case, since 2
is written as a number, we get a normal calculator-type result of 16, but in the second case, since we wrote ‘2’
as a string (with quotation marks), the result is just that string repeated eight times. Sometimes you’ll want that, sometimes you won’t so pay close attention to this.
You may notice some numbers in the square brackets next to the code I wrote here. These stand for orders of operation within the notebook. Notebooks are sequential in running their code. If you define some value in a cell before, you can always retrieve it in a cell that was run sequentially after that cell. Check this:
Look at cell number 9: here I told Python to print three things that were previously defined. Python remembers what you tell it, it keeps the values until you overwrite them (which you can do at any point you wish, and Python will then remember the new value).
Besides obvious data types like numbers and strings, we can have others, some of which are also simple, while others are more complex. For example, another useful data type is a Boolean, which is a derivation of the surname of a famous mathematician, George Boole, and this data type has only two values: True
and False
.
Booleans are a bit different than numbers or strings because they are related to some logical operators. Logic is a formal way of thinking whose rules are very simple, and logical operators are procedures for using these rules. You learned many of them in elementary school. They connect two or more expressions and allow us to assert those expressions or, as in programming, ask some questions about them.
For example, the expression ‘a AND b’
is a logical operation involving two elements, ‘a’
and ‘b’
, and the word AND
is a logical operator helping us to assert that both a
and b
are true.
In Python, we can use logical operators to check if some things are true. If our expressions are name = ‘Alice’
and eye_color = ‘brown’
, we can do the following:
Note the double equality sign, ==
. This is not a mistake, but a special logical operator that asks Python a question. The output is a Boolean data type, True
.
To check that the logical operator ‘AND’
works as it should, try changing one of the two values connected by it. If we change only one of them, then the whole expression ‘a AND b’
will not be true then (since only one element is true), and Python will return this:
Remember, the double equation sign ==
does not assign anything, it just asks Python a question, to which we get a Boolean data value in return: True
or False
.
Exercise 1: If you definedeye_color
as'brown'
, ask Python if theeye_color
is'blue'
. Did you get the expected result?
Besides simple data types, we also have more complex ones, such as lists, sets, tuples, dictionaries, and data frames (there are more, but we don’t need them right now).
Let’s review a few of them.
Lists are ordered collections of values, kept within square brackets, like this:
Sets are unordered collections, defined with curly brackets, like this:
Dictionaries are unordered collections of pairs of elements, called keys and values, also defined with curly brackets, like this:
Tuples are ordered collections of items, defined with the parentheses, like this:
If you haven’t done any coding before, you may think that computers are weird for demanding different formats for different types of data, but let me assure you that this is not much different from the ways our brains work too.
Exercise 2: Use a dictionary data type to make an inventory of your fridge, where the keys will be the names of the items (they should be strings, like'eggs'
) and the values will be numbers indicating the amount (they should be integers, like6
). Think about this: What kind of an app could you imagine making with this dictionary?
Representing the world with Python
When we think, we format our thoughts in different ways. A big lesson I learned from programming is how we organize our thoughts matters. Coding helps us understand that orderly thinking leads to better results, conclusions, and decisions.
Here’s the thing. The world in which we live is not given to our minds directly. It doesn’t come pre-packaged for our understanding; we must extend effort to grasp it.
We do it by representing the world using concepts mediated by language. ‘Name’ is a word used to denote a concept of a name, which we use to distinguish between unique objects in the world, like different persons. ‘Alice’ is a value assigned to some person using this concept, and as long as that person doesn’t change their name, we remember it and use it to refer to her.
Now, imagine if instead of ‘Alice’ that person changed their name to ‘Name’. In such a case, the word used to denote the concept would also be used in assigning a particular value to the person using the concept. While doing that is perfectly fine from a legal or moral standpoint, think about the confusion it would bring to thinking and communicating personal names. Imagine a person called Name getting their driver’s license at the DMV. Confusion in the usage of concepts can often lead to confusion in thinking.
The concepts we use to reason about the world are different and they can’t all be used in the same way. Since we have a choice in how we conceptualize things, we should do it in ways that lend themselves to easier mental processing and better thinking results.
Here’s the most important lesson I learned from Python: clarity and order, which are intrinsic to good programming, are crucial critical thinking concepts. Every complex process consists of a number of smaller concepts and sub-processes, and if those are well-ordered (if there is a clear logical flow in them), the results of our thinking will be good.
Learning how to code can help us appreciate clarity in thinking and communication. It can also bring simplicity to processes that otherwise may be quite confusing or complex.
For example, let’s say we wish to optimize our food consumption. We do not want to throw away unused and spoiled food from the fridge, but we also do not want to end up lacking some items when we’re hungry. We wish to go grocery shopping only if we’re running low on some items.
Let’s represent our fridge contents with a dictionary, like this:
Now, how would you represent a process that checks if the stock of some of the items is running low and tells you to go shopping?
The easiest way is to use a conditional procedure, with terms such as if
and else
. Here’s how that looks in Python:
This code snippet, while very simple to experienced programmers, is actually quite amazing because it shows you how all complex processes utilize simple concepts (data types) to produce desired outcomes.
Let’s analyze it a bit.
First, check the two purple-colored phrases, if
and else
. Python conveniently colors them in the same way to help us understand that they are both a part of a single operation. This is a conditional operation that executes some commands only if some things are true.
Look at the first line. The phrase that comes after if
is called antecedent, or a condition, and here that is fridge[‘eggs’] < 5
.
Square brackets can also be used to retrieve parts of our complex data types (like lists, dictionaries, or data frames). This one retrieves the value of the key ‘eggs’
, the other element of the key-value pair.
Type it in by itself to confirm:
When we use a logical operator like <
(‘smaller than’) with some phrase, we get a Boolean value in return. So, the entire first line compares the values of fridge[‘eggs’]
with number 5
, and tells Python to print the sentence “You’re running low on eggs, go shopping!”2 if the comparison returns a Boolean value of True
.
The print command in this piece of code is called the consequent, and it represents an operation that is executed if the antecedent is true. In our case, the antecedent is true because the phrase fridge[‘eggs’] < 5
evaluates to True
. You can check that by yourself like this:
Another important thing to notice is the indentation of different pieces of code here. Notice how the words if
and else
are at the same indentation level, while what’s underneath them is moved one tab to the right?
This serves the purpose of good organization of the process of code execution. We can even visually confirm which actions belong to which conditions.
It also specifies to the computer that not everything in this code needs to be executed. This same piece of code can produce a different result if the values we assigned previously change.
Go ahead and change the value of ‘eggs’
in the fridge
dictionary. When we execute our conditional code, it will look like this:
There is a deceptively simple lesson to be learned here. The same piece of code will produce a different outcome if the inputs to it change. In Python, just as in life, it is important to keep track of the parameters we use to do our thinking. If we’re not aware of the changes in what values these parameters take, we will make mistakes.
I hope you can see the similarity between this piece of code and the graph that we talked about in the last lesson. This Python code is nothing else but a software version of this decision tree:
This is the beauty and power of coding: it allows us to represent real-life situations in ways that preserve order. In our thinking, we always want to preserve order because disorderly thinking will not be productive or useful.
Debugging as critical reflection
Once I learned a bit of Python and started playing around with code, I learned to what extent the popular hacker-style image of programming (prevalent in movies) is incorrect. Writing code is rarely linear. Instead, programming involves constant checking, testing, and removing bugs (mistakes) hidden somewhere in our code.
This gives us another great analogy between coding and thinking. Just as a programmer tests individual components of code to isolate the source of an error, when we think critically, we examine our own beliefs and assumptions to identify inconsistencies.
Critical reflection is basically ‘debugging.’
In programming, debugging involves hypothesizing potential causes of the problem, testing these hypotheses, and going back and forth to fix things until the issue is resolved.
In both debugging and critical thinking, clarity and precision are paramount. A small typo in a program can lead to a significant error, just as a minor flaw in reasoning can undermine an argument. By engaging in debugging, we practice the discipline of paying close attention to detail, recognizing that each element must be correct for the whole system to function properly. This meticulous attention to detail can cultivate a mindset of thoroughness and accuracy, which are essential for good critical thinking.
It also teaches us patience and resilience. Being stuck is normal. We’ve all been there. But with meticulous work, and resilient attitude, we can get out of the rut.
Parting thoughts
The examples in this article are simple, but I hope you can see the effects of coding on clear, systematic, and orderly thinking. We will utilize and expand on things learned here in our future lessons.
I will leave you with a reading suggestion and an exercise.
If you’d like to learn more about the connections between philosophy and Python programming, check this book out:
Since practice makes perfect, here’s an exercise you can do:
Exercise 3: Useif
andelse
commands to represent a larger and more complex decision tree. For example, make one related to some more serious life decisions than going grocery shopping. Here's a challenge: how can you represent nested conditionals, i.e. situations in which one condition is followed by another?
You can either use single or double quotation marks, it doesn’t matter as long as you use the same in the opening and the closing.
Notice how I used double quotation marks here so I could use the apostrophe in You’re. If I hadn’t then the string would close after You.
Interesting threads you weave here.
Why would a Coder use definitions of Nouns & Verbs within Dictionaries and muddle with Education ?
Because the Semantics of those definitions are interpreted by forGL as running programs.
Dictionary is real in forGL and not a faux abstraction.
The other use for Dictionary reasoning is translation between Semantic equavalents.
forGL 2019 demonstrated programming in German and other European languages.
https://www.forgl.org