Upon installation, you can already program some immediate applications.
>>> 9 - 1 # subtraction
8
>>> 4 + 2 # addition
6
>>> 1 / 4 # division
0.25
>>> 2 * 5 # multiplication
10
>>> 2 ** 9 # exponentiation
512
>>> 2 ** 9 - 1 / 4 + 2 * 5 # evaluation precedences
521.75
>>> 2 ** ((9 - 1) / (4 + 2) * 5) # evaluation precedences alterated
101.59366732596473
All of the above are examples of Python expressions (as shown beside interactive prompt >>>
) which evaluate to eventual values (as presented below the interactive prompt >>>
).
Each expression may have elements such as operands (such as the numbers), as well as operators (such as +
).
Expression evaluation follows a set of rules, from what we have seen so far:
The text after #
is a type of inline comments, which are only for humans to read and discarded by the machine. They are not a part of expressions.
>>> 10 / 3
3.3333333333333335
Notice the oddity in the output value 3.3333333333333335
?
It is known as a floating-point arithmetic error or round-off error since real numbers are only emulations of the underlying binaries, a product and trade-off of digitization.
So by design, this type of error cannot be eliminated in digitally based systems but can only be managed by taking trade-offs between ranges and precisions. When it is not managed well, it resulted in matters of life and death.
For this reason, precision-sensitive data usually gets stored and calculated in fixed-point numbers – or integers with an implicit definition of the fraction scale it represents. For instance, if we want to perform the same division, instead of 10.00 / 3
, we will scale everything to cents (1/100 of a dollar):
>>> 1000 / 3 # 1000 cents
333.3333333333333
Now it is a bit better without the odd 5
at the end of the fraction. And if we choose a desired fractional precision and can afford to forego the remainder, let us say down to 1/10 of a cent (1/1000 of a dollar):
>>> 10000 // 3 # 10000 mills, integer division
3333
Unlike divisions, //
performs specifically an integer division (or floor division) and forgoes the remainder.
The above is a real-life example of a creative workaround of an innate limit by applying controlled trade-offs.
And if we want to know how much remainder we have foregone, we can use the modulo operator %
to do so:
>>> 10000 % 3 # modulo, for integer division remainders
1
The modulo %
operator can be practical in a couple of other ways:
>>> 864192 % 7 # is 864192 divisible by 7 (without remainders)?
0
>>> (16 + 12345) % 24 # what's the time after 12345 hours from 16:00?
1
If using Python as a glorified calculator is not good enough for you, let us do some text processing.
>>> 'make puppies great again! 🐶'.upper()
'MAKE PUPPIES GREAT AGAIN! 🐶'
What’s up? Letter cases, of course.
Follow the same expression evaluation rules we have collected from before, let us pick apart the above expression.
'make puppies great again! 🐶'
portion defines a string value or a sequence of textual characters. In Python, these string values are of the built-in str
type
Each type corresponds to a class that has a set of internal mechanisms referred to as methods that make use of the value it holds. In this particular case, we are applying a letter case transformation mechanism upper()
to return a copy of the original text with all letters in uppercase. The notion of ()
means it is a form of “Callable” that activates the said mechanism.
Methods that returns (evaluates into) a value enables us to do:
>>> 'make puppies great again! 🐶'.title().swapcase() # title, then swap lower/upper cases
'mAKE pUPPIES gREAT aGAIN! 🐶'
The last example calls two methods in a chain, and it is evaluated as expected, from left-to-right:
'make puppies great again! 🐶'.title()
gets evaluated into 'Make Puppies Great Again! 🐶'
.'Make Puppies Great Again! 🐶'.swapcase()
gets evaluated into what you see.Note: aside from str
we have also seen two of the numeric built-in types, int
(or integer) and float
(or floating-point number), in the Arithmetics section from before. We will see more built-in types and their methods along with the series, and we will get to define our types when we get to the details of defining custom classes and their methods.
Use what you have gathered so far, come up with a Python expression to answer “what is the time after 12345 seconds from 16:00?”.
One of the ways to define strings in Python is by surrounding a sequence of textual characters with quotes ('
or "
).
>>> "a string"
'a string'
>>> 'another string'
'another string'
Consult the official Python documentation on the Built-in Type str
and other online resources, find out one or multiple ways to define strings such as 'tis the season for some Trick 'r Treat, says "Nobody"
which contain both types of quotes.