Skip to learning content

DATA SCIENCE PYTHON PLAYGROUND

Data Foundations

← All challenges
WC02 · Café / orders · ~10–15 min

Prices that can be used

numeric quality · eligibility · provenance

Usable & repair lists

The question

Separate usable café prices from records that need repair, retaining the original text as evidence.

df Usable & repair lists

Your inputs

df

Prices use dollars. Missing, empty and unparseable prices need repair; they do not mean zero.

Field meanings and units
order_id
Order or order-line identifier, as defined by this brief.
drink
Recorded drink label.
size
Recorded serving size.
price
Price in dollars; unparseable text needs the stated policy.
tip
Tip in dollars.
shift
AM or PM service period.
date
Calendar date supplied as YYYY-MM-DD text unless the task states it is invalid.
df · first 5 of 16 rows
order_iddrinksizepricetipshiftdate
C001" Latte "Small4.50AM2026-04-01
C002teaLarge2.81PM2026-04-01
C003LATTESmall4.50.5AM2026-04-02
C004" Mocha"LargeunknownNoneAM2026-04-02
C005" Latte "Small4.50PM2026-04-03
View all 16 rows
df · complete input
order_iddrinksizepricetipshiftdate
C001" Latte "Small4.50AM2026-04-01
C002teaLarge2.81PM2026-04-01
C003LATTESmall4.50.5AM2026-04-02
C004" Mocha"LargeunknownNoneAM2026-04-02
C005" Latte "Small4.50PM2026-04-03
C006teaLarge2.81AM2026-04-03
C007LATTESmall4.50.5AM2026-04-04
C008" Mocha"Large5.2NonePM2026-04-04
C009" Latte "Small0AM2026-04-05
C010teaLarge2.81AM2026-04-05
C011LATTESmall4.50.5PM2026-04-06
C012" Mocha"LargeNoneNoneAM2026-04-06
C013" Latte "Small4.50AM2026-04-07
C014teaLarge2.81PM2026-04-07
C015LATTESmall4.50.5AM2026-04-08
C016" Mocha"Large5.2NoneAM2026-04-08

The editable setup in Your Python creates these inputs when you run it.

Your task · Prices that can be used

Separate usable café prices from records that need repair, retaining the original text as evidence.

eligibleDataFrameinvalidDataFrame

Deliverables

Make the outputs listed below. Use each name exactly as shown. Then choose Check answer.

Python name key

Teal outlines name table columns. Violet left rules name Python objects. Dotted rules mark syntax, functions and parameters. Use each name exactly as shown.

Words in this task
numeric
a number, rather than text
missing
no value was supplied
eligible
rows that meet this task’s stated conditions
  1. Usable pricesOutputeligibleDataFrame
    1. Make a table named eligible.
    2. Keep every original column.
    3. Add a column named numeric_price.
    4. Put the price as a number in this column.
    5. Keep only rows where price can be read as a number.
    6. Keep the rows in their original order.
    7. Keep the original text in price.
    8. Do not replace it with the converted number.
  2. Repair queueOutputinvalidDataFrame
    1. Make a table named invalid.
    2. Use the same columns as eligible, including numeric_price.
    3. Keep rows where price is missing or cannot be read as a number.
    4. Missing means that no value was supplied.
    5. Keep the rows in their original order.
    6. Keep the original text in price in both output tables.

Data policy Keep all supplied source tables unchanged. Work on separate outputs.

Help Hints & explained solution

Choose the amount of help you need. Opening one hint does not reveal the others.

Hint 1 — Think

Can a parsed value replace the evidence needed to investigate failures?

Hint 2 — Tools

to_numeric(), isna(), notna() and copy()

Revisit: Convert numeric text · Protect the original · Find missing values

Hint 3 — Approach

Add parsed values alongside raw text, then separate usable and unusable prices without losing any source records.

Explained solution

Add these lines below # Your work in the editor. The supplied input setup is already there.

work = df.copy()
work['numeric_price'] = pd.to_numeric(work.price, errors='coerce')
eligible = work[work.numeric_price.notna()]
invalid = work[work.numeric_price.isna()]
eligible
View supplied setup

This code is already at the top of the editor.

import pandas as pd

# Supplied input: df (16 rows)
df = pd.DataFrame(
    [
        ('C001', ' Latte ', 'Small', '4.5', 0, 'AM', '2026-04-01'),
        ('C002', 'tea', 'Large', '2.8', 1, 'PM', '2026-04-01'),
        ('C003', 'LATTE', 'Small', '4.5', 0.5, 'AM', '2026-04-02'),
        ('C004', ' Mocha', 'Large', 'unknown', None, 'AM', '2026-04-02'),
        ('C005', ' Latte ', 'Small', '4.5', 0, 'PM', '2026-04-03'),
        ('C006', 'tea', 'Large', '2.8', 1, 'AM', '2026-04-03'),
        ('C007', 'LATTE', 'Small', '4.5', 0.5, 'AM', '2026-04-04'),
        ('C008', ' Mocha', 'Large', '5.2', None, 'PM', '2026-04-04'),
        ('C009', ' Latte ', 'Small', '', 0, 'AM', '2026-04-05'),
        ('C010', 'tea', 'Large', '2.8', 1, 'AM', '2026-04-05'),
        ('C011', 'LATTE', 'Small', '4.5', 0.5, 'PM', '2026-04-06'),
        ('C012', ' Mocha', 'Large', None, None, 'AM', '2026-04-06'),
        ('C013', ' Latte ', 'Small', '4.5', 0, 'AM', '2026-04-07'),
        ('C014', 'tea', 'Large', '2.8', 1, 'PM', '2026-04-07'),
        ('C015', 'LATTE', 'Small', '4.5', 0.5, 'AM', '2026-04-08'),
        ('C016', ' Mocha', 'Large', '5.2', None, 'AM', '2026-04-08'),
    ],
    columns=['order_id', 'drink', 'size', 'price', 'tip', 'shift', 'date'],
)

Why these steps exist

  • numeric_price is added beside the raw text so failed conversions can be investigated.
  • The two outputs partition the source: each order is either usable or needs repair, without losing records.

Another valid approach

Build a mask once and use it for both outputs, or select by missingness of numeric_price separately.

Tab: indent · Shift+Tab: outdent · Esc, then Tab: leave editor

Edit Python. Control or Command plus Enter runs it. Tab indents by four spaces. Shift plus Tab outdents. Press Escape, then Tab or Shift plus Tab to leave the editor.

Each run executes all editor code in a fresh Python session. Named outputs appear below when you run.

Python starts when you open a lesson.

Output

Run your code to see what Python returns.