<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged basics</title>
<link>https://coderlegion.com/tag/basics</link>
<description>Powered by Question2Answer</description>
<item>
<title>Python Basics in the Matatu Context</title>
<link>https://coderlegion.com/29960/python-basics-in-the-matatu-context</link>
<description>&lt;p&gt;Watch a matatu conductor work for one trip and you will see a programmer at full speed. He counts heads. He knows the fare. He takes a KSh 500 note from someone who owes KSh 70 and hands back the exact change without a pause. He also decides, by feel, when the vehicle is full enough to leave.&lt;/p&gt;
&lt;p&gt;Listen to what he tracks: a number plate, a seat count, a fuel bill and a yes or no on whether the vehicle is full. That is text, a whole number, a decimal number and a true-or-false answer. Python cares about that difference, and once you see why, the basics stop looking like rules to memorise.&lt;/p&gt;
&lt;p&gt;This article covers variables, four data types (string, integer, float and boolean), input and output, and the syntax that binds them together. Every example follows one fictional conductor working for the Mwananchi Express sacco. The fares, fuel prices and plate number are invented, so change them to match real life. Each code block shows the output you will see in your terminal. &lt;/p&gt;
&lt;h3 id=&quot;variables-names-not-boxes&quot;&gt;Variables: names, not boxes&lt;/h3&gt;
&lt;p&gt;Most tutorials say a variable is a box that holds a value. The picture fails quickly, so use this one. A variable is a sticky note with a name on it. Python sticks the note onto a value. You can peel the note off and stick it on something else, and you can put two notes on one value.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;plate = &quot;KDD 482P&quot;
seats = 14
fare_kes = 100
is_full = True

print(plate, seats, fare_kes, is_full)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$ python matatu.py
KDD 482P 14 100 True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;=&lt;/code&gt; sign does not mean &quot;equals&quot; the way it does in maths. It means &quot;stick this name on that value.&quot; Python works out the right side first, then attaches the name on the left.&lt;/p&gt;
&lt;p&gt;That order explains a line that would be nonsense in algebra. Say the sacco raises the fare by KSh 20:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;fare_kes = fare_kes + 20
print(fare_kes)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;120
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python takes the current value of &lt;code&gt;fare_kes&lt;/code&gt; (100), adds 20, and moves the sticky note onto the result. Nothing was changed in place. The note moved.&lt;/p&gt;
&lt;p&gt;Here is the two-notes idea at work:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;x = 14
y = x        # y sits on the same value as x
x = 13       # x moves to a new value; y stays put
print(x, y)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;13 14
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Changing &lt;code&gt;x&lt;/code&gt; did not touch &lt;code&gt;y&lt;/code&gt;, because &lt;code&gt;y&lt;/code&gt; never pointed at &lt;code&gt;x&lt;/code&gt;. It pointed at the value 14.&lt;/p&gt;
&lt;h4 id=&quot;naming-rules&quot;&gt;Naming rules&lt;/h4&gt;
&lt;p&gt;A name can hold letters, digits and underscores. It cannot start with a digit, and it cannot be a word Python already uses, such as &lt;code&gt;if&lt;/code&gt; or &lt;code&gt;True&lt;/code&gt;. Names are case sensitive, so &lt;code&gt;Seats&lt;/code&gt; and &lt;code&gt;seats&lt;/code&gt; are two different notes.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;Seats = 14
print(seats)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Traceback (most recent call last):
  File &quot;matatu.py&quot;, line 2, in &amp;lt;module&amp;gt;
    print(seats)
          ^^^^^
