-
Notifications
You must be signed in to change notification settings - Fork 8
Baraah A. #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Baraah A. #2
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| transaction_id,product_name,category,price,quantity,customer_email,date,revenue,vat | ||
| 1,Laptop Pro,Electronics,999.99,2,alice@example.com,2024-03-15,1999.98,420.0 | ||
| 2,Wireless Mouse,Electronics,29.99,5,bob@company.com,2024-03-15,149.95,31.49 | ||
| 3,Usb Cable,Electronics,4.99,10,,2024-03-16,49.9,10.48 | ||
| 4,Office Chair,Furniture,349.5,1,charlie@work.org,2024-03-16,349.5,73.39 | ||
| 5,Standing Desk,Furniture,599.0,1,charlie@work.org,not_a_date,599.0,125.79 | ||
| 9,Webcam Hd,Electronics,54.99,1,,2024-03-18,54.99,11.55 | ||
| 10,Desk Lamp,Furniture,34.99,4,grace@university.edu,2024-03-19,139.96,29.39 | ||
| 11,Noise Cancelling Headphones,Electronics,199.99,1,alice@example.com,2024-03-19,199.99,42.0 | ||
| 12,Cable Management Kit,Furniture,15.99,6,henry@business.com,2024-03-20,95.94,20.15 | ||
| 13,Ergonomic Mouse Pad,Furniture,24.99,3,ivan@email.com,2024-03-20,74.97,15.74 | ||
| 14,Laptop Stand,Furniture,45.99,2,jenny@work.org,2024-03-21,91.98,19.32 | ||
| 15,Bluetooth Speaker,Unknown,39.99,1,karl@startup.io,2024-03-21,39.99,8.4 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,14 +20,29 @@ | |
| # customer_email: str | ||
| # date: str | ||
| # revenue: float = 0.0 | ||
| # vat: float = 0.0 | ||
| # vat: float = 0.0 | ||
| # | ||
| # TODO 2: Add __post_init__ that raises ValueError when: | ||
| # - self.price < 0 (with a message naming the bad value) | ||
| # - not self.product_name.strip() (empty / whitespace-only product name) | ||
|
|
||
|
|
||
|
|
||
| # Replace this stub with your dataclass: | ||
| @dataclass | ||
| class Transaction: | ||
| transaction_id: int # TODO: replace this stub with the full field list above | ||
| product_name: str | ||
| category: str | ||
| price: float | ||
| quantity: int | ||
| customer_email: str | ||
| date: str | ||
| revenue: float = 0.0 | ||
| vat: float = 0.0 | ||
|
|
||
| def __post_init__(self): | ||
| if self.price < 0 : | ||
| return ValueError(f"Invalid price {self.price} the price can not be negative!") | ||
| if not self.product_name.strip(): | ||
| return ValueError("product name can not empty or has a whitespace!") | ||
|
Comment on lines
+45
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,9 +19,12 @@ def remove_invalid(rows: list[dict]) -> list[dict]: | |
| Empty here means missing, "", or whitespace-only. | ||
| """ | ||
| # TODO: implement. Return a new list, do not mutate `rows`. | ||
| raise NotImplementedError | ||
|
|
||
| return [ | ||
| row for row in rows | ||
| if str(row.get("product_name","")).strip() and float(row.get("price",0))>= 0 | ||
| ] | ||
|
|
||
|
|
||
| def clean_fields(rows: list[dict]) -> list[dict]: | ||
| """Clean string fields: | ||
|
|
||
|
|
@@ -32,7 +35,24 @@ def clean_fields(rows: list[dict]) -> list[dict]: | |
| Return a new list. Do not mutate the input rows. | ||
| """ | ||
| # TODO: implement. | ||
| raise NotImplementedError | ||
| cleaned =[] | ||
| for row in rows : | ||
| new_row = {**row, | ||
| "product_name": row.get("product_name", "").strip().title(), | ||
| "customer_email": row.get("customer_email", "").strip().lower(), | ||
| "category": row.get("category") or "Unknown", | ||
| } | ||
| cleaned.append(new_row) | ||
| return cleaned | ||
|
|
||
| def filter_zero_quantity(rows: list[dict]) -> list[dict]: | ||
| """Remove rows where quantity is 0.""" | ||
| # TODO: implement. | ||
| if rows is None: | ||
| return[] | ||
|
Comment on lines
+51
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| return [ | ||
| row for row in rows | ||
| if int(row.get("quantity", 0)) != 0 ] | ||
|
|
||
|
|
||
| def calculate_revenue(rows: list[dict], vat_rate: float = 0.21) -> list[dict]: | ||
|
|
@@ -41,10 +61,21 @@ def calculate_revenue(rows: list[dict], vat_rate: float = 0.21) -> list[dict]: | |
| Round both to 2 decimal places. Coerce price/quantity from string if needed. | ||
| """ | ||
| # TODO: implement. | ||
| raise NotImplementedError | ||
| result =[] | ||
| for row in rows : | ||
|
|
||
| price = float(row.get("price",0)) | ||
| quantity =int(row.get("quantity",0)) | ||
|
|
||
| revenue = round(price * quantity,2) | ||
| vat = round(revenue * vat_rate,2) | ||
|
|
||
| new_row = { **row, | ||
| "revenue" : revenue, | ||
| "vat" : vat } | ||
|
|
||
| result.append(new_row) | ||
| return result | ||
|
|
||
|
|
||
|
|
||
| def filter_zero_quantity(rows: list[dict]) -> list[dict]: | ||
| """Remove rows where quantity is 0.""" | ||
| # TODO: implement. | ||
| raise NotImplementedError | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| https://sthyfstudentsdemo.blob.core.windows.net/week2-thebaraah/clean_sales.csv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small edge case:
os.environ.get(name)returns""(empty string) for a set-but-empty variable, notNone. Your checkif value is Nonewould let an empty path through.Safer pattern would be: