Shanraq.org Shanraq.org
Daulet Baimurza

Daulet Baimurza

✦ Shanraq.org team

Project author & leadership

Founder of Shanraq.org. I distinguish between economy and greed—Aristotle called the latter "chrematistics." From this distinction, in my opinion, grows almost everything else: both the structure of the world and our view of it.

60Articles
1 307views
35Rating
2Rubrics
IT 58Society 2
Society

Free Python course for beginners: 57 lessons and a real-data project

Shanraq’s open course teaches Python through one continuous project. Learners collect data from official sources, validate and analyse it, then turn their work into a reproducible report. Here is who the 57 lessons are for, how the learning path works, and why money is a subject to investigate rather than a conclusion supplied in advance.

IT

Type annotations and mypy: fail before running

Lesson fifty-three of the Python course. Describe data shapes in signatures, narrow `None` with a check, and run `mypy` so incompatible values are found before the program executes.

IT

Finale: verify, publish, and reproduce

Lesson fifty-five and the end of the introductory Python course. Combine checks into one gate, build an immutable report directory, publish only after success, and expose verifiable source and build information to the reader.

IT

pytest tests: verify the pipeline's promises

Lesson fifty-two of the Python course. Turn project rules into automated tests: check the normal case, boundaries, and expected failures, then run the whole suite with one command.

IT

What a model cannot be trusted with: fact, inference, cause

Lesson fifty-one of the Python course. Separate an observation, a computed result, and a causal explanation. Code can verify a value and reproduce a calculation, but plausible causal prose remains a hypothesis until it has independent evidence and human review.

IT

A model on our data: verify every number

Lesson fifty of the Python course. Give the model a small table with stable source identifiers, accept structured claims, and compare every number with its source row. The model proposes wording; our code inserts the verified value, unit, and year into the final text.

IT

A structured response: model JSON and validation

Lesson forty-nine of the Python course. Ask the model for JSON governed by a schema instead of free-form prose, parse it with the standard `json` module, and validate it with `jsonschema`. Three separate gates—syntax, structure, and facts—keep a plausible-looking error out of the report.

IT

A prompt as code: parameters and reproducibility

Lesson forty-eight of the Python course. Stop composing a model request as one disposable line: separate role, task, data, and constraints; pin temperature, seed, and an output limit; then store the whole request beside its result. An identical request becomes a repeatable experiment, not a promise of byte-for-byte identical prose.

IT

A language model on your own computer: Ollama and the first local request

Lesson forty-seven of the Python course. Install Ollama, get a first answer without an API key, and follow the whole request: the program sends JSON to localhost, checks the HTTP response, and only then takes the model's text. The data stays on your computer unless you expose the local port yourself.

IT

Where a model ends

The forty-sixth lesson of the Python course and the end of the module on models. The same line promises an index of 146,206 for the year 2100 and minus a thousand for 1800 — and marks neither answer as doubtful. The border has to be written by hand: what it learned on, where it was checked, past which year it no longer holds.

IT

Classification and the confusion matrix

The forty-fifth lesson of the Python course. The model answers yes or no: will next year's inflation be above ten per cent. Accuracy of 0.75 against 0.675 for a model that always says no — and the confusion matrix shows that twenty of the twenty-six high years were missed along the way.

IT

Training and checking: why a model cannot mark its own work

The forty-fourth lesson of the Python course. The same model on the same data: an error of 2.48 points on the years it was taught, and 35.99 on the years it never saw. A random cut instead of a cut by time shows 5.37 and lies. A fifth-degree polynomial learns almost perfectly and is three times worse than a line.

IT

The first model: linear regression

The forty-third lesson of the Python course. A line drawn through sixteen years of prices gives an R² of 0.927 and loses to the rule "same as last year" — by a hundredth of a point. Its error is not random but has a shape: plus, minus, plus. A line in logarithms is wrong by half as much, because prices multiply.

IT

What comes from outside and what is ours: one shock, many prices

The forty-second lesson of the Python course. In 2022 world food rose by 14.9 % — the same for everybody. Inflation among ten neighbours came out between 8.6 and 72.3 %, a difference of eight times. The two usual culprits, the rate and money, are tested with a link — and one country moves the answer, while for money it flips the sign.

IT

How to read official statistics

The forty-first lesson of the Python course. One row of an official table carries five different numbers about the same prices, and all five are right. Which question each of them answers, how to recover the weights of the official basket that the release does not print, and why the World Bank ends up with a different figure than the news.

IT

Where money comes from: cash, deposits, credit

