Skip to content

Commit e0ef005

Browse files
committed
typing and generics
1 parent 040fd07 commit e0ef005

File tree

20 files changed

+530
-0
lines changed

20 files changed

+530
-0
lines changed

.gitignore

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.sof
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
pip-wheel-metadata/
24+
share/python-wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
*.manifest
32+
*.spec
33+
34+
# Installer logs
35+
pip-log.txt
36+
pip-delete-this-directory.txt
37+
38+
# Unit test / coverage reports
39+
htmlcov/
40+
.tox/
41+
.nox/
42+
.coverage
43+
.coverage.*
44+
.cache
45+
nosetests.xml
46+
coverage.xml
47+
*.cover
48+
*.py,cover
49+
.hypothesis/
50+
.pytest_cache/
51+
52+
# Translations
53+
*.mo
54+
*.pot
55+
56+
# Django stuff:
57+
*.log
58+
local_settings.py
59+
db.sqlite3
60+
db.sqlite3-journal
61+
62+
# Flask stuff:
63+
instance/
64+
.webassets-cache
65+
66+
# Scrapy stuff:
67+
.scrapy
68+
69+
# Sphinx documentation
70+
docs/_build/
71+
72+
# PyBuilder
73+
target/
74+
75+
# Jupyter Notebook
76+
.ipynb_checkpoints
77+
78+
# IPython
79+
profile_default/
80+
ipython_config.py
81+
82+
# pyenv
83+
.python-version
84+
85+
# pipenv
86+
Pipfile.lock
87+
88+
# PEP 582
89+
__pypackages__/
90+
91+
# Celery stuff
92+
celerybeat-schedule
93+
celerybeat.pid
94+
95+
# SageMath parsed files
96+
*.sage.py
97+
98+
# Environments
99+
.env
100+
.venv
101+
env/
102+
venv/
103+
ENV/
104+
env.bak/
105+
venv.bak/
106+
107+
# Spyder project settings
108+
.spyderproject
109+
.spyproject
110+
111+
# Rope project settings
112+
.ropeproject
113+
114+
# mkdocs documentation
115+
/site
116+
117+
# mypy
118+
.mypy_cache/
119+
.dmypy.json
120+
dmypy.json
121+
122+
# Pyre type checker
123+
.pyre/
124+
125+
# IDE
126+
.vscode/
127+
.idea/
128+
*.swp
129+
*.swo
130+
*~
131+
.DS_Store
132+
133+
# OS
134+
Thumbs.db
135+
.DS_Store

Pydantic_tutorial/lecture_5.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from pydantic import BaseModel, ValidationError, Field
2+
from datetime import datetime, UTC
3+
from functools import partial
4+
from typing import Literal,Annotated
5+
6+
class User(BaseModel):
7+
uid : Annotated[int, Field(gt=0)]
8+
username : Annotated[str, Field(min_length=3, max_length=20)]
9+
email : str
10+
age : Annotated[int, Field(ge=13,le=130)]
11+
12+
verified_at : datetime | None = None
13+
14+
bio : str = ""
15+
is_active : bool = True
16+
17+
full_name : str | None = None
18+
19+
class BlogPost(BaseModel):
20+
title : Annotated[str, Field(min_length=1,max_length=200)]
21+
content : Annotated[str, Field(min_length=20)]
22+
view_count : int = 0
23+
is_published : bool = False
24+
25+
tags : list[str] = Field(default_factory=list)
26+
27+
# create_at : datetime = Field(default_factory=lambda : datetime.now(tz=UTC))
28+
# both will do same work lambda or partial function
29+
create_at : datetime = Field(default_factory=partial(datetime.now,tz=UTC))
30+
31+
author_id : str | int
32+
status : Literal["draft", "published", "archived"] = "draft"
33+
34+
slug : Annotated[str, Field(pattern=r"^[a-z0-9-]+$")]
35+
36+
37+
try:
38+
user = User(
39+
uid = 0,
40+
username="cs",
41+
email="ashwini@gmail.com",
42+
age=12
43+
44+
)
45+
except ValidationError as e:
46+
print(e)
47+
# post = BlogPost(
48+
# title="Getting started with Python",
49+
# content="python is dynamically typing language.",
50+
# author_id="123",
51+
# )
52+
53+
# print(post)

Pydantic_tutorial/lecture_6.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from pydantic import BaseModel, ValidationError, Field, EmailStr
2+
from datetime import datetime, UTC
3+
from functools import partial
4+
from typing import Literal,Annotated
5+
6+
class User(BaseModel):
7+
uid : Annotated[int, Field(gt=0)]
8+
username : Annotated[str, Field(min_length=3, max_length=20)]
9+
email : str
10+
age : Annotated[int, Field(ge=13,le=130)]
11+
12+
verified_at : datetime | None = None
13+
14+
bio : str = ""
15+
is_active : bool = True
16+
17+
full_name : str | None = None
18+
19+
class BlogPost(BaseModel):
20+
title : Annotated[str, Field(min_length=1,max_length=200)]
21+
content : Annotated[str, Field(min_length=20)]
22+
view_count : int = 0
23+
is_published : bool = False
24+
25+
tags : list[str] = Field(default_factory=list)
26+
27+
# create_at : datetime = Field(default_factory=lambda : datetime.now(tz=UTC))
28+
# both will do same work lambda or partial function
29+
create_at : datetime = Field(default_factory=partial(datetime.now,tz=UTC))
30+
31+
author_id : str | int
32+
status : Literal["draft", "published", "archived"] = "draft"
33+
34+
slug : Annotated[str, Field(pattern=r"^[a-z0-9-]+$")]
35+
36+
37+
try:
38+
user = User(
39+
uid = 0,
40+
username="cs",
41+
email="ashwini@gmail.com",
42+
age=12
43+
44+
)
45+
except ValidationError as e:
46+
print(e)
47+
# post = BlogPost(
48+
# title="Getting started with Python",
49+
# content="python is dynamically typing language.",
50+
# author_id="123",
51+
# )
52+
53+
# print(post)

Typing_Generics/lec_1.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
age: int = 1
2+
3+
a : int
4+
5+
# a = input()
6+
7+
child: bool
8+
if age < 18:
9+
child = True
10+
else:
11+
child = False
12+

Typing_Generics/lec_2.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
x1: int = 1
2+
x2: float = 1.0
3+
x3: bool = True
4+
x4: str = "test"
5+
x5: bytes = b"test"
6+
7+
# For collections on Python 3.9+, the type of the collection item is in brackets
8+
x6: list[int] = [1]
9+
x7: set[int] = {6, 7}
10+
11+
# For mappings, we need the types of both keys and values
12+
x8: dict[str, float] = {"field": 2.0} # Python 3.9+
13+
14+
# For tuples of fixed size, we specify the types of all the elements
15+
x9: tuple[int, str, float] = (3, "yes", 7.5) # Python 3.9+
16+
17+
# For tuples of variable size, we use one type and ellipsis
18+
x0: tuple[int, ...] = (1, 2, 3)

Typing_Generics/lec_3.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from typing import List, Set, Dict, Tuple
2+
x0: List[int] = [1]
3+
x1: Set[int] = {6, 7}
4+
x2: Dict[str, float] = {"field": 2.0}
5+
x3: Tuple[int, str, float] = (3, "yes", 7.5)
6+
x4: Tuple[int, ...] = (1, 2, 3)
7+
8+
from typing import Union, Optional
9+
10+
# On Python 3.10+, use the | operator when something could be one of a few types
11+
x5: list[int | str] = [3, 5, "test", "fun"] # Python 3.10+
12+
# On earlier versions, use Union
13+
x6: list[Union[int, str]] = [3, 5, "test", "fun"]
14+
15+
# Use X | None for a value that could be None on Python 3.10+
16+
# Use Optional[X] on 3.9 and earlier; Optional[X] is the same as 'X | None'
17+
x7: str | None = "something" if 1 == 1 else None
18+
if x7 is not None:
19+
# Mypy understands x won't be None here because of the if-statement
20+
print(x7.upper())
21+
# If you know a value can never be None due to some logic that mypy doesn't
22+
# understand, use an assert
23+
assert x7 is not None
24+
print(x7.upper())

Typing_Generics/lec_4.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""
2+
Meta class
3+
"""
4+
from typing import ClassVar, TypeVar
5+
6+
S = TypeVar("S")
7+
8+
class M(type):
9+
count: ClassVar[int] = 0
10+
11+
def make(cls: type[S]) -> S:
12+
M.count += 1
13+
return cls()
14+
15+
class A(metaclass=M):
16+
pass
17+
18+
a: A = A.make() # make() is looked up at M; the result is an object of type A
19+
print(A.count)
20+
21+
class B(A):
22+
pass
23+
24+
b: B = B.make() # metaclasses are inherited
25+
# print(B.count + " objects were created")

Typing_Generics/lec_5.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from typing import TypeVar, Generic
2+
3+
T = TypeVar('T') # Define type variable "T"
4+
5+
class Stack(Generic[T]):
6+
def __init__(self) -> None:
7+
# Create an empty list with items of type T
8+
self.items: list[T] = []
9+
10+
def push(self, item: T) -> None:
11+
self.items.append(item)
12+
13+
def pop(self) -> T:
14+
return self.items.pop()
15+
16+
def empty(self) -> bool:
17+
return not self.items

adv python/metaclass_example.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class NamingConventionMeta(type):
2+
def __new__(cls, name, bases, attrs):
3+
if not name.startswith("My"):
4+
raise ValueError("Class name must start with 'My'")
5+
# Add a default method
6+
attrs["get_class_name"] = lambda self: name
7+
return super().__new__(cls, name, bases, attrs)
8+
9+
class MyCalculator(metaclass=NamingConventionMeta):
10+
def add_numbers(self, a, b):
11+
return a + b
12+
13+
# This will raise ValueError
14+
# class Calculator(metaclass=NamingConventionMeta):
15+
# pass

adv python/string_intern.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Example of string interning
2+
a = "hello"
3+
b = "hello"
4+
print(a is b) # True (interned, same memory address)
5+
print(id(a))
6+
print(id(b))
7+
8+
c = "hello world" * 100 # Runtime-generated string
9+
d = "hello world" * 100
10+
print(c is d) # False (not interned, different objects)
11+
12+
# Explicit interning
13+
import sys
14+
c_interned = sys.intern(c)
15+
d_interned = sys.intern(d)
16+
print(c_interned is d_interned) # True (interned explicitly)

0 commit comments

Comments
 (0)