NameError: name 'seats' is not defined. Did you mean: 'Seats'?
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Read the error from the bottom. Python names the problem (&lt;code&gt;NameError&lt;/code&gt;), names the culprit (&lt;code&gt;seats&lt;/code&gt;), and guesses what you meant. Most Python errors help you this much once you learn to read them.&lt;/p&gt;
&lt;p&gt;The community habit is &lt;code&gt;snake_case&lt;/code&gt;: lowercase words joined by underscores. Put the unit in the name (&lt;code&gt;fare_kes&lt;/code&gt;, &lt;code&gt;fuel_litres&lt;/code&gt;) and you prevent a whole class of mistakes later. Values that should never change get capital letters, like &lt;code&gt;SEATS&lt;/code&gt;. Python will let you change them anyway. The capitals are a note to the next reader.&lt;/p&gt;
&lt;h3 id=&quot;the-four-data-types&quot;&gt;The four data types&lt;/h3&gt;
&lt;p&gt;Every value has a type, and the type decides what you can do with it. Ask Python with &lt;code&gt;type()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(type(plate))
print(type(seats))
print(type(38.5))
print(type(is_full))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;class 'str'&amp;gt;
&amp;lt;class 'int'&amp;gt;
&amp;lt;class 'float'&amp;gt;
&amp;lt;class 'bool'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;strings-str-&quot;&gt;Strings (&lt;code&gt;str&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;A string is text inside quotes. Single or double quotes both work. Pick one style and keep it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;sacco = &quot;Mwananchi Express&quot;

print(len(sacco))
print(sacco.upper())
print(sacco + &quot; Sacco&quot;)
print(sacco[0])
print(sacco[:9])
print(&quot;Karibu! &quot; * 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;17
MWANANCHI EXPRESS
Mwananchi Express Sacco
M
Mwananchi
Karibu! Karibu! 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;len()&lt;/code&gt; counts characters, spaces included. The &lt;code&gt;+&lt;/code&gt; sign glues strings together. Counting starts at zero, so &lt;code&gt;sacco[0]&lt;/code&gt; is the first letter, and &lt;code&gt;sacco[:9]&lt;/code&gt; means &quot;everything before position 9.&quot; Multiplying a string by a number repeats it.&lt;/p&gt;
&lt;p&gt;Strings suit phone numbers well. A Safaricom number is text, not a number, because nobody adds two phone numbers together and the leading zero matters. Here is how to turn a local number into the international form that M-Pesa integrations expect:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;local_number = &quot;0712345678&quot;

print(&quot;+254&quot; + local_number[1:])
print(len(local_number))
print(local_number.startswith(&quot;07&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;+254712345678
10
True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The slice &lt;code&gt;[1:]&lt;/code&gt; means &quot;everything from position 1 onward,&quot; which drops the leading zero. The &lt;code&gt;startswith()&lt;/code&gt; method asks a question about the text, and the answer comes back as a boolean. We will meet booleans shortly.&lt;/p&gt;
&lt;p&gt;A string that looks like a number is still a string. &lt;code&gt;&quot;14&quot;&lt;/code&gt; and &lt;code&gt;14&lt;/code&gt; are different things, and Python refuses to mix them:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(&quot;Seats: &quot; + 14)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Traceback (most recent call last):
  File &quot;matatu.py&quot;, line 1, in &amp;lt;module&amp;gt;
    print(&quot;Seats: &quot; + 14)
          ~~~~~~~~~~^~~~
TypeError: can only concatenate str (not &quot;int&quot;) to str
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You have to convert the number first. We cover that in a moment.&lt;/p&gt;
&lt;h4 id=&quot;integers-int-&quot;&gt;Integers (&lt;code&gt;int&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;An integer is a whole number. Python has three division-related operators, and beginners mix them up:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;riders = 47

print(riders // 14)
print(riders % 14)
print(2 ** 10)
print(7 / 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;3
5
1024
3.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;//&lt;/code&gt; operator divides and drops the remainder. A 14-seater carrying 47 riders in a day needs 3 full loads. The &lt;code&gt;%&lt;/code&gt; operator keeps only the remainder: 5 riders are left for a fourth, partly empty trip. Together they answer &quot;how many full loads, and what is left?&quot;, a question that turns up all the time. The &lt;code&gt;**&lt;/code&gt; operator raises a number to a power. The single &lt;code&gt;/&lt;/code&gt; always returns a float, even when the answer is whole:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(type(8 / 2), 8 / 2)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;class 'float'&amp;gt; 4.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;floats-float-&quot;&gt;Floats (&lt;code&gt;float&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;A float is a number with a decimal point. Fuel is measured in litres and priced to the cent, so floats fit. Mixing an integer with a float gives a float:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(3 * 1.5)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;4.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Floats have one quirk that startles everyone once:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(0.1 + 0.2)
print(round(0.1 + 0.2, 2))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;0.30000000000000004
0.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Computers store numbers in binary. One tenth has no exact binary form, just as one third has no exact decimal form, so the machine stores a very close neighbour. The error is tiny, and it appears when you print raw results. Two habits protect you. Use &lt;code&gt;round()&lt;/code&gt; or a format specifier when you display a float, and never test two floats for exact equality.&lt;/p&gt;
&lt;h4 id=&quot;booleans-bool-&quot;&gt;Booleans (&lt;code&gt;bool&lt;/code&gt;)&lt;/h4&gt;
&lt;p&gt;A boolean is &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;, with a capital first letter. You will seldom type them yourself. Comparisons produce them:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;boarded = 14
is_full = boarded &amp;gt;= seats
traffic_heavy = False

print(is_full)
print(is_full and not traffic_heavy)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;True
True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The keywords &lt;code&gt;and&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt; and &lt;code&gt;not&lt;/code&gt; combine booleans. The expression &lt;code&gt;is_full and not traffic_heavy&lt;/code&gt; asks: is the vehicle full, and is the road clear? Both hold, so the answer is &lt;code&gt;True&lt;/code&gt;. Set &lt;code&gt;traffic_heavy&lt;/code&gt; to &lt;code&gt;True&lt;/code&gt; and the answer flips to &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;converting-between-types&quot;&gt;Converting between types&lt;/h3&gt;
&lt;p&gt;Python will not guess when you mix types, so you convert on purpose with &lt;code&gt;int()&lt;/code&gt;, &lt;code&gt;float()&lt;/code&gt;, &lt;code&gt;str()&lt;/code&gt; and &lt;code&gt;bool()&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(int(&quot;120&quot;) + 30)
print(float(&quot;38.5&quot;) * 2)
print(str(14) + &quot; seats&quot;)
print(int(9.99))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;150
77.0
14 seats
9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that &lt;code&gt;int(9.99)&lt;/code&gt; gives 9. Converting to an integer cuts off the decimals. It does not round.&lt;/p&gt;
&lt;p&gt;Converting to a boolean has a trap:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(bool(0), bool(1), bool(&quot;&quot;), bool(&quot;no&quot;))
print(bool(&quot;False&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;False True False True
True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;bool()&lt;/code&gt; asks one question: is there anything here? Zero and the empty string count as nothing, so they become &lt;code&gt;False&lt;/code&gt;. Everything else becomes &lt;code&gt;True&lt;/code&gt;, including the text &lt;code&gt;&quot;False&quot;&lt;/code&gt;, which is a non-empty string. If you read the word &quot;false&quot; from a user, compare it with the text yourself. Do not pass it to &lt;code&gt;bool()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;input-and-output&quot;&gt;Input and output&lt;/h3&gt;
&lt;p&gt;Python talks through &lt;code&gt;print()&lt;/code&gt; and listens through &lt;code&gt;input()&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;output-with-print-&quot;&gt;Output with &lt;code&gt;print()&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;print()&lt;/code&gt; takes several values and puts a space between them. Two options change that: &lt;code&gt;sep&lt;/code&gt; sets the separator, and &lt;code&gt;end&lt;/code&gt; sets what closes the line (a newline by default).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;print(&quot;Nairobi&quot;, &quot;Thika&quot;, &quot;Kenol&quot;, sep=&quot; &amp;gt; &quot;)
print(&quot;Counting heads...&quot;, end=&quot; &quot;)
print(&quot;done&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Nairobi &amp;gt; Thika &amp;gt; Kenol
Counting heads... done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For anything longer, use an f-string. Put an &lt;code&gt;f&lt;/code&gt; before the opening quote and write expressions inside curly braces. After a colon you control the format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;fuel_cost = 5.5 * 190
print(f&quot;{sacco} spent KSh {fuel_cost:.2f} on fuel&quot;)
print(f&quot;KSh {1234567.891:,.2f}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Mwananchi Express spent KSh 1045.00 on fuel
KSh 1,234,567.89
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;.2f&lt;/code&gt; means &quot;two digits after the decimal point,&quot; and the comma adds thousands separators. F-strings also fix the &lt;code&gt;&quot;Seats: &quot; + 14&lt;/code&gt; problem, because they convert values to text for you.&lt;/p&gt;
&lt;h4 id=&quot;input-with-input-&quot;&gt;Input with &lt;code&gt;input()&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;input()&lt;/code&gt; shows a prompt, waits for the user to type and press Enter, then hands you what they typed. In the transcripts below, the text after each prompt is what the user typed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;name = input(&quot;Conductor name: &quot;)
print(&quot;Karibu,&quot;, name)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Conductor name: Maxwell
Karibu, Maxwell
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember this rule: &lt;code&gt;input()&lt;/code&gt; always returns a string. If the user types &lt;code&gt;3&lt;/code&gt;, you receive the text &lt;code&gt;&quot;3&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;passengers = input(&quot;Passengers: &quot;)
print(passengers + 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Passengers: 3
Traceback (most recent call last):
  File &quot;matatu.py&quot;, line 2, in &amp;lt;module&amp;gt;
    print(passengers + 1)
          ~~~~~~~~~~~^~~
TypeError: can only concatenate str (not &quot;int&quot;) to str
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The fix is to convert the moment the value arrives: &lt;code&gt;passengers = int(input(&quot;Passengers: &quot;))&lt;/code&gt;. If the user types something that is not a number, &lt;code&gt;int()&lt;/code&gt; raises a &lt;code&gt;ValueError&lt;/code&gt;. Handling that needs &lt;code&gt;try&lt;/code&gt; and &lt;code&gt;except&lt;/code&gt;, which sit outside this article. For now, know that it can happen.&lt;/p&gt;
&lt;h3 id=&quot;syntax-rules-that-hold-it-together&quot;&gt;Syntax rules that hold it together&lt;/h3&gt;
&lt;p&gt;Python's syntax is small. Five rules cover most of what you will write this month.&lt;/p&gt;
&lt;p&gt;Indentation is part of the language. Where other languages use braces, Python uses the four spaces at the start of a line to show what belongs inside an &lt;code&gt;if&lt;/code&gt;. Leave them out and Python stops you:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;seats = 14
if seats &amp;gt; 10:
print(&quot;big&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;  File &quot;matatu.py&quot;, line 3
    print(&quot;big&quot;)
    ^
IndentationError: expected an indented block after 'if' statement on line 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A colon ends the line that opens a block (&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;elif&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;). Comments start with &lt;code&gt;#&lt;/code&gt;, and Python ignores them, so use them to explain why you did something. A line break ends a statement, so you need no semicolons. And names are case sensitive, as you saw with &lt;code&gt;Seats&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;if&lt;/code&gt; statement is the one piece of flow control we need. It runs a block only when a boolean is &lt;code&gt;True&lt;/code&gt;. The second and third projects below use it.&lt;/p&gt;
&lt;h3 id=&quot;practical-example-1-the-conductor-s-change-counter&quot;&gt;Practical example 1: the conductor's change counter&lt;/h3&gt;
&lt;p&gt;A passenger owes KSh 70 and hands over a KSh 500 note. The conductor must return the right change, fast, and sometimes the passenger has paid too little. This program uses integers, division, a boolean and an &lt;code&gt;if&lt;/code&gt; statement.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# change_counter.py
fare_kes = int(input(&quot;Fare (KSh): &quot;))
paid_kes = int(input(&quot;Passenger paid (KSh): &quot;))

enough = paid_kes &amp;gt;= fare_kes

if enough:
    change = paid_kes - fare_kes
    hundreds = change // 100
    small_change = change % 100
    print(f&quot;Change due: KSh {change}&quot;)
    print(f&quot;Give back: {hundreds} x KSh 100, plus KSh {small_change} in smaller notes or coins&quot;)
else:
    print(f&quot;Short by KSh {fare_kes - paid_kes}. Ask for the rest.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Two runs, one where the passenger overpays and one where they come up short:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$ python change_counter.py
Fare (KSh): 70
Passenger paid (KSh): 500
Change due: KSh 430
Give back: 4 x KSh 100, plus KSh 30 in smaller notes or coins

$ python change_counter.py
Fare (KSh): 70
Passenger paid (KSh): 50
Short by KSh 20. Ask for the rest.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Follow the arithmetic: 500 minus 70 is 430. Then 430 // 100 is 4, the number of hundred-shilling notes, and 430 % 100 is 30, what remains. The same &lt;code&gt;//&lt;/code&gt; and &lt;code&gt;%&lt;/code&gt; pair that counted full loads now counts notes.&lt;/p&gt;
&lt;h3 id=&quot;practical-example-2-the-trip-profit-calculator&quot;&gt;Practical example 2: the trip profit calculator&lt;/h3&gt;
&lt;p&gt;At the end of a trip, the owner wants to know whether the trip paid for itself. Income is the passenger count times the fare. Costs are the fuel and a flat sacco fee. This program mixes integers and floats and ends on a boolean.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# trip_profit.py
FARE_KES = 100
SACCO_FEE_KES = 150

passengers = int(input(&quot;Passengers on this trip: &quot;))
fuel_litres = float(input(&quot;Fuel used (litres): &quot;))
price_per_litre = float(input(&quot;Fuel price (KSh per litre): &quot;))

income = passengers * FARE_KES
fuel_cost = fuel_litres * price_per_litre
profit = income - fuel_cost - SACCO_FEE_KES
made_profit = profit &amp;gt; 0

print()
print(f&quot;Income:    KSh {income:,.2f}&quot;)
print(f&quot;Fuel:      KSh {fuel_cost:,.2f}&quot;)
print(f&quot;Sacco fee: KSh {SACCO_FEE_KES:,.2f}&quot;)
print(f&quot;Profit:    KSh {profit:,.2f}&quot;)
print(&quot;Trip paid for itself?&quot;, made_profit)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A full vehicle on one run, and a half-empty one on another:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$ python trip_profit.py
Passengers on this trip: 14
Fuel used (litres): 5.5
Fuel price (KSh per litre): 190

Income:    KSh 1,400.00
Fuel:      KSh 1,045.00
Sacco fee: KSh 150.00
Profit:    KSh 205.00
Trip paid for itself? True

$ python trip_profit.py
Passengers on this trip: 9
Fuel used (litres): 5.5
Fuel price (KSh per litre): 190

Income:    KSh 900.00
Fuel:      KSh 1,045.00
Sacco fee: KSh 150.00
Profit:    KSh -295.00
Trip paid for itself? False
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The numbers show why conductors hate leaving half empty. Five fewer passengers turn a KSh 205 profit into a KSh 295 loss. Look at the types: &lt;code&gt;passengers&lt;/code&gt; is an integer, &lt;code&gt;fuel_litres&lt;/code&gt; is a float, and multiplying the integer by the integer constant gives an integer, while any product with a float gives a float. The &lt;code&gt;:,.2f&lt;/code&gt; format makes every amount line up with two decimals and a thousands separator.&lt;/p&gt;
&lt;h3 id=&quot;practical-example-3-the-departure-call&quot;&gt;Practical example 3: the departure call&lt;/h3&gt;
&lt;p&gt;The hardest decision on the route is when to go. Leave too early and you lose fares. Wait too long and passengers get off. This program takes the number of people on board and the minutes spent waiting, turns them into three booleans, and decides.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# departure.py
SEATS = 14

boarded = int(input(&quot;Passengers on board: &quot;))
minutes_waiting = int(input(&quot;Minutes waiting: &quot;))

is_full = boarded &amp;gt;= SEATS
waited_long = minutes_waiting &amp;gt;= 20
half_full = boarded &amp;gt;= SEATS / 2

if is_full:
    print(&quot;Decision: full. Close the door and go.&quot;)
elif waited_long and half_full:
    print(&quot;Decision: enough people and enough waiting. Leave now.&quot;)
elif waited_long:
    print(&quot;Decision: long wait, few riders. Keep calling, but tell them the delay.&quot;)
else:
    print(&quot;Decision: keep calling for passengers.&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Four situations, four decisions:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$ python departure.py
Passengers on board: 14
Minutes waiting: 5
Decision: full. Close the door and go.

$ python departure.py
Passengers on board: 9
Minutes waiting: 25
Decision: enough people and enough waiting. Leave now.

$ python departure.py
Passengers on board: 4
Minutes waiting: 30
Decision: long wait, few riders. Keep calling, but tell them the delay.

$ python departure.py
Passengers on board: 6
Minutes waiting: 8
Decision: keep calling for passengers.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python checks the &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;elif&lt;/code&gt; lines from top to bottom and runs only the first block whose condition is true. That is why the full vehicle leaves even after five minutes: &lt;code&gt;is_full&lt;/code&gt; is checked first. Notice that &lt;code&gt;SEATS / 2&lt;/code&gt; is a float (7.0), and comparing an integer with a float works without any conversion.&lt;/p&gt;
&lt;h3 id=&quot;try-it-yourself&quot;&gt;Try it yourself&lt;/h3&gt;
&lt;p&gt;You now have every piece for tools like these. Pick one and bend it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extend the change counter to hand back KSh 50 notes as well as KSh 100 notes, using another &lt;code&gt;//&lt;/code&gt; and &lt;code&gt;%&lt;/code&gt; step.&lt;/li&gt;
&lt;li&gt;Change the profit calculator to ask for the fare, so it works for a route that charges KSh 60 or KSh 150.&lt;/li&gt;
&lt;li&gt;Add a fourth rule to the departure call: if the road is blocked, tell the passengers and stop counting.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Then pick a small problem from your own week. Splitting a shopping bill, converting shillings to dollars and tracking your data bundle all follow the same steps: ask for input, convert it, calculate, and print the answer. Each program you finish teaches you more than another hour of reading. &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/29960/python-basics-in-the-matatu-context</guid>
<pubDate>Tue, 06 Oct 2026 09:19:50 +0000</pubDate>
</item>
</channel>
</rss>