diff --git a/task-1/output/clean_users.json b/task-1/output/clean_users.json new file mode 100644 index 0000000..a9d38dc --- /dev/null +++ b/task-1/output/clean_users.json @@ -0,0 +1,86 @@ +[ + { + "id": 1, + "name": "Alice Johnson", + "email": "alice.johnson@company.com", + "department": "Engineering", + "salary": 85000 + }, + { + "id": 2, + "name": "Bob Smith", + "email": "bob.smith@company.com", + "department": "Unknown", + "salary": 72000 + }, + { + "id": 3, + "name": "Carol Williams", + "email": "carol.williams@company.com", + "department": "Engineering", + "salary": null + }, + { + "id": 4, + "name": "David, Jr.", + "email": "david.brown@company.com", + "department": "Sales", + "salary": 68000 + }, + { + "id": 5, + "name": "Caf\u00e9 Owner", + "email": "eva@company.com", + "department": "Engineering", + "salary": 88000 + }, + { + "id": 6, + "name": "FRANK WILSON", + "email": "frank@company.com", + "department": "marketing", + "salary": 95000 + }, + { + "id": 7, + "name": "Grace Lee", + "email": "grace.lee@company.com", + "department": "Engineering", + "salary": null + }, + { + "id": 9, + "name": "Henry Davis", + "email": "henry.davis@company.com", + "department": "Sales", + "salary": 82000 + }, + { + "id": 11, + "name": "Linda Taylor", + "email": "linda.t@company.com", + "department": "HR", + "salary": 55000 + }, + { + "id": 12, + "name": "Mike Brown", + "email": "mike.b@company.com", + "department": "Sales", + "salary": null + }, + { + "id": 13, + "name": "Sarah Connor", + "email": "s.connor@sky.net", + "department": "Unknown", + "salary": -1 + }, + { + "id": 15, + "name": "John Doe", + "email": "john.doe@company.net", + "department": "Engineering", + "salary": 100000 + } +] \ No newline at end of file diff --git a/task-1/src/__pycache__/utils.cpython-311.pyc b/task-1/src/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000..265952c Binary files /dev/null and b/task-1/src/__pycache__/utils.cpython-311.pyc differ diff --git a/task-1/src/__pycache__/utils.cpython-312.pyc b/task-1/src/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000..f993e81 Binary files /dev/null and b/task-1/src/__pycache__/utils.cpython-312.pyc differ diff --git a/task-1/src/utils.py b/task-1/src/utils.py index 2762398..c249c78 100644 --- a/task-1/src/utils.py +++ b/task-1/src/utils.py @@ -13,7 +13,9 @@ def clean_name(raw: str) -> str: Returns the cleaned string. An empty input returns "". """ - raise NotImplementedError("Implement clean_name (Task 1)") + name = raw.strip() + return name + def clean_email(raw: str) -> str: @@ -21,7 +23,8 @@ def clean_email(raw: str) -> str: Returns the cleaned string. An empty input returns "". """ - raise NotImplementedError("Implement clean_email (Task 1)") + email = raw.strip().lower() + return email def clean_department(raw: str) -> str: @@ -29,7 +32,10 @@ def clean_department(raw: str) -> str: Strip whitespace; treat empty string as missing. """ - raise NotImplementedError("Implement clean_department (Task 1)") + department =raw.strip() + if not department: + return "Unknown" + return department def clean_salary(raw: str) -> int | None: @@ -38,4 +44,8 @@ def clean_salary(raw: str) -> int | None: Handles inputs like "85000", " 95000", '"68,000"', "N/A", "". Returns None when the value cannot be parsed (missing or "N/A"). """ - raise NotImplementedError("Implement clean_salary (Task 1)") + try: + salary = raw.strip().replace(",","").replace('"',"") + return int(salary) + except ValueError: + return None diff --git a/task-2/AI_DEBUG.md b/task-2/AI_DEBUG.md index 413b94a..f17e5a1 100644 --- a/task-2/AI_DEBUG.md +++ b/task-2/AI_DEBUG.md @@ -11,19 +11,100 @@ Document one debugging session you had during Task 1 where you used an LLM +Traceback (most recent call last): + File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 58, in + main(args.input, args.output) + File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 46, in main + cleaned = [c for row in reader if (c := clean_row(row)) is not None] + ^^^^^^^^^^^^^^ + File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 38, in clean_row + "salary": clean_salary(row.get("salary", "")), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Beheerder\c55-data-week1\task-1\src\utils.py", line 49, in clean_salary + salary = int(raw.strip().replace(",","").replace('"',"")) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ValueError: invalid literal for int() with base 10: 'N/A' ## The Prompt +Traceback (most recent call last): +  File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 58, in +    main(args.input, args.output) +  File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 46, in main +    cleaned = [c for row in reader if (c := clean_row(row)) is not None] +                                            ^^^^^^^^^^^^^^ +  File "C:\Users\Beheerder\c55-data-week1\task-1\src\cleaner.py", line 38, in clean_row +    "salary": clean_salary(row.get("salary", "")), +              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +  File "C:\Users\Beheerder\c55-data-week1\task-1\src\utils.py", line 49, in clean_salary +    salary = int(raw.strip().replace(",","").replace('"',"")) +             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +ValueError: invalid literal for int() with base 10: 'N/A' +Why i get this? Explain it to me ## The Solution +It work from the first try and Gemini response is: +Think of a **Traceback** as a "crime scene report" for your code. It shows you exactly where the program "died" and why. + +Here is the breakdown of why you got this error: + +### 1. The Root Cause: `ValueError` +At the very bottom of your error message, you see: +`ValueError: invalid literal for int() with base 10: 'N/A'` + +* **`int()`**: This is a function that expects a string of digits (like `"100"` or `"5000"`). +* **`'N/A'`**: This is the actual value the program found in your CSV file. +* **The Problem**: Python does not know how to turn the letters "N", "/", and "A" into a whole number. Since it can't do the math, it panics and shuts down the entire script. + +--- + +### 2. The Chain of Events (Traceback) +The Traceback reads from **bottom to top** to show the sequence of calls: + +* **At the bottom (`utils.py`, line 49):** This is the exact line where the crash happened. The code tried to execute `int(raw.strip()...)` on the value `'N/A'`. +* **The middle (`cleaner.py`, line 38):** This shows that `clean_row` called the `clean_salary` function. +* **The top (`cleaner.py`, line 46):** This shows that the error happened while your program was looping through the rows of your CSV. Because one row was "broken," it stopped the entire cleaning process for the remaining rows. + + + +--- + +### 3. Why did this happen now? +In real-world data (like your `messy_users.csv`), columns aren't always perfect. Even if a column is named "salary," someone might have typed "N/A," "Unknown," or "5000.00" (a float). + +Your current code is **fragile** because it assumes every single row will have a perfect integer. + +--- + +### 4. How to Fix It (Defensive Programming) +To prevent this, you need to use a **try/except** block. This tells Python: *"Try to turn this into an integer. If you see a `ValueError` (like 'N/A'), don't crash! Just return `None` instead."* + +**The fix in `utils.py`:** +```python + try: + # Clean the string (remove commas, spaces, etc.) + clean_value = raw.strip().replace(",", "").replace('"', "") + return int(clean_value) + except ValueError: + # If 'N/A' or any non-number is found, return None safely + return None +``` + + + +By adding this, your script will successfully finish the task, and the "bad" salaries will simply appear as `null` in your JSON file instead of breaking the program. ## Reflection +After the LLm response, I understand it because I was using the try/except but in the wrong way. +I think I will try to fix it first without using LLm by following the trace from bottom to top! + + diff --git a/task-3/azure_proof.png b/task-3/azure_proof.png new file mode 100644 index 0000000..7d753d0 Binary files /dev/null and b/task-3/azure_proof.png differ