Nega funksiyalar kerak?
Tasavvur qiling, dasturingizning beş joyida narxga QQS (12%) qöşib, çiroyli formatda çiqariş kerak. Har safar şu hisobni qayta yozsangiz, ertaga QQS stavkasi özgarganda beş joyni topib tuzatişingiz kerak böladi — bittasini unutib qöyiş oson.
Funksiya — nom berilgan kod bölagi. Uni bir marta yozasiz va keyin istalgança çaqirasiz. Funksiyalar:
- takrorlanişni yöqotadi (bir joyda tuzatiş — hamma joyda tuzaladi);
- katta masalani kiçik, tuşunarli qismlarga böladi;
- kodni öqişni osonlaştiradi:
qqs_qosh(narx)nomi özi nima qilişini aytib turadi.
Siz allaqaçon köp funksiyadan foydalangansiz: print(), len(), input(). Endi özimiznikini yozamiz.
def bilan funksiya yaratiş
def salomlash():
print("Assalomu alaykum!")
print("Darsimizga xuş kelibsiz.")
salomlash()
salomlash()
Natija:
Assalomu alaykum!
Darsimizga xuş kelibsiz.
Assalomu alaykum!
Darsimizga xuş kelibsiz.
def kalit sözi, funksiya nomi, qavslar va ikki nuqta — bu eʼlon qiliş. Surilgan qatorlar funksiya tanasi. Eʼlon qilinganda kod bajarilmaydi, faqat çaqirilganda (salomlash()) işlaydi. Qavslarsiz salomlash yozsangiz, funksiya çaqirilmaydi — bu keng tarqalgan xato.
Parametrlar va argumentlar
Funksiyaga maʼlumot uzatiş mumkin. Eʼlondagi nomlar — parametrlar, çaqirganda beriladigan haqiqiy qiymatlar — argumentlar:
def tabrikla(ism, yosh): # ism, yoş - parametrlar
print(f"{ism}, {yosh} yoşingiz bilan tabriklaymiz!")
tabrikla("Madina", 21) # "Madina", 21 - argumentlar
tabrikla("Otabek", 30)
Natija:
Madina, 21 yoşingiz bilan tabriklaymiz!
Otabek, 30 yoşingiz bilan tabriklaymiz!
Standart qiymatlar va kalitli argumentlar
Parametrga standart qiymat bersangiz, u argumentni beriş ixtiyoriy böladi. Çaqirganda esa argumentlarni nomi bilan (keyword argument) ham beriş mumkin — şunda tartib muhim emas:
def kofe_buyurt(nom, hajm="örta", shakar=0):
print(f"{nom}: {hajm} hajm, {shakar} qoşiq şakar")
kofe_buyurt("Latte")
kofe_buyurt("Kapuçino", "katta")
kofe_buyurt("Amerikano", shakar=2)
kofe_buyurt(shakar=1, nom="Raf")
Natija:
Latte: örta hajm, 0 qoşiq şakar
Kapuçino: katta hajm, 0 qoşiq şakar
Amerikano: örta hajm, 2 qoşiq şakar
Raf: örta hajm, 1 qoşiq şakar
*args va **kwargs
Baʼzan argumentlar soni oldindan nomaʼlum böladi. *args barça qöşimça oddiy argumentlarni kortejga, **kwargs esa barça qöşimça nomli argumentlarni luğatga yiğadi (nomlar ixtiyoriy, muhimi * va **):
def jami_narx(*narxlar):
print("Kelgan narxlar:", narxlar)
return sum(narxlar)
print(jami_narx(4000, 12000, 18000))
def profil(ism, **malumot):
print(f"Foydalanuvçi: {ism}")
for kalit, qiymat in malumot.items():
print(f" {kalit}: {qiymat}")
profil("Javlon", shahar="Namangan", kasb="dasturçi")
Natija:
Kelgan narxlar: (4000, 12000, 18000)
34000
Foydalanuvçi: Javlon
shahar: Namangan
kasb: dasturçi
return: qiymat qaytariş
print() natijani faqat ekranga çiqaradi. return esa natijani funksiyadan qaytaradi — uni özgaruvçiga yoziş, boşqa hisobda işlatiş mumkin:
def qqs_qosh(narx, stavka=0.12):
return round(narx * (1 + stavka), 2)
narx = qqs_qosh(50000)
print(narx)
print(qqs_qosh(10000) + qqs_qosh(20000))
def hech_narsa():
x = 5
print(hech_narsa())
Natija:
56000.0
33600.0
None
return bölmagan funksiya avtomatik ravişda None qaytaradi.
Bir neçta qiymat va erta qaytiş
return vergul bilan bir neçta qiymat qaytara oladi (aslida bitta kortej). return bajarilişi bilan funksiya darhol tugaydi — bundan notöğri holatlarni boşidayoq "çiqarib yuboriş" uçun foydalaniladi:
def statistika(ballar):
if not ballar: # erta qaytiş
return None
return min(ballar), max(ballar), sum(ballar) / len(ballar)
eng_kam, eng_kop, ortacha = statistika([72, 95, 88, 64])
print(eng_kam, eng_kop, ortacha)
print(statistika([]))
Natija:
64 95 79.75
None
Docstring va tur izohlari
Funksiya nima qilişini uning birinçi qatoriga uçta qöştirnoq içida yoziş odat tusiga kirgan. Bu docstring deyiladi va help() orqali körinadi. Tur izohlari (type hints) esa parametr va natija qanday turda ekanini bildiradi:
def kurs_bilan(summa_usd: float, kurs: float = 12_800) -> float:
"""Dollardagi summani sömga ögiradi."""
return summa_usd * kurs
print(kurs_bilan(25))
print(kurs_bilan.__doc__)
Natija:
320000
Dollardagi summani sömga ögiradi.
Köriniş sohasi (scope)
Funksiya içida yaratilgan özgaruvçi — lokal, u faqat şu funksiya içida mavjud. Fayl darajasida yaratilgani — global:
shahar = "Toşkent" # global
def sayohat():
shahar = "Samarqand" # lokal, global özgaruvçiga tegmaydi
print("Içkarida:", shahar)
sayohat()
print("Taşqarida:", shahar)
Natija:
Içkarida: Samarqand
Taşqarida: Toşkent
Global özgaruvçini funksiya içida özgartiriş kerak bölsa, global kalit sözi işlatiladi. Içma-iç funksiyada taşqi funksiyaning özgaruvçisini özgartiriş uçun esa nonlocal:
tashriflar = 0
def tashrif_qosh():
global tashriflar
tashriflar += 1
tashrif_qosh()
tashrif_qosh()
print("Taşriflar:", tashriflar)
def hisoblagich_yarat():
son = 0
def keyingi():
nonlocal son
son += 1
return son
return keyingi
navbat = hisoblagich_yarat()
print(navbat(), navbat(), navbat())
Natija:
Taşriflar: 2
1 2 3
lambda ifodalari
lambda — bitta ifodadan iborat kiçik, nomsiz funksiya. U asosan boşqa funksiyaga "qanday işlaş kerak"ligini qisqa aytiş uçun işlatiladi:
kvadrat = lambda x: x ** 2
print(kvadrat(7))
mahsulotlar = [("non", 4000), ("göşt", 95000), ("sut", 12000)]
mahsulotlar.sort(key=lambda m: m[1])
print(mahsulotlar)
Natija:
49
[('non', 4000), ('sut', 12000), ('göşt', 95000)]
Birinçi misoldagidek lambdani özgaruvçiga yoziş yaxşi uslub emas — buning uçun oddiy def bor. lambda ikkinçi misoldagi kabi joylarda özini oqlaydi. Bu haqda 12-bobda köproq gaplaşamiz.
Metod va funksiya farqi
Metod — maʼlum bir obyektga "boğlangan" funksiya. U nuqta orqali çaqiriladi va öşa obyekt bilan işlaydi:
ism = "nodira"
print(len(ism)) # funksiya: obyektni argument sifatida oladi
print(ism.upper()) # metod: satr obyektining öziga tegişli
sonlar = [3, 1, 2]
sonlar.append(5) # röyxat metodi röyxatni özgartiradi
print(sorted(sonlar), sonlar)
Natija:
6
NODIRA
[1, 2, 3, 5] [3, 1, 2, 5]
len() har xil turdagi obyektlar bilan işlaydi, upper() esa faqat satrlarda bor. Metodlarni özimiz qanday yaratişni sinflar (class) mavzusida örganamiz.
Sof funksiyalar
Sof funksiya (pure function) — natijasi faqat argumentlarga boğliq va taşqi dunyoni özgartirmaydigan funksiya. Bir xil argument — doim bir xil natija:
# Sof emas: taşqi röyxatni özgartiradi
def chegirma_qoy(narxlar):
for i in range(len(narxlar)):
narxlar[i] *= 0.9
# Sof: yangi röyxat qaytaradi, asl röyxatga tegmaydi
def chegirmali(narxlar, foiz=10):
return [n * (100 - foiz) / 100 for n in narxlar]
asl = [10000, 25000]
yangi = chegirmali(asl)
print(asl, yangi)
chegirma_qoy(asl)
print(asl)
Natija:
[10000, 25000] [9000.0, 22500.0]
[9000.0, 22500.0]
Sof funksiyalarni tekşiriş, qayta işlatiş va xatosini topiş ança oson. Imkon bölsa, funksiyalaringizni şunday yozing.
Amaliyot: tub sonni tekşiriş
Tub son faqat 1 ga va öziga bölinadi. Böluvçilarni √n gaça tekşiriş kifoya, çunki katta böluvçining "jufti" doim kiçik böladi:
def tubmi(n: int) -> bool:
"""n tub son bölsa True qaytaradi."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
print([n for n in range(1, 40) if tubmi(n)])
print(tubmi(97), tubmi(91))
Natija:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
True False
Amaliyot: böluvçilar
def boluvchilar(n: int) -> list[int]:
"""n ning barça musbat böluvçilarini ösiş tartibida qaytaradi."""
return [i for i in range(1, n + 1) if n % i == 0]
def mukammalmi(n: int) -> bool:
"""Özidan boşqa böluvçilar yiğindisi öziga tengmi?"""
return sum(boluvchilar(n)[:-1]) == n
print(boluvchilar(36))
print([n for n in range(2, 1000) if mukammalmi(n)])
Natija:
[1, 2, 3, 4, 6, 9, 12, 18, 36]
[6, 28, 496]
Eʼtibor bering: mukammalmi() içida boluvchilar() funksiyasidan foydalandik — kiçik funksiyalardan kattasini yiğiş şunday böladi.
Amaliyot: kredit kalkulyatori
Bankda kredit odatda annuitet usulida tölanadi: har oy bir xil summa. Oylik tölov formulasi:
tolov = S * r / (1 - (1 + r) ** -n)
Bu yerda S — kredit summasi, r — oylik foiz stavkasi (yillik stavka / 12), n — oylar soni.
def oylik_tolov(summa: float, yillik_foiz: float, oylar: int) -> float:
"""Annuitet kredit böyiça oylik tölovni hisoblaydi."""
if yillik_foiz == 0:
return summa / oylar
r = yillik_foiz / 100 / 12
return summa * r / (1 - (1 + r) ** -oylar)
def kredit_hisoboti(summa, yillik_foiz, oylar):
tolov = oylik_tolov(summa, yillik_foiz, oylar)
jami = tolov * oylar
print(f"Kredit: {summa:,.0f} söm, {yillik_foiz}% yillik, {oylar} oy")
print(f" Oylik tölov: {tolov:,.0f} söm")
print(f" Jami tölanadi: {jami:,.0f} söm")
print(f" Ortiqça tölov: {jami - summa:,.0f} söm")
kredit_hisoboti(30_000_000, 24, 12)
kredit_hisoboti(30_000_000, 24, 36)
Natija:
Kredit: 30,000,000 söm, 24% yillik, 12 oy
Oylik tölov: 2,836,788 söm
Jami tölanadi: 34,041,455 söm
Ortiqça tölov: 4,041,455 söm
Kredit: 30,000,000 söm, 24% yillik, 36 oy
Oylik tölov: 1,176,986 söm
Jami tölanadi: 42,371,481 söm
Ortiqça tölov: 12,371,481 söm
Muddat uzaygani sari oylik tölov kamayadi, lekin umumiy ortiqça tölov keskin oşadi — funksiya buni bir qaraşda körsatib berdi.
Xulosa
- Funksiya
defbilan eʼlon qilinadi va faqat çaqirilganda işlaydi. - Parametrlar eʼlonda, argumentlar çaqiruvda; standart qiymatlar va kalitli argumentlar çaqiruvni moslaşuvçan qiladi.
*argsqöşimça argumentlarni kortejga,**kwargsluğatga yiğadi.returnnatijani qaytaradi (bir neçta qiymatni ham);returnsiz funksiyaNoneqaytaradi.Docstringva tur izohlari kodni hujjatlaştiradi.- Lokal özgaruvçilar funksiya içida yaşaydi;
globalvanonlocaldan ehtiyotkorlik bilan foydalaning. lambda— qisqa nomsiz funksiya; metod — obyektga boğlangan funksiya; sof funksiyalar eng işonçli.
Maşqlar
- Selsiyni Farengeytga ögiruvçi
farengeyt(c)funksiyasini yozing (F = C * 9 / 5 + 32) va-10,0,36.6uçun sinang.
Yeçim
def farengeyt(c: float) -> float:
"""Selsiydan Farengeytga ögiradi."""
return c * 9 / 5 + 32
for c in (-10, 0, 36.6):
print(f"{c} C = {farengeyt(c):.1f} F")
- Istalgança son qabul qilib, ularning örtaçasini qaytaruvçi
ortacha(*sonlar)funksiyasini yozing. Son berilmasa0qaytarsin.
Yeçim
def ortacha(*sonlar: float) -> float:
if not sonlar:
return 0
return sum(sonlar) / len(sonlar)
print(ortacha(4, 5, 3, 5))
print(ortacha())
- Satrda neçta söz, neçta harf va neçta raqam borligini kortej qilib qaytaruvçi funksiya yozing.
Yeçim
def tahlil(matn: str) -> tuple[int, int, int]:
sozlar = len(matn.split())
harflar = sum(1 for b in matn if b.isalpha())
raqamlar = sum(1 for b in matn if b.isdigit())
return sozlar, harflar, raqamlar
print(tahlil("2025-yilda 3 ta kitob öqidim"))
- Berilgan sondan kiçik yoki teng bölgan barça tub sonlar yiğindisini qaytaruvçi funksiya yozing. Bobdagi
tubmi()funksiyasidan foydalaning.
Yeçim
def tubmi(n: int) -> bool:
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def tublar_yigindisi(chegara: int) -> int:
return sum(n for n in range(2, chegara + 1) if tubmi(n))
print(tublar_yigindisi(10))
print(tublar_yigindisi(100))