There is a well-known movie line: “This! Is! Sparta!!” To begin the new year, here begins a series of posts under the rubric of “This is Python!” (Python isn’t quite as emphatic about things as Spartans, so it’s just one sentence with one exclamation point.)
These posts are meant for those who have never met Python but who have used a programming language before and know the general concepts. These posts provide a tour of the language.
Python is a freely available — and very popular — programming language. (Visit Python.org for more information and downloads.)
Python is a scripting language. Programmers write Python code in text files — typically with a .py extension. Coders can use any text editor (for example, Windows Notepad), but most prefer an editor made for code writing. Such editors, at the very least, use syntax highlighting to make coding easier. Python-aware editors can do even more to help programmers avoid mistakes.
A notable feature of Python is that it uses indentation for block scope:
002| class MyClass:
003| ”’An example class.”’
004|
005| def foobar ():
006| ”’An example function.”’
007|
008| # See if x is less than zero…
009| if x < 0:
010| x = 0
011| …
012|
The fragment above illustrates a number of Python features. Firstly, anything following a pound-sign (aka hash mark) — up to the end of the line — is a comment. Lines #1 and #8 are examples.
Secondly, everything after line #2 is indented (at least) one level and therefore “belongs” to line #2 (don’t worry about what it does; we’ll get to that later). Everything after line #5 is indented a second level and belongs to line #5 (and line #5 belongs to line #2). Lastly, everything after line #9 is indented a third level and belongs to line #9 (which belongs to line #5, which belongs to line #2).
From a code execution point of view, line #2 has only one “child” — line #5. That line also has only one child — line #9. But line #9 has two children, lines #10 and #11.
The three dots in line #11 are valid Python syntax — they create a “no-op” Ellipsis token in the code. Programmers use them as placeholders. Programmers can also use Python’s pass statement to accomplish the same thing:
002| ”’Need to define this!”’
003| pass
004|
Lastly, from a code point of view, line#2 in the first example actually has two children. So does line #5. In the code directly above, line #1 has two children. In all three cases, the string immediately following the line — which uses three single-quotes — is a documentation string attached to the definition preceding it. This string is available to the code, an advanced topic for later.
Now that we’ve gotten a taste of what Python looks like, let’s start exploring.
A key aspect of any programming language is the set of built-in (“native”) data types it supports. Most languages have integer and floating-point types for numbers; Python is no different.
Its integer type has a few wrinkles you may not have encountered in other languages. This code fragment shows eight ways to create an integer variable called n:
002| n = int()
003| n = 0
004|
005| n = int(42)
006| n = int(’42’)
007| n = 42
008|
009| n = 1_000_000_000_000_000_000
010| n = 1e18
011|
012| n:int = –42
013|
In Python, the integer type (or class) is called int.
Line #2 uses the int type directly by using it as a constructor. This creates an integer object with the default value (zero) and binds (or assigns) it to the variable name n. Line #3 does the same thing (the literal value 0 is an integer because it has no decimal point).
Note that the first assignment (line #2) creates the variable (because it’s the first time the name n appears) — assignments after that only bind a new integer object to it. In line #3, when Python assigns the new integer object to n, it discards the one it assigned in line #2.
Lines #5-#7 all create and bind an integer value of 42. Note that the int constructor can take a text value or a numeric value. A frequent use for the constructor is converting string values into numeric ones. As we’ll see later, it can convert hexadecimal, octal, or binary strings to numeric values (it can, in fact, handle any base up to 36).
Lines #9 and #10 both create and bind an integer value of one quintillion. Python allows large integer values subject only to memory limits. As an aid to clarity, underbars are permitted in numeric literals. They are generally used the same way commas are used: to break a long string of digits into easier to read triplets. Python ignores underbars in numbers.
Note that variable declarations do not have type declarations. Python data knows what type it is, but variable names can be freely bound to any data object and changed at will. Data type only matters when actually acting on the data.
Python uses duck typing — if an object looks like a duck, walks like a duck, quacks like a duck, as far as Python is concerned, it is indistinguishable from a duck. If you try to add two objects together, and they know how to add themselves, then the operation works. If not, Python raises an Exception — Python’s way of bugging out.
That said, Python allows type hints. Such type hints are, firstly, annotations that make the code’s intent clearer (clarity is rule #1). Secondly, there are tools that use them to validate the code. Some coding environments use them for real-time type-checking.
Line #12 shows an integer type hint for the variable n. Python ignores type hints, so the integer creation and name binding are the same as in the previous lines. Line #12 is essentially identical to line #7, except that the integer value here is minus 42. Integers can be negative or positive.
There is more to Python int objects, but that’s enough for now.
For real numbers, Python has a floating-point type. Here are seven examples that create a floating-point variable named x:
002| x = float()
003| x = 0.0
004|
005| x = 2.718281828
006| x = float(42)
007| x = float(‘3.14159’)
008| x = 6.16e-32
009|
010| x:float = –3.141592
011|
The Python floating-point type is called float (but is the IEEE double).
As in the first example, line #2 uses the float constructor to create a floating-point object with the default value (zero) and assignment to the variable x. Line #3 does the same thing but uses a floating-point literal value (indicated by the decimal point).
Likewise, lines #5-#8 create floating-point objects with values provided by literals. As with the int constructor, the float constructor can convert string values to numeric ones (line #7). Note that, without the float constructor in line #6, variable x would be assigned an int object with the value 42. Line #8 illustrate using scientific notation in a floating-point literal value.
Lastly, line #10 shows a float type hint.
Python has a string type for handling text and characters:
002| s = str()
003| s = ”
004|
005| s = “Hello, World!”
006| s = ‘Hello, World!’
007| s:str = “Hello, World!”
008|
009| s = “””\
009| This is line one of three.
009| This is line two of three.
009| This is the last line.
009| “””
010|
The type is called str, and it does a lot that we’ll explore in detail later. Unlike some languages, Python does not have separate string and character types. Python strings can have from zero to as many characters as needed. (In fact, there is a limit, depending on your platform, but it’s absurdly large, especially for 64-bit platforms.)
In Python, string literals can be enclosed in either single-quotes or double-quotes. Python makes no distinction. This is handy when the string contains single- or double-quote characters:
002| s = “Don’t forget. It’s next Tuesday.”
003|
004| # Single-quoted string with embedded double-quotes…
005| s = ‘The text read, “Hello, World!”‘
006|
007| # Single-quoted string with escaped embedded single-quotes…
008| s = ‘Don\’t forget. It\’s next Tuesday.’
009|
010| # Double-quoted string with escaped embedded double-quotes…
011| s = “The text read, \”Hello, World!\””
012|
013|
Note that you can use a backslash to “escape” embedded quote characters (lines #8 and #11).
Python also has a special quoting mechanism (line #9 in the first example) that uses three single- or double-quotes in a row. This is handy for multi-line text, as the example shows. As we saw in the very first example, such strings also serve as documentation strings that, because they are accessible to code, can be extracted and put into code documentation.
Note that Python strings are immutable. Strings cannot be changed once created. You can only create a new string with whatever changes and then, if you want, reassign it to the same variable. Here’s an example:
002| print(s)
003|
004| s = s.lower()
005| print(s)
006|
007| s = s.upper()
008| print(s)
009|
010| s = s.title()
011| print(s)
012|
Line #1 assigns the literal string "Hello, World!" to the variable name s. (Note that Python doesn’t care what you call your variables. That’s totally up to you. Just don’t use Python keywords.)
Line #2 introduces Python’s print function, which displays text on the console.
Line #4 invokes the str.lower method, which creates a new version of the string in lowercase. The original string is discarded and the new one assigned to variable s. Line #5 prints the now all-lowercase text.
Line #7 invokes the str.upper method, which creates an uppercase version of the (lowercase) text. The lowercase version is discarded. Line #8 prints the uppercase version now assigned to s.
Line #10 invokes the str.title method, which creates a “title” case version — uppercase leading letters, the rest lowercase. The uppercase version is discarded and the new version assigned to s. (Line #11 prints what looks like the original string but is in fact third-generation copy.)
When run, this code prints:
Hello, World! hello, world! HELLO, WORLD! Hello, World!
This example just hints at the capabilities of Python strings. There is a lot more to them that we’ll get to down the road. For now, though, let’s move on.
The two numeric types, int and float, along with the string type, str, suffice for many programming tasks. Python has a number of other important built-in types. A key one is the true/false Boolean type:
002|
003| flag = bool() # set flag to False
004| flag = True # set flag to True
005| flag = False # set flag to False
006|
007| flag = bool(0) # set flag to False
008| flag = bool(1) # set flag to True
009| flag = bool(42) # set flag to True
010|
011| flag = bool(”) # set flag to False
012| flag = bool(‘False’) # set flag to True
013| flag = bool(‘True’) # set flag to True
014| flag = bool(‘Hello’) # set flag to True
015|
Python’s Boolean type is bool. It’s the value type you get back from comparisons such as equals or greater-than. It’s also the effective type of conditional expressions such as used in if statements or while loops.
The bool constructor can take an argument which it treats as a Boolean expression and returns either True or False. Both are special Python objects. False is effectively zero, and True is effectively one:
002|
003| print(‘Integer value of False is:’)
004| print(int(False))
005|
006| print(‘Integer value of True is:’)
007| print(int(True))
008|
009| print()
010|
When run, this prints:
Integer value of False is: 0 Integer value of True is: 1
As in many languages, when Python sees an expression in a Boolean context, it treats non-zero numeric values as True and zero as False. Strings are False if they have zero length, otherwise they are True (lines #12 to #14). In general, any type of list (a string is a list of characters), is True if it has at least one item and False only if it is empty. (When you design your own types, you can control how they respond to a Boolean context.)
Generally speaking, the Boolean type is a bit under the hood. They are implicit in comparisons and conditional expressions, but contrary to the examples above, one doesn’t often use the bool constructor. The special True and False objects, however, are very common in code.
Another important special Python built-in is the None object. It’s somewhat like the null in C and other languages. It’s a special object that you can use in code:
002| ”’Demo function.”’
003|
004| if x is None:
005| x = 0
006|
007| if y is None:
008| y = 0
009|
010| print(x, y)
011|
012| return None
013|
014|
015| # Call function with no parameters…
016| my_function()
017|
018| # Call function one parameter…
019| my_function(21)
020|
021| # Call function one parameter…
022| my_function(y=42)
023|
024| # Call function with all parameters…
025| my_function(21, 42)
026|
We’re jumping a bit ahead here — we’ll come back to explore functions in detail later — but lines #1 to #12 define a function named my_function. It takes two parameters, x and y, both of which have the default value None. Parameters with default values do not have to be supplied when the function is called.
Lines #4 and #5 test x to see if it has the default value None. If so, line #5 sets x to zero. Lines #7 and #8 do the same thing for y. The function then prints x and y (line #10) and returns the value None in line #12.
Note that functions that do not explicitly return values still have a return value of None. We could leave line #12 out, and the function would work the same, it would still return None.
Lines #16, #19, #22, and #25 all invoke the function in various ways. First, with no parameters, then with just one — which gets assigned to the first parameter, x. The third one shows how we can provide y while allowing x to default. Lastly, with both parameters supplied.
When run, this prints:
0 0 21 0 0 42 21 42
We’ll look at functions in a lot more detail in future posts.
We’ll pick up next time with more Python types, especially lists and dictionaries.
∅
ATTENTION: The WordPress Reader strips the style information from posts, which can destroy certain important formatting elements. If you’re reading this in the Reader, I highly recommend (and urge) you to [A] stop using the Reader and [B] always read blog posts on their website.
This post is: This is Python! (part 1)