The fortieth lesson of the Python course. Of all the money in the country the National Bank printed nine per cent; the other ninety-one are records in bank accounts that appeared at the moment a bank made a loan. The aggregates as a matryoshka, money per tenge of GDP, the money multiplier — and what the law says about all of it.

IT

Your own inflation: your basket against the official one

The thirty-ninth lesson of the Python course. "Inflation is 8 %, but everything doubled for me" — both sentences can be true at once, and what tells them apart is weights. The basket, each item's share of the spending, its contribution to the growth — and why a simple mean over items promises 84.6 % where the basket grew by 69.8 %.

IT

Inflation as a multiplier: what a tenge was worth

Lesson thirty-eight of the Python course. Add up ten yearly rates and you get 92.98 % — and that is the wrong answer: prices grew by 141.98 %, because percentages multiply. The index through `cumprod`, the multiplier, the average yearly rate, and a thousand tenge of 2014 with 413 of them left by 2024.

IT

The mean, the median and the spread: when the mean lies

Lesson thirty-seven of the Python course, and the start of the module about money. Ten countries, one year: the mean is 20.48 %, the median 13.88 % — and the mean is higher than what eight of the ten actually had. `mean`, `median`, `std`, the quarters, and the rule that picks a measure before anyone has seen the result.

IT

A digest that updates itself: the whole pipeline

The thirty-sixth lesson of the Python course and the end of the module on reports. Four steps in one `main()`, a write through a temporary file, a repeat with no consequences and an exit code; the exercise adds `--dry-run`. And the rule it was all for: a source that fell over leaves yesterday's report rather than erasing it.

IT

Numbers in a report: formats, rounding and units

The thirty-fifth lesson of the Python course. `1234567.891` and `1 234 567,89` are one number and two different reports. Format strings, the local separators, the `round` that goes to the even one, `Decimal` for money, and the sum of rounded rows that does not equal the rounded sum.

IT

The report as a page: a table, a picture and a source in one file

The thirty-fourth lesson of the Python course. HTML built out of data: a template instead of glued strings, `html.escape` for everything that came from the table, the picture inside the file — and a page that checks itself. One file that opens in any browser, prints to PDF and travels as a single attachment.

IT

How not to lie with a chart: the scale, the zero and the labels

The thirty-third lesson of the Python course. The same two numbers: from zero the bar is 1.31 times taller, with the axis starting at eight it is 4.86. The same segment of a line: 14 degrees on a wide sheet and 73 on a narrow one. Per cent against percentage points, the choice of window — and a chart that checks itself.

IT

matplotlib: the first chart, and a file rather than a window

The thirty-second lesson of the Python course. We draw the series from the last lesson: a sheet and axes, a line, labels, a grid, a legend — and save it to a file without a single window opening. Plus the three things that break a chart for everybody: `Agg`, the order of drawing before saving, and a figure nobody closed.

IT

Time in a table: resampling, rolling means and honesty

The thirty-first lesson of the Python course. An index of dates can do what a list cannot: `asfreq` shows the days that are not there, `resample` folds days into weeks, `rolling` smooths. And the measured price of smoothing: the range halves, and the day of the real peak disappears from the series.

IT

The module's vocabulary: eight words a table speaks in

Not a lesson but a reference page, standing in front of the heavy part of the pandas module. Eight words — a table, a column, a label and a position, a mask, a missing value, a key, a type and a shape — on one table of three rows. Read it once now and come back when a word turns up in a lesson.

IT

Dirty data: gaps, duplicates and types

The thirtieth lesson of the Python course. Data arrives broken: numbers as text, a city spelled three ways, a duplicate row and an empty cell. `isna`, `to_numeric` with `errors="coerce"`, `astype`, `drop_duplicates` — and the question the lesson turns on: drop a gap or fill it, and what filling it costs.

IT

Joining tables: gluing two sources on a key

The twenty-ninth lesson of the Python course. `merge` joins two tables on a key — and by default throws away, in silence, every row that found no match. `inner` and `left`, `indicator`, keys with different names, `join` by label, and the duplicated key that multiplies rows and the sums along with them.

IT

Grouping and aggregates: counting by category and by month

The twenty-eighth lesson of the Python course. `groupby` is a loop written as a question: cut the table by a key, count each piece, put the pieces back. `agg` with column names of your own, two keys, a key the table does not hold, `transform` for a share, the difference between `count` and `size`, and the groups that go missing without a word.

IT

Selecting and filtering: keeping only what is needed

