Typorithm · easy

Series, DataFrame and a declared table schema

pythonpandasnumerical-computingindependent-practice
Saved on this device
Full lesson · 4 learning steps Open any exercise for focused practice
1

Step 1 of 4 · intro card

Series, DataFrame and a declared table schema

0%

Concept and contract

Build a table whose columns, nullable dtypes and row count are explicit.

A Series is one labelled column; a DataFrame relates columns through a shared row index. Neither object knows that a row represents a vacancy or that a numeric value means annual pay. Start with a small declared schema: role_id is text and score is a nullable floating-point measurement. The constructor's columns argument fixes presentation order, while astype establishes the intended representations. Shape describes rows and columns, not the number of distinct roles.

Keep this first boundary deliberately narrow. It verifies field names and representation, but does not yet prove that identifiers are unique, scores are finite or rows belong to the same reporting population. Those are separate contracts introduced later.

Mechanism and worked example

The worked function accepts a list of records with exactly role_id and score.

The worked function accepts a list of records with exactly role_id and score. It rejects missing or extra fields before constructing the table, then casts each column explicitly. Empty input still produces both named columns with their declared dtypes. A missing score remains missing in Float64; it is not silently converted into an observed zero. The returned object is a real DataFrame, rather than a list formatted to resemble one.

Trace two records and inspect columns, shape and dtypes independently. Selecting one named column yields a Series. Selecting a list of column names yields a DataFrame, even when that list contains only one name.

Complete worked example

python

import pandas as pd

def inspect_example(rows):
    if any(set(row) != {"role_id", "score"} for row in rows):
        raise ValueError("expected role_id and score fields")
    frame = pd.DataFrame(rows, columns=["role_id", "score"])
    return frame.astype({"role_id": "string", "score": "Float64"})
Reasoning
The worked function accepts a list of records with exactly role_id and score. It rejects missing or extra fields before constructing the table, then casts each column explicitly. Empty input still produces both named columns with their declared dtypes. A missing score remains missing in Float64; it is not silently converted into an observed zero. The returned object is a real DataFrame, rather than a list formatted to resemble one. Trace two records and inspect columns, shape and dtypes independently. Selecting one named column yields a Series. Selecting a list of column names yields a DataFrame, even when that list contains only one name.
Open in local Python playground ↗

Focused decision: context is in the complete example

python

import pandas as pd
frame = pd.DataFrame(rows, columns=["role_id", "score"])
frame = frame.astype({"role_id": "string", "score": "Float64"})
Focused decision
Type this short table decision after reading its complete context. The complete imports, table construction, validation, and result checks remain in the worked example. Typing records practice; only the downloadable computer lab executes Python.

Counterexamples and common mistakes

Inferring a schema from one successful sample is fragile.

Inferring a schema from one successful sample is fragile. An empty batch, all-missing column or newly introduced field can change inference without changing your business requirements. The controlled mistake returns records instead of a DataFrame. Printed output can look plausible, but downstream labelled operations and the lab's type checks detect the broken interface. Another common mistake is treating the default RangeIndex as a durable role identifier.

Pandas 3 infers a dedicated string dtype rather than assuming every text column is object. This course uses explicit nullable string and numeric dtypes where missing-value behavior matters, so exercises do not depend on display formatting or optional Arrow installation.

Controlled mistake: inspect the failing table contract

python

import pandas as pd

def inspect_example(rows):
    if any(set(row) != {"role_id", "score"} for row in rows):
        raise ValueError("expected role_id and score fields")
    frame = pd.DataFrame(rows, columns=["role_id", "score"])
    return frame.to_dict("records")
Reasoning
Inferring a schema from one successful sample is fragile. An empty batch, all-missing column or newly introduced field can change inference without changing your business requirements. The controlled mistake returns records instead of a DataFrame. Printed output can look plausible, but downstream labelled operations and the lab's type checks detect the broken interface. Another common mistake is treating the default RangeIndex as a durable role identifier. Pandas 3 infers a dedicated string dtype rather than assuming every text column is object. This course uses explicit nullable string and numeric dtypes where missing-value behavior matters, so exercises do not depend on display formatting or optional Arrow installation.
Open in local Python playground ↗

