Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
49bf581
Merge pull request #13 from PANDATD/day15-model_validator
PANDATD Jul 7, 2026
484a439
Understand how to use pydantic extra, allow, and forbid
PANDATD Jul 7, 2026
dcfefac
Merge pull request #14 from PANDATD/pydantic-extras
PANDATD Jul 7, 2026
dae3a69
feat: Understand Why is used in buisness fields
PANDATD Jul 17, 2026
0f7087f
fix: Add SALES to Department enum and use valid enum member
PANDATD Jul 17, 2026
d89f14e
fix: Add type: ignore comments for snake_case field names with popula…
PANDATD Jul 17, 2026
0ec879d
Merge pull request #15 from PANDATD/feat/day-23-str-enum
PANDATD Jul 17, 2026
a5eec3f
day_24_decimal/product_invoice.py
PANDATD Jul 21, 2026
8b0f836
feat(pydantic): add date and datetime models
PANDATD Jul 21, 2026
598daa8
Merge pull request #16 from PANDATD/feat/day25-date-datetime
PANDATD Jul 21, 2026
6767002
feat(model_dump) understand how to serialize model using include, exc…
PANDATD Jul 22, 2026
3867116
docs(Add Why model_dump is used and How to use)
PANDATD Jul 22, 2026
8f04c2c
Merge pull request #17 from PANDATD/feat/day26-understand-model_dump
PANDATD Jul 22, 2026
a738cb6
feat(field_serializer) lesson
PANDATD Jul 25, 2026
6e50c47
capsote project
PANDATD Jul 27, 2026
c143fa9
Merge pull request #18 from PANDATD/feat/capstone-project-1-employee-…
PANDATD Jul 27, 2026
d5f68f0
Merge pull request #19 from PANDATD/feat/day-27-field_serializer
PANDATD Jul 27, 2026
fbe275e
Merge pull request #20 from PANDATD/main
PANDATD Jul 27, 2026
084c0cd
Merge pull request #21 from PANDATD/feat/day24-decimal
PANDATD Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions python_fundamentals/exercises/day18-field-alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from typing import ClassVar

from pydantic import (
BaseModel,
ConfigDict,
Field,
ValidationError,
computed_field,
field_validator,
)


class Employee(BaseModel):
model_config: ClassVar[ConfigDict] = ConfigDict(
populate_by_name=True,
)

"""
Allow model initialization using both the Python field name (`snake_case`)
and its alias (for example, `camelCase`).

This keeps the internal codebase consistent with Python's naming conventions
while remaining compatible with external APIs that use different field names.
Without `populate_by_name=True`, Pydantic accepts only the alias for aliased
fields during validation, which can result in a `ValidationError` when the
Python field name is provided.
"""

"""This Model represents an employee"""

first_name: str = Field(
min_length=3,
max_length=20,
alias="firstName",
)
last_name: str = Field(min_length=2, max_length=20, alias="lastName")
monthly_salary: float = Field(gt=0, alias="monthlySalary")

@field_validator("first_name")
@classmethod
def transform_first_name(cls, first_name: str) -> str:
first_name = first_name.strip().title()
return first_name

@field_validator("last_name")
@classmethod
def transform_last_name(cls, last_name: str) -> str:
last_name = last_name.strip().title()
return last_name

@computed_field
def full_name(self) -> str:
"""This will return full name of an employee"""
return f"{self.first_name} {self.last_name}"

@computed_field
def annual_salary(self) -> float:
"""This will return annual salary of an employee"""
return self.monthly_salary * 12

def change_first_name(self, first_nm: str) -> None:
self.first_name = first_nm.strip().title()
return None


try:
emp1: Employee = Employee(
firstName="tejas",
lastName="dixit",
monthlySalary=25000,
)

print(emp1.model_dump())
except ValidationError as exc:
print(exc)

try:
emp2: Employee = Employee(
first_name="swaroop", # type: ignore
last_name="dixit", # type: ignore
monthly_salary=20000, # type: ignore
)
print(emp2.model_dump())
except ValidationError as exc:
print(exc)
129 changes: 129 additions & 0 deletions python_fundamentals/exercises/day_23_str_enum/employee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from enum import StrEnum

from pydantic import BaseModel, EmailStr, Field, field_validator

"""

Understand why StrEnum is used ?


Problem:

- department : str = " HR"
- department : str = "hr"
- department : str = "Human Resource"

We know the Fixed Department and so we can resolve the same issue with StrEnum which
follow the consistancy for redundant but fixed values.

now StrEnum will gives JSON friendly ouput for department
but after serialization using `.model_dump_json()`

"""


class Department(StrEnum):
ADMIN = "ADMIN"
TECH = "TECH"
DATA = "DATA"
CONTENT = "CONTENT"


class Address(BaseModel):
city: str | None = Field(
default=None,
min_length=3,
max_length=10,
)
pincode: str | None = Field(default=None, min_length=6, max_length=6)


class Employee(BaseModel):
"""
This class represent an Employee of a Company
"""

emp_name: str = Field(min_length=3, max_length=60)
emp_id: str = Field(min_length=7, max_length=20)
email: EmailStr | None = None
department: Department
address: Address

@field_validator("emp_name")
@classmethod
def transform_employee_name(cls, emp_name: str) -> str:
"""
This method transforms emp_name and validates it
removes whitespace and save employee name in title case
"""
emp_name = emp_name.strip().title()

if emp_name.isalpha():
raise ValueError(
f"Employee name has digits in it. \
Employee name must be pure string and not contains digit. \
you have entered {emp_name}"
)
return emp_name

@field_validator("emp_id")
@classmethod
def transform_and_validate_employee_id(cls, emp_id: str) -> str:
"""
This method helps to transforms and validate the employee id
- Removes the whitespaces from emp_id
- Capitalize the emp_id
- Checks wether it strats with EMP-
"""
emp_id = emp_id.strip().upper()

if not emp_id.startswith("EMP-"):
raise ValueError("Employee id must starts with EMP- ")

if emp_id.isalnum():
raise ValueError("Employee id must contain digits")

return emp_id


class Company(BaseModel):
"""
This Class represents company
"""

company_name: str = Field(min_length=3, max_length=50)
employees: list[Employee]

@field_validator("company_name")
@classmethod
def transform_company_name(cls, company_name: str) -> str:
company_name = company_name.strip().title()
return company_name


tejas_dixit: Employee = Employee(
emp_name=" tejas dixit ",
emp_id=" emp-108 ",
email="tejasdixit17@gmail.com",
address=Address(city="Pune", pincode="411028"),
department=Department.TECH,
)

aniket_jagadale: Employee = Employee(
emp_name=" aniket Jagadale",
emp_id="EmP-107 ",
department=Department.CONTENT,
address=Address(),
)


media_vidya: Company = Company(
company_name=" media VIdya pvt ltd", employees=[tejas_dixit, aniket_jagadale]
)


print(media_vidya.model_dump()) # prints normal model with python object for Department
print(media_vidya.model_dump_json()) # heare we can see department values pydantic
# serialize the output using model_dump_json()
# its API friendly and help when working with
# other languages.
46 changes: 46 additions & 0 deletions python_fundamentals/exercises/day_24_decimal/product_invoice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from decimal import Decimal

from pydantic import BaseModel, Field, computed_field


class Product(BaseModel):
name: str = Field(min_length=3, max_length=20)
price: Decimal
quantity: int

@computed_field
def subtotal(self) -> Decimal:
return self.price * self.quantity


class Invoice(BaseModel):
invoice_id: str
customer_name: str = Field(min_length=3, max_length=20)
products: list[Product]
gst_percentage: Decimal

@computed_field
def subtotal_total(self) -> Decimal:
total: Decimal = Decimal("0")
for product in self.products:
total += product.subtotal
return total

@computed_field
def grand_total(self) -> Decimal:
subtotal: Decimal = self.subtotal_total
gst_amount = subtotal * (self.gst_percentage / 100)
return Decimal(subtotal + gst_amount)


p1: Product = Product(name="Sugar", price=Decimal("20.00"), quantity=1)
p2: Product = Product(name="Oil", price=Decimal("120.00"), quantity=2)

invoice: Invoice = Invoice(
invoice_id="123",
customer_name="Tejas Dixit",
products=[p1, p2],
gst_percentage=Decimal("18"),
)

print(invoice.model_dump())
74 changes: 74 additions & 0 deletions python_fundamentals/exercises/day_25_date_datetime/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Day 25 — Date & DateTime

## Objective

Understand when to use `date` and `datetime` in Pydantic models and how Pydantic parses ISO formatted strings into Python objects.

---

## Concepts Covered

- `date`
- `datetime`
- Pydantic parsing
- `ValidationError`
- `model_dump()`
- `model_dump_json()`

---

## Business Use Cases

### `date`

- Employee joining date
- Date of birth
- Manufacturing date

### `datetime`

- User login
- Payment timestamp
- Audit logs
- Record creation time

---

## Key Learning

- Use `date` when only the calendar date is required.
- Use `datetime` when both date and time are required.
- Python validates `date()` and `datetime()` constructors.
- Pydantic parses strings into `date` and `datetime` objects.
- Invalid parsed values raise `ValidationError`.

---

## Run

```bash
uv run python employee.py
```

---

## Expected Output

- Successful creation of a valid `Employee`.
- `model_dump()` returns Python objects.
- `model_dump_json()` returns JSON.
- Invalid input raises `ValidationError`.

---

## Files

```
employee.py
```

---

## Status

✅ Completed
35 changes: 35 additions & 0 deletions python_fundamentals/exercises/day_25_date_datetime/employee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3.12
from datetime import date, datetime

from pydantic import BaseModel, Field, ValidationError


class Employee(BaseModel):
emp_name: str = Field(min_length=3, max_length=20)
joining_date: date
created_at: datetime


try:
tejas_dixit: Employee = Employee(
emp_name="Tejas Dixit",
joining_date=date(year=2024, month=1, day=29),
created_at=datetime(year=2024, month=1, day=29, hour=13, minute=00, second=20),
)

print(f"Python Representaion of Employee Object: {tejas_dixit.model_dump()}")
print(f"Pydantic Representaion of Employee Object: {tejas_dixit.model_dump_json()}")

vignesh_gawali: Employee = Employee(
emp_name="Vignesh Gawali",
joining_date="2024-12-12", # Intentional: testing Pydantic parsing
created_at="0000-12-12 12:12", # Intentional: testing Pydantic parsing
)

print(f"Python Representaion of Employee Object: {vignesh_gawali.model_dump()}")
print(
f"Pydantic Representaion of Employee Object: {vignesh_gawali.model_dump_json()}"
)

except (ValueError, ValidationError) as exc:
print(exc)
Loading
Loading