The twenty-seventh lesson of the Python course. A mask is a column of yes and no, and a whole table is filtered with one. `df[mask]`, `.loc[mask, columns]`, `&`, `|`, `~` and the brackets that are not decoration, `isin`, `between`, `str` — and the labels a filter leaves exactly as they were, which is where `loc` and `iloc` finally part company.

IT

Reading and writing: CSV, JSON and SQL in one line

The twenty-sixth lesson of the Python course. Somebody else's file means a separator, a comma inside the decimals, a BOM and its own mark for a missing value; in a loop you have to remember every one of them, and in `read_csv` they are arguments. `read_csv`, `to_csv`, `read_sql` and `to_sql` — and what a file does not remember about a table.

IT

DataFrame and Series: labels instead of numbers

The twenty-fifth lesson of the Python course. A table whose rows carry labels does not answer the way a list does: `loc` takes by label, `iloc` by number, and two series are added by year rather than by position. `DataFrame` and `Series`, the index, slices whose ends differ, and the `NaN` that appears on its own.

IT

Why pandas, when lists already work: what the measurement showed

The twenty-fourth lesson of the Python course. The pandas module opens with the question it ought to open with: is the library worth it. A measurement answers, not belief. Where pandas is forty times faster, where it is merely twice, where it loses to an ordinary loop, what the memory costs — and the rule for when a table is needed.

IT

On a schedule: arguments, a journal, a lock and an exit code

The twenty-third lesson of the Python course. A program that works through the night without you: arguments instead of editing the source, a journal with levels instead of `print`, a lock against two runs at once, and the exit code — the one thing the scheduler actually reads. Plus cron, launchd and systemd.

IT

SQL from Python: `GROUP BY`, `JOIN`, and an empty answer that is not zero

The twenty-second lesson of the Python course. The database does the counting: `GROUP BY` gives one row per currency, `JOIN` brings the names from a second table, and a month is a group made of the first seven characters of the date. Plus the trap: over an empty answer `avg` returns `None` rather than zero.

IT

SQLite: a history instead of an overwritten file, a `?` instead of gluing

The twenty-first lesson of the Python course. A database instead of a file: a row is added, yesterday's stay, and running the same day again makes no duplicates. Plus two measured traps: a value glued into a query returned the whole table instead of one currency, and closing without a `commit` lost the row.

IT

Politeness to somebody else's server: a timeout, a backoff and a cache

The twentieth lesson of the Python course. Politeness to somebody else's server is three concrete things: a timeout, so you do not wait for ever; a retry with the pause doubling, so you do not hit what is already down; and a cache, so you do not ask twice. Measured on a server of our own: four readings, one request.

IT

HTTP from Python: the status, the bytes, and two different failures

The eighteenth lesson of the Python course. A request to the National Bank: 200, `text/xml`, 11,407 bytes — and those are `bytes`, not a string. Plus the difference that breaks error handling: `HTTPError` means the server said no, `URLError` means there was no answer at all.

IT

Iterators and generators: 800,984 bytes against 208

The sixteenth lesson of the Python course. A hundred thousand squares take almost four megabytes as a list and 376 bytes as a generator — measured, with every number counted in. The difference is not in how you count them but in when the values appear. Plus the mistake that matters: a generator is good for one pass, and the second one quietly gives you nothing.

IT

Sets: `&`, `-`, `|`, and what the second export does not have

The fifteenth lesson of the Python course. Of the five names in the list only four are different: a set swallows the repeat without a word. In exchange, three questions about two exports take three signs: `&` for what is in both, `-` for what is gone, `|` for all of it. Plus `{}` is an empty dictionary, not an empty set.

IT

Dates and time: 45 days, a timezone, and a format that reads two ways

The fourteenth lesson of the Python course. There are 45 days between the 15th of January and the 1st of March, and `timedelta` counts them, not you. Plus two traps: `01.02.2026` parses under two formats without an error — as January and as February — and a naive time cannot be taken from an aware one, which Python says outright.

IT

JSON: the API answer we took on trust in the first lesson

The thirteenth lesson of the Python course. The World Bank's answer is a list of two elements: a service part and the records. We take it apart by hand and find what spoils a calculation silently: `null` becomes `None`, and numeric keys come back from a round trip through JSON as strings — `2025` goes out, `"2025"` comes in.

IT

CSV: a comma inside a field, and the mark Excel leaves

The twelfth lesson of the Python course. On the row `2022,15.0,"shock, war, logistics"`, `split(",")` returns five pieces instead of three — measured. The csv module returns three. Plus `DictReader`, the required `newline=""`, and Excel's mark, which makes `row["year"]` answer `KeyError` while the column is right there.

IT

Files and pathlib: a path that does not break on somebody else's machine

The eleventh lesson of the Python course. The program writes its data, reads it line by line and puts the report beside it. The path is built by `Path` rather than by gluing strings: on Windows the same path is written with a backslash. And the encoding is always named — leave it out and the system chooses it for you.

IT

Errors and exceptions: no file, or rubbish inside it

The tenth lesson of the Python course. Three of five rows from somebody else's export made it through: a comma is a full stop, while "no data" and an empty string are not numbers. `try/except/else/finally`, an error name of your own in one line, and the skill that matters — reading a traceback from its last line upwards.

IT

Functions: a name for a calculation, and an assert that catches a wrong number

The ninth lesson of the Python course. The walk over a series gets a name and works on any series: Kazakhstan at 11.52%, the world at 4.68%. Plus an `assert` that stops the calculation on an empty series, the `lambda` in `sorted(key=)`, and a measured trap: `into=[]` in a header keeps its values between calls.

IT

Loops: for, range, and what zip does silently

The eighth lesson of the Python course. One comparison instead of thirty: a loop walks the series itself, `continue` steps over the year with no data, an accumulator gives the average — 11.52% across five years. Plus two traps: `zip` silently cuts to the shorter series, and a `while` without a way out walks off the edge.

IT

Conditions: if, elif, else — and the number that is not there

The seventh lesson of the Python course. A number on its own says nothing: is 11.4% a lot or a little? A condition compares, and the comparison picks the road. Measured on inflation: Kazakhstan at 11.4% in 2025, the world at 3.0%. Plus the first rule of working with data: a gap in a series is not a zero, and `is None` is how you ask.

IT

Putting the blog where people can reach it: free hosting

The forty-sixth lesson of the Go course. A host decides three things for you: the port arrives in PORT, the service has to listen on every address rather than on itself, and the disk of a free plan is wiped on every deploy — measured: the same password gives 303 before and 401 after. Plus a build into one static file.

IT

A dictionary: a link instead of hoping the order holds

The sixth lesson of the Python course. Prices by name: `get` instead of an error, `in` instead of a search, `items()` as a ready table. Measured: reaching for a missing key is a `KeyError` rather than emptiness; Counter tallies a basket in one line, and defaultdict supplies the zero where an ordinary dictionary fails.

IT

A list and a tuple: a receipt that counts itself

The fifth lesson of the Python course. Prices in a list: indexes, slices, changes, the sum and the maximum — without a single loop. The difference everybody trips over is measured: sorted() returns a new list, .sort() changes the original and returns None. And a tuple that refuses to change: TypeError.

IT

Variables and types: why "260" and 260 are different things

The fourth lesson of the Python course. Data from somebody else's file arrives as text, and until the text becomes a number, adding it makes no sense: "260" + "260" gives 260260. The money rule is measured too: 0.1 + 0.2 is not 0.3, while Decimal is. Plus None, the truth of "0", and the difference between == and is.

Society

A second free course: Python for data and AI

The site's second free course — 55 lessons, from data to a digest that updates itself. Why Python, why data and AI rather than the web, and what the reader will actually count: prices up 3.48 times, and what cost a thousand tenge now costs 3481. No account, no payment, in three languages.

IT

The first program: numbers, strings and output

The third lesson of the Python course. We count on a shop receipt: two divisions instead of one, the remainder, a power, and then strings — trim, replace, cut, glue. And f-strings, which put a number inside text: 52,751,740,084,727 tenge with separators and 11.4% to one decimal place.

IT

A workplace: Python, the project's environment and the first run

The second lesson of the Python course. We install the language, create the project's environment and move yesterday's program into it. Measured: a package installed into the environment is invisible outside it — `ModuleNotFoundError` — which is exactly what an environment is for. The `.venv` folder weighs 17 MB and never goes into the repository.

IT

Counting for yourself: prices, the tenge and one question

The first lesson of the Python course. No libraries have to be installed: a ready program fetches the official numbers itself. Prices in Kazakhstan are 3.48 times higher than in 2010: what cost a thousand tenge now costs 3481. And after the same shock inflation in other countries of the region is three times lower, which is the first reason to count for yourself.

IT

Where to go next: generics and the road after the course

The fiftieth and last lesson of the Go course. Generics are one function instead of three, and the condition on the type is checked by the compiler: measured, a `string` does not get through before the program runs. Measured too is what they gain over `any`: 534 nanoseconds against 1801. Plus where to go from here.