Independent practice

Change the table's presentation order to score followed by role_id.

Change the table's presentation order to score followed by role_id. Keep the same accepted field names, row order and values. Change only the constructor's declared column list; preserve the dtype mapping. This is a small first edit using an argument already explained in the worked example, rather than introducing a new transformation.

Before editing, write down the expected columns for a normal batch and an empty batch. The same contract must hold for both. Do not rename fields, sort rows or fill missing scores to make the output appear different. Those would introduce changes beyond the requested column order.

Step 1: Present score before role_id without changing values, row order or dtypes. Step 2: Retain the working imports, input validation and table schemas. Change the stated policy, run the supplied practice cases, then explain the newly accepted or rejected boundary.

Practice starter: solve before reading the solution

python

import pandas as pd

def inspect_example(rows):
    if any(set(row) != {"role_id", "score"} for row in rows):
        raise ValueError("expected role_id and score fields")
    frame = pd.DataFrame(rows, columns=["role_id", "score"])
    return frame.astype({"role_id": "string", "score": "Float64"})

# Independent task: Present score before role_id without changing values, row order or dtypes.
Reasoning
Present score before role_id without changing values, row order or dtypes.
Open in local Python playground ↗
  • Hint 1: Find the constructor columns argument.
  • Hint 2: Change its order, leaving the dtype dictionary intact.

Solution, tests and trade-offs

Acceptance compares the actual DataFrame type, ordered column names, per-column dtypes, row index and values.

Acceptance compares the actual DataFrame type, ordered column names, per-column dtypes, row index and values. Two tables with identical numbers but swapped columns are different outputs under this contract. Missing values are compared as missing values, rather than through equality with a particular printed sentinel. The original input records must remain unchanged after the call.

The solution changes one list of column names. The tests include an empty batch and a record with no score value, because those cases expose accidental inference. Extra and absent fields remain errors. This establishes a useful pattern: specify the smallest observable change, then verify that unrelated guarantees survive it.

Practice solution and acceptance checks

python

import pandas as pd

def inspect_example(rows):
    if any(set(row) != {"role_id", "score"} for row in rows):
        raise ValueError("expected role_id and score fields")
    frame = pd.DataFrame(rows, columns=["score", "role_id"])
    return frame.astype({"role_id": "string", "score": "Float64"})
Reasoning
Acceptance compares the actual DataFrame type, ordered column names, per-column dtypes, row index and values. Two tables with identical numbers but swapped columns are different outputs under this contract. Missing values are compared as missing values, rather than through equality with a particular printed sentinel. The original input records must remain unchanged after the call. The solution changes one list of column names. The tests include an empty batch and a record with no score value, because those cases expose accidental inference. Extra and absent fields remain errors. This establishes a useful pattern: specify the smallest observable change, then verify that unrelated guarantees survive it.
Open in local Python playground ↗

Interview reasoning and next step

For an interview, distinguish a Series, a DataFrame and an index using this two-column example.

For an interview, distinguish a Series, a DataFrame and an index using this two-column example. Explain why explicit dtypes and a stable empty result matter at an API boundary. State what this schema check does not establish: identity, finite measurements and source freshness are not implied by successful construction. Describe how you would test each added rule separately.

On the PC, type the short construction and cast, then recall the key constructor argument. In the app, answer the schema questions and read the complete code. The downloadable computer lab executes the function; the typing trainer records practice without pretending to run pandas.

Optional stretch — after the core task works: Add one independently reasoned boundary case and explain its expected value before running it.

Computer practice: https://applydjinn.com/typorithm/pandas-lab-20261106.zip. Install pinned dependencies in an isolated Python environment. Run verify.py, then change the working exercise baseline and run --practice pd-schema. The real pandas tables, exact schemas, unchanged inputs, CSV parser options and owned in-memory SQL reconciliation use owned fixtures only. No production database, feed, account or paid service is used. This lab executes Python; the PC typing trainer and native reading progress do not execute it.

Build a table whose columns, nullable dtypes and row count are explicit.