randint(a,b)
Bu funksiya a va b oraligi'da tasodifiy butun son qaytaradi.
In [16]:
import random as r # random modulini r deb chaqirayapmiz
son = r.randint(0,100) # 0 va 100 oralig'ida tasodifiy son
print(son)
62
choice(x)
x ning ichidan tasodifiy qiymatni qaytaruvchi funksiya. Bunda x bir necha elementdan iborat o'zgaruvchi (matn, ro'yxat) bo'lishi kerak.
In [17]:
ismlar = ['olim','anvar','hasan','husan']
ism = r.choice(ismlar) # ismlar dan tasodifiy ism tanlaymiz
print(ism)
print(r.choice(ism)) # ismdan tasodifiy harf tanlaymiz
hasan n
In [18]:
x = list(range(0,51,5))
print(x)
print(r.choice(x))
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50] 0
shuffle(x)
x ichidagi elementlarni tasodifiy tartibda qaytaruvchi funksiya. Bunda x bir necha elementdan iborat o'zgaruvchi (matn, ro'yxat) bo'lishi kerak.
In [19]:
x = list(range(11))
print(x)
r.shuffle(x)
print(x)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [1, 2, 10, 8, 7, 3, 5, 0, 6, 9, 4]
random moduli ichidagi boshqa funksiyalar haqida Python rasmiy sahifasidan ma'lumot olishingiz mumkin.
24-DARS. FUNKSIYALAR. SON'GSO'Z.
Funksiyalar mavzusiga yakun yasaymiz.
lambda YOHUD NOMSIZ FUNKSIYA
Pythonning o'ziga xos xususiyatlaridan biri, nomsiz vaqtinchalik funksiyalar yaratish imkoniyati. Bunday funksiyalarni yaratishda def operatori o'rniga lambda operatori ishlatilgani uchun ham lambda funskiyalar deb ataladi.
Nomsiz funksiyalar quyidagicha yaratiladi:
In [ ]:
lambda argument:ifoda
Lambda funksiyalari istalgan miqdordagi argumentlarga ega bo'lishi mumkin, ammo funksiya badanida faqat bitta ifoda mavjud bo'ladi. Ifoda bajariladi va qaytariladi (return operatori shart emas).
Nomsiz funksiyalar biror ifodani tezda hisoblab olishda qulay. Misol uchun quyidgai lambda funksiya ikkita argument qabul qiladi ( ), va aylana uzunligini qaytaradi:
In [5]:
import math
uzunlik = lambda pi, r : 2*pi*r
print(uzunlik(math.pi,10))
62.83185307179586
Kodni tahlil qilamiz, 1-qatorda math modulini chaqirib oldik. 2-qatorda lambda funksiyani yaratdik, funksiyamiz pi va r argumentlarini qabul qilib, 2*pi*r qiymatni qaytaradi. Funksiyaga nom bermadik, lekin unga uzunlik identifikatori orqali murojat qilishimiz mumkin. 3-qatorda funksiyamizga murojat qildik va natijani konsolga chiqardik.
Yana bir misol, topingchi quyidagi funksiyaning vazfiasi nima?
In [ ]:
product = lambda x, y : x ** y
print(product(3, 2))
Shu yerda so'rashingiz mumkin, nima uchun lambda nomsiz deb ataladi, ahir unga hozirgina nomi bilan murojat qildikku?
Gap shundaki, lambda finksiyalarning asl mohiyati boshqa funskiyalar bilan birga ishlaganda ko'rinadi. Keling, tushunarli bo'lishi uchun oddiyroq misol ko'ramiz.
Quyidagi dasturda biz avval daraja degan funksiya yasadik, bu funskiyamiz n degan o'zgaruvchi qabul qilib oladi va funksiya ichidagi noma'lum x ning n-darajasini qaytaradi. Aslida darajabu funksiya yasaydigan funksya bo'ldi. Xo'sh, undan qanday foydalanamiz? 4-5-qatorlarda esa daraja funksiyasidan yana 2 ta funksiya yasadik: kvadrat - kiritilgan sonning kvadratini hisoblaydi, kub - kiritilgan sonning kubini hisoblaydi.
In [7]:
def daraja(n):
return lambda x : x**n
kvadrat = daraja(2)
kub = daraja(3)
print(f"3-ning kvadrati {kvadrat(3)} ga, kubi {kub(3)} ga teng")
3-ning kvadrati 9 ga, kubi 27 ga teng
Lambda funksiyalaridan argument sifatida boshqa funksyani qabul qiluvchi funksiyalar bilan ishlashda ham keng foydalaniladi. Misol uchun map() va filter() funksiyalari.
map() FUNKSIYASI
Bu funksiya argument sifatida ro'yxat (yoki lug'at) va boshqa bir funksiyani qabul qilib, ro'yxat elementlariga qabul qilingan funksya yordamida ishlov beradi. Tushunarli bo'lish uchun quyidagi misolni ko'ramiz.
In [ ]:
from math import sqrt
sonlar = list(range(11)) # 0 dan 10 gacha sonlar ro'yxati
ildizlar = list(map(sqrt,sonlar))
Yuqoridagi misolda avval 0 dan 10 gacha sonlar ro'yxatini tuzib oldik, keyin esa map funksiyasiga ro'yxat va sqrt funksiyasini uzatib, ro'yxatdagi barcha sonlarning ildizini hisoblab oldik.
map() funksiyasi map obyekt qaytargani sababli, qaytgan obyektni ro'yxatga o'tkazib olish uchun list() funksiyasidan foyydalandik.
Yana bir misol ko'ramiz:
In [8]:
sonlar = list(range(11)) # 0 dan 10 gacha sonlar ro'yxati
def daraja2(x):
"""Berilgan sonning kvadratini qaytaruvchi funksiya"""
return x*x
print(list(map(daraja2,sonlar))) # sonlar ning kvadratini hisoblaymiz
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Yuqoridagi misolda biz avval berilgan sonning kvadratini hisoblovchi funksiya yaratib oldik, undan keyin esa map yordamida sonlar ro'yxatidagi elementlarning kvadratini ham hisoblab oldik.
Endi keling huddi shu misolni lambda yordamida yozamiz:
In [9]:
kvadratlar = list(map(lambda x:x*x,sonlar))
print(kvadratlar)
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Yuqoridagi misolda, endi daraja degan funksiyani yaratib o'tirmasdan, to'g'ridan-to'g'ri map() ni ichiga darajani hisoblovchi lambda funksiya uzatdik.
map() funksiyasi bo'lmaganida biz bunday dasturlarni for yordamida yozishimiz kerak bo'lar edi:
In [ ]:
kvadratlar = []
for son in sonlar:
kvadratlar.append(son*son)
map() funksiyasiga bir nechta ro'yxatlar ham uzatish mumkin:
In [10]:
a = [4, 5, 6]
b = [7, 8, 9]
a_plus_b = list(map(lambda x,y:x+y,a,b))
print(a_plus_b)
[11, 13, 15]
map() istalgan ko'rinishdagi ma'lumot turlari bilan ishlaydi:
In [11]:
ismlar = ['hasan','husan','olim','umid']
print(list(map(lambda matn:matn.upper(),ismlar)))
['HASAN', 'HUSAN', 'OLIM', 'UMID']
filter() FUNKSIYASI
Bu funksiya ham argument sifatida ro'yxat va boshqa funskiyani qabul qilib oladi va berilgan ro'yxat elementlarini berilgan funksiya yordamida saralaydi. Bunda argument sifatida uzatilgan funksiya mantiqiy qiymat qaytarishi kerak (True yoki False).
Keling bunga ham bir misol ko'ramiz: tasodifiy sonlar ro'yxatidan juft sonalrni ajratib oluvchi dastur yozamiz. Dasturimiz 3 qismdan iborat:
Avvalo, random modulidagi sample() funksiyasi yordamida 0-99 oralig'idagi 10 ta tasodifiy sonlar ro'yxatini tuzib oldik
Berilgan son juft (True) yoki juft emas (False) ekanligini qaytaruvchi funksiya yozdik
filter() fuksiyasiga yangi yaratgan juftmi funksiyasi va tasodifiy sonlar ro'yxatini uzatib, yangi juft_sonlar ro'yxatini shakllantridik
In [12]:
import random as r
sonlar = r.sample(range(100),10) # 0-99 oralig'ida 10 ta tasodifiy sonlar
def juftmi(x):
"""x juft bo'lsa True, aks holda False qaytaruvchu funksiya"""
return x%2==0
juft_sonlar = list(filter(juftmi,sonlar))
print(sonlar)
print(juft_sonlar)
[86, 63, 18, 10, 8, 71, 14, 59, 42, 40] [86, 18, 10, 8, 14, 42, 40]
Keling endi shu dasturni lambda yordamida yozamiz:
In [13]:
import random as r
sonlar = r.sample(range(100),10) # 0-99 oralig'ida 10 ta tasodifiy sonlar
juft_sonlar = list(filter(lambda son: son%2==0,sonlar))
print(sonlar)
print(juft_sonlar)
[57, 94, 43, 62, 0, 46, 67, 74, 65, 71] [94, 62, 0, 46, 74]
Kurib turganingizdek, lambda funksiya yordamida dastur bir muncha qisqaroq chiqadi. Agar juftmi funksiyasi kelajakda shart bo'lmasa, alohida funksiya yaratib o'tirmasdan, bir marttalik lambda funksiyasidan foydalangan afzal.
Keling endi filter() funksiyasi yordamida matnlarni saralashga ham misollar ko'raylik.
Quyidagi dastur mevalar ro'yxatidan b harfiga boshlanuvchi mevalarni ajratib oladi. Bu yerda biz matnlarga tegishli bo'lgan .startswith() metodidan foydalandik. Bu metod, berilgan matn shu harfdan boshlanadimi yoki yo'q tekshiradi va True yoki False qiymat qaytaradi.
In [1]:
mevalar = ['olma','anor','anjir','shaftoli',"o'rik","tarvuz","qovun","banan"]
mevalar_b = list(filter(lambda meva:meva.startswith('b'),mevalar))
print(mevalar_b)
['banan']
Quyidagi dastur esa mevalar ro'yxatidan nomi 5 yoki undan kam harfdan iborat mevalarni saralab oladi.
In [2]:
mevalar2 = list(filter(lambda meva:len(meva)<=5, mevalar))
print(mevalar2)
['olma', 'anor', 'anjir', "o'rik", 'qovun', 'banan']
Topingchi, quyidagi kod qanday vazifani bajaradi?
In [ ]:
list(filter(lambda meva:(meva.startswith('a') and meva.endswith('r')), mevalar))
SO'NGSO'Z
Ushbu darsimiz bilan biz dasturlash asoslarining katta bir qismiga yakun yasadik, navbat Object Oriented Programming va boshqa katta mavzularga. Lekin, bu mavzularga o'tishdan avval, keyingi darslarimizni bir nechta sodda loyihalar qilishga bag'ishlaymiz.
E'tiboringiz uchun rahmat!
28-DARS. KLASSLAR
Pythonda klasslar bilan tanishamiz
KIRISH
Avvalgi darsimizda ko'rganimizdek, klasslar Object oriented dasturlashning poydevorlaridan biridir. Klasslar bizga dasturlashga va dastur elementlariga real hayotdagi buyumlar (obyektlarga) yondoshgandek yondoshish imkonin beradi.
Klasslar, obyketlar va ularning qanday ishlashini tushungan dasturchi, mantiqiy fikrlashda ham kuchli bo'ladi. Mukammal va kompleks muammolarga ham yechimni ko'ra biladi.
PYTHONDAGI KLASSLAR
Klass tushunchasi siz uchun yangi bo'lishi mumkin, lekin biz shu vaqtgacha ulardan doimiy ravishda foydalanib keldik. Keling x o'zgaruvchi yaratamiz, unga biror qiymat yuklaymiz va type() funksiyasi yordamida uning turini kuramiz:
In [1]:
x = 10
print(type(x))
In [2]:
matn = "salom"
print(type(matn))
Yuqoridan ko'rayabmizki, x bu int klassidagi, matn esa str klassidagi obyektlar ekan. Demak biz o'zgaruvchi yaratganimizda, aslida Python int yoki str klassidan foydalangan holda yangi obyektlar yaratib kelayotgan ekan.
Huddi shu kabi, agar yangi funksiya yaratib, uning ham turini tekshirsak, funksiyamiz function klassiga tegishli obyekt bo'lib chiqadi.
In [3]:
def salom_ber():
print("Assalom alaykum")
print(type(salom_ber))
Demak, Pythondagi har qanday o'zgaruvchi, funksiya va boshqa elementlar aslida obyektlar ekan.
METODLAR
Har bir obyekt uning ustida bajarish mumkin bo'lgan funksiyalar bilan keladi. Bu funksiyalar obyekt ichida yashirin bo'ladi, va biz ularga nuqta va funksiya nomi orqali murojat qilishimiz mumkin. Bunday funksiyalar shu klass (yoki obyektga) tegishli metodlar deyiladi.
Biz ba'zi metodlar bilan avvalgi darslarimizda tanishdik. Bir klassga tegishli metodlar, boshqa klassdagi obyketlar uchun mavjud bo'lmasligi tabiiy. Misol uchun matnlar uchun mavjud metodlarni, butun yoki o'nli sonlarga qo'llab bo'lmaydi.
In [4]:
matn = "salom"
print(matn.upper())
SALOM
In [5]:
son = 20
print(son.lower())
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) in 1 son = 20 ----> 2 print(son.lower()) AttributeError: 'int' object has no attribute 'lower'
Keling endi o'zimizning klasslarimizni yaratishni ko'ramiz.
KLASS YARATISH
Yangi klass yaratish uchun class operatoridan foydalanamiz va klassimizga tushunarli nom beramiz. Esingizda bo'lsin, klass bu hali obyekt emas, bu obyekt uchun shablon. Shuning uchun klass yaratishda shu klassdagi obyektlar uchun umumiy bo'lgan xususiyatlar va funksiyalarni o'ylashimiz kerak.
Keling, Talaba degan klass yaratamiz:
In [6]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
Kodimizni tahlil qilamiz:
class Talaba — Talaba nomli klass yaratdik. Klasslarga nom berishda uning birinchi harfini katta harfdan boshlash tavsiya qilinadi. Agar klass nomi 2 va undan ko'p so'zdan iborat bo'lsa har bir so'zni katta harf bilan boshlang.
def __init__(self) — klassga tegishli xususiyatlarni saqlovchi maxsus metod (funksiya). self kalit so'zi ingliz tilidan "o'zi" deb tarjima qilinadi, va bu klassdan yaratilgan obyektning o'ziga ishora qiladi. Ya'ni keyinchalik biz obyekt ichidagi metodga murojat qilganimizda shu obyektning o'zi birinchi bo'lib funksiyaga argument sifatida uzatiladi, obyket ustida turli amallar bajarish imkonin beradi
def __init__(self,ism,familiya,tyil) — yaratayotgan klassimizga xos xususiyatlarni def __init__(self) funksiyasiga argument sifatida uzatamiz. Bizning Talaba klassimiz ism, familiya va tug'ilgan yilga ega bo'ladi.
Keyingi qatorlarda esa self.xususiyat = argument komandasi yordamida uzatilgan argumentlarni klassning xususiyatlari bilan bo'glayapmiz. Bu yerda xususiyat nomi uzatilgan argument nomi bilan mos tushishi shart emas, unga istalgan nom berishimiz mumkin (masalan self.name = ism)
KLASSDAN OBYEKT YARATAMIZ
K lassimiz tayyor, keling endi klassimizdan yangi obyekt yaratamiz.
In [7]:
talaba1 = Talaba("Alijon","Valiyev",2000)
Mana, talaba1 obyektimiz tayyor. Obyektni yaratish uchun Talaba klassiga murojat qildik va talabaning ismi, familiyasi va tug'ilgan yilini parameter sifatida uzatdik.
OBYKETNING XUSUSIYATLARINI KO'RISH
Obyektning xususiyatlarini ko'rish uchun nuqta orqali murojat qilishimiz mumkin.
In [8]:
print(talaba1.ism)
Alijon
In [9]:
print(talaba1.familiya)
Valiyev
Yuqoridagi klassdan biz istalgancha obyektlar yaratishimiz mumkin:
In [10]:
talaba2 = Talaba("Olim","Olimov",1995)
talaba3 = Talaba("Husan","Akbarov",2004)
talaba4 = Talaba("Hasan","Akbarov",2004)
Bunda har bir obyekt o'zining alohida xususiyatlariga ega bo'ladi.
In [11]:
print(talaba2.ism)
Olim
In [12]:
print(talaba4.familiya)
Akbarov
KLASSGA METODLAR QO'SHAMIZ
Obyektimizning xususiyatlarini aniqlab oldik, keling endi obyekt bajarishi kerak bo'lgan metodlarni ham qo'shaylik.
In [13]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
def tanishtir(self):
print(f"Ismim {self.ism} {self.familiya}. {self.tyil} yilda tu'gilganman")
Boshlanishiga klassimizga bitta, tanishtir metodini qo'shdik. Bu metodimiz ko'rib turganingizdek bitta self (ya'ni obyektning o'zini) argumentini qabul qiladi va talaba haqidagi ma'lumotlarni konsolga chiqaradi.
OBYEKTNING METODLARIGA MUROJAT QILAMIZ
Obyekt ichidagi funksiyaga ya'ni obyektning metodiga murojat qilamiz:
In [14]:
talaba4 = Talaba("Hasan","Akbarov",2004)
talaba4.tanishtir()
Ismim Hasan Akbarov. 2004 yilda tu'gilganman
Klassimiz istalgancha metodlardan iborat bo'lishi mumkin:
In [15]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
def get_name(self):
"""Talabaning ismini qaytaradi"""
return self.ism
def get_lastname(self):
"""Talabaning familiyasini qaytaradi"""
return self.familiya
def get_fullname(self):
"""Talabaning ism-familiyasini qaytaradi"""
return f"{self.ism} {self.familiya}"
def tanishtir(self):
print(f"Ismim {self.ism} {self.familiya}. {self.tyil} yilda tu'gilganman")
In [16]:
talaba1 = Talaba("Alijon","Valiyev",2000)
print(talaba1.get_fullname())
Alijon Valiyev
ARGUMENT QABUL QILUVCHI METODLAR
Yuqoridagi misolimizda barcha metodlar faqatgina self parametrini qabul qilishayapti. Aslida, barcha funksiyalar kabi, klass ichidagi obyektlarni ham boshqa argumentlar qabul qiladigan qilib yozish mumkin.
In [17]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
def get_name(self):
"""Talabaning ismini qaytaradi"""
return self.ism
def get_lastname(self):
"""Talabaning familiyasini qaytaradi"""
return self.familiya
def get_fullname(self):
"""Talabaning ism-familiyasini qaytaradi"""
return f"{self.ism} {self.familiya}"
def get_age(self,yil):
"""Talabaning yoshini qaytaradi"""
return yil-self.tyil
def tanishtir(self):
print(f"Ismim {self.ism} {self.familiya}. {self.tyil} yilda tu'gilganman")
Yuqorida klassimizga yangi get_age(self, yil) metodini qo'shdik. Bu metod obyektning o'zidan tashqari, qo'shimcha, yil argumentini ham qabul qiladi va talabaning yoshini qaytaradi.
In [18]:
talaba1 = Talaba("Alijon","Valiyev",2000)
print(talaba1.get_age(2021))
21
pass OPERATORI
Pythonda hech qanday vazifani bajarmaydigan pass operatori mavjud. Bu operatordan bo'sh metodlar yaratishda foydalanish mumkin. Misol uchun siz klassingiz uchun muhim metodlarni bilasiz, lekin metod badani hali tayyor emas. Agar metod badanini bo'sh qoldirsangiz, Python IndentationError xatosini qaytaradi. Shunday xolatlarda, funksiya badaniga pass operatorini qo'yib ketishimiz mumkin:
In [19]:
class User:
def __int__(self,name,username,email):
self.name = name
self.uname = username
self.mail = email
def describe():
pass
def get_email():
pass
Yuqoridagi klassimizda describe() va get_email() funksiyalar badani hali tayyor emas, bo'shliqni to'ldirish uchun esa pass operatoridan foydalanganmiz.
pass operatoridan if-else, for, while operatorlari badanida ham foydalanish mumkin.
AMALIYOT
Web sahifangiz uchun foydalanuvchi (user) klassini tuzing. Klassning xususiyatlari sifatida odatda ijtimoiy tarmoqlar talab qiladigan ma'lumotlarni kiriting (ism, foydalanuvchi ismi, email, va hokazo)
Klassga bir nechta metodlar qo'shing, jumladan get_info() metodi foydalanuvchi haqida yig'ilgan ma'lumotlarni chiroyli qilib chiqarsin (masalan: "Foydalanuvchi: alijon1994, ismi: Alijon Valiyev, email: alijon1994@gmail.com).
Klassdan bir nechta obyektlar yarating va uning xususiyatlari va metodlariga murojat qiling.
29-DARS. OBYKETLAR BILAN ISHLASH
Obyektlar bilan ishlashni o'rganamiz.
XUSUSIYATLARGA STANDART QIYMAT BERISH
Avvalgi darsizmida biz klass yaratish, unga xususiyatlar va metodlar qo'shishni ko'rdik. Klassdan obyekt yaratganimizda esa uning xususiyatlarini parametr sifatida uzatishni o'rgandik.
Pythonda obyektning ba'zi xususiyatlarini parametr yordamida uzatmasdan, klass yaratishda unga standart qiymat berib ketishimiz mumkin. Keling, Talaba klassimizga qaytamiz. Bu klassimiz 3 ta xususiyatga ega edi: ism, familiya, tyil. Biz yana bitta qo'shimcha, bosqich nomli xususiyat qo'shamiz, va unga standart qiymat sifatida 1 beramiz, e'tibor qiling bu xususiyat obyekt yaratilishida parametr sifatida uzatilmaydi:
In [4]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
self.bosqich = 1
def get_info(self):
return f"{self.ism} {self.familiya}. {self.bosqich}-bosqich talabasi "
Endi, Talaba klassidan yangi obyekt yaratganimizda har bir yangi talabaning kursi 1 ga teng bo'ladi.
In [5]:
talaba1 = Talaba("Alijon","Valiyev",2000)
print(talaba1.get_info())
Alijon Valiyev. 1-bosqich talabasi
STANDART QIYMATNI O'ZGARTIRISH
Obyektning standart qiymatiga ham boshqa xususiyatlar kabi nuqta orqali murojat qilishimiz va uning qiymatini almashtirishimiz mumkin:
In [6]:
talaba1.bosqich= 2
print(talaba1.bosqich)
2
Yana boshqa usuli, obyekt xususiyatini yangilovchi metod yozish.
In [9]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
self.bosqich = 1
def get_info(self):
"""Talaba haqida ma'lumot"""
return f"{self.ism} {self.familiya}. {self.bosqich}-bosqich talabasi "
def set_bosqich(self,bosqich):
"""Talabaning kursini yangilovchi metod"""
self.bosqich = bosqich
Metodga murojat qilamiz:
In [11]:
talaba1 = Talaba("Alijon","Valiyev",2000)
talaba1.set_bosqich(3)
print(talaba1.get_info())
Alijon Valiyev. 3-bosqich talabasi
Umuman olganda xususiyatlarni yangilashda turli usullardan foydalanish mumkin. Misol uchun talabaning bosqichi odatda 1 tadan ko'payib boradi, shuning uchun quyidagicha metod ham yozishimiz mumkin:
In [12]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
self.bosqich = 1
def get_info(self):
"""Talaba haqida ma'lumot"""
return f"{self.ism} {self.familiya}. {self.bosqich}-bosqich talabasi "
def set_bosqich(self,bosqich):
"""Talabaning kursini yangilovchi metod"""
self.bosqich = bosqich
def update_bosqich(self):
"""Talabanining bosqichini 1taga ko'paytirish"""
self.bosqich += 1
update_bosqich() metodiga murojat qilganimizda talabning bosqichi oshib boradi:
In [15]:
talaba1 = Talaba("Alijon","Valiyev",2000)
print(talaba1.get_info())
Alijon Valiyev. 1-bosqich talabasi
In [16]:
talaba1.update_bosqich() # 1 bosqichga oshiramiz
print(talaba1.get_info())
Alijon Valiyev. 2-bosqich talabasi
In [14]:
talaba1.update_bosqich() # 1 bosqichga oshiramiz
print(talaba1.get_info())
Alijon Valiyev. 3-bosqich talabasi
OBYEKTLAR O'RTASIDA MUNOSABAT
Obyektga yo'naltirilgan dasturlashning afzalligi, turli obyektlar o'rtasida o'zaro munosabatlarni oson yo'lga qo'yish mumkinligida. Buni misolda ko'rish uchun, yangi Fan degan klass yaratamiz va fanimizga talabalar qo'shish imkoniyatini ham yaratamiz (add_student() metodi):
In [17]:
class Fan():
def __init__(self,nomi):
self.nomi = nomi
self.talabalar_soni = 0
self.talabalar = []
def add_student(self,talaba):
"""Fanga talabalar qo'shish"""
self.talabalar.append(talaba)
self.talabalar_soni += 1
E'tibor bering, Fan klassi faqatgina yagona nomi degan parametrga ega. Qolgan xususiyatlariga esa standart qiymat berilgan: talabalar soni (self.talabalar_soni) 0 ga teng, talabalar ro'yxati (self.talabalar) esa bo'sh.
Fanimizga talaba qo'shish uchun dd_student() metodini chaqiramiz. Bu metod parametr sifatida Talaba obyektini qabul qiladi va uni talabalar ro'yxatiga qo'shadi. Shuningdek, bu metod yangi talaba qo'shilganda talabalar_soni ni 1 taga oshirib qo'yadi.
Keling boshlanishiga yangi fan obyektini va bir nechta talabalarni yaratamiz:
In [35]:
matematika = Fan("Oliy Matematika")
talaba1 = Talaba("Alijon","Valiyev",2000)
talaba2 = Talaba("Hasan","Alimov",2001)
talaba3 = Talaba("Akrom","Boriyev",2001)
Talabalarni yangi fanimizga qo'shamiz:
In [26]:
matematika.add_student(talaba1)
matematika.add_student(talaba2)
matematika.add_student(talaba3)
Mana, fanimiz tayyor, talabalar qo'shildi. Keling endi fan haqida ma'lumotlarni olamiz:
In [20]:
print(matematika.talabalar_soni)
3
Fanimizga 3 ta talaba qo'shilibdi. Talabalar haqida ma'lumot olsak bo'ladimi?
In [21]:
print(matematika.talabalar)
[<__main__.Talaba object at 0x7f8cdabeeb80>, <__main__.Talaba object at 0x7f8cdabeea00>, <__main__.Talaba object at 0x7f8cdabee8b0>]
Talabalarning ismi familiyasi o'rniga qandaydur tushunarsiz ma'lumotlar. Aslida hammasi to'g'ri, yuqorida fanimizga yangi talabalarni obyekt sifatida qo'shgan edik, yuqoridagi natija esa matematika.talabalar ro'yxatida Talaba klassiga oid 3 ta obyekt borligini ko'rsatayapti.
Fanimizga yozilgan talabalar haqida tushunarli ma'lumot olish uchun esa Fan klassiga yana bir, get_students() degan, yangi metod qo'shamiz. Bu metod talabalar ichidagi har bir talaba obyektiga murojat qilib, get_info() metodi yordamida talabaning ma'lumotlarini oladi, ro'yxatga qo'shadi va shu ro'yxatni qaytaradi:
In [22]:
class Fan():
def __init__(self,nomi):
self.nomi = nomi
self.talabalar_soni = 0
self.talabalar = []
def add_student(self,talaba):
"""Fanga talabalar qo'shish"""
self.talabalar.append(talaba)
self.talabalar_soni += 1
def get_students(self):
return [talaba.get_info() for talaba in self.talabalar]
Shu o'rinda Pythonda ro'yxatlar bilan ishlashning qulayliklaridan birini ham ko'rsatib o'tsak. Yuqoridagi kodimizning oxirgi qatorida e'tibor bersangiz, biz yangi ro'yxat shakllantirishda 1 qator koddan foydalandik:
In [ ]:
[talaba.get_info() for talaba in self.talabalar]
Kodimizni tahlil qilsak, self.talabalar ichidagi har bir talaba uchun get_info() metodini bajar degan ma'no kelib chiqadi. Kodni kvadrat qavslar ichiga olganimiz uchun esa, har bir tsikl natijasi avtomat ravishda ro'yxatga qo'shib boriladi.
Mana endi metodga murojat qilib, talabalar haqida ma'lumot olishimiz mumkin:
In [27]:
mat_talabalar = matematika.get_students()
print(mat_talabalar)
['Alijon Valiyev. 1-bosqich talabasi ', 'Hasan Alimov. 1-bosqich talabasi ', 'Akrom Boriyev. 1-bosqich talabasi ']
Shunday qilib biz ikki bir-biriga bog'liq bo'lmagan obyektlar ustida turli munosabatlar o'rnatishimiz mumkin.
NUQTA YOKI METOD?
Pythondagi obyketlarning o'ziga xos xususiyatlaridan biri, obyektning xususiyatiga nuqta orqali murojat qilish mumkin. Misol uchun avval yaratagn talaba1 obyektining ismini bilish uchun talaba1.ism deb yozish kifoya.
Bu o'ziga yarasha qulay bo'lsada, bu usuldan foydalanmagan afzal. Sababi, vaqt o'tib klassingiz takomillashishi, uning ba'zi xususiyatlari o'zgarishi, o'chirilishi yoki almashtirilishi mumkin. Shunday holatlarda nuqta orqali murojat qilish siz kutgan natijani bermasligi va dastur xato ishlashiga olib kelishi mumkin. Bunday holatlarning oldini olish uchun esa, obyektning xususiyatlarini metod orqali olishni odat qilish tavsiya qilinadi. Huddi shu kabi, obyektning xususiyatlarini yangilash uchun ham alohida metodlar yozga afzal.
Dasturchilar orasida obyektning xususiyatlarini o'zgartiradigan metodlarni set (o'zgartir) so'zi bilan, xususiyatlarni qaytaradigan metodlarni esa get (olish) so'zi bilan boshlash qoida qilib olingan. Masalan: set_name() va get_name() kabi.
Agar yuqoridagi qoidalarga amal qilgan holda, Talaba klassimizni yangilaydigan bo'lsak, u tahminan shunday ko'rinishga ega bo'ladi:
In [34]:
class Talaba:
"""Talaba nomli klass yaratamiz"""
def __init__(self,ism,familiya,tyil):
"""Talabaning xususiyatlari"""
self.ism = ism
self.familiya = familiya
self.tyil = tyil
self.bosqich = 1
def set_bosqich(self,bosqich):
"""Talabaning kursini yangilovchi metod"""
self.bosqich = bosqich
def update_bosqich(self):
"""Talabanining bosqichini 1taga ko'paytirish"""
self.bosqich += 1
def get_info(self):
"""Talaba haqida ma'lumot"""
return f"{self.ism} {self.familiya}. {self.bosqich}-bosqich talabasi "
def get_name(self):
"""Talabaning ismini qaytaradi"""
return self.ism
def get_lastname(self):
"""Talabaning familiyasini qaytaradi"""
return self.familiya
def get_fullname(self):
"""Talabaning ism-familiyasini qaytaradi"""
return f"{self.ism} {self.familiya}"
def get_age(self,yil):
"""Talabaning yoshini qaytaradi"""
return yil-self.tyil
Huddi shu kabi, Fan klassimizning yakuniy ko'rinishi quyidagicha bo'ladi:
In [29]:
class Fan():
"""Fan nomli klass"""
def __init__(self,nomi):
self.nomi = nomi
self.talabalar_soni = 0
self.talabalar = []
def add_student(self,talaba):
"""Fanga talabalar qo'shish"""
self.talabalar.append(talaba)
self.talabalar_soni += 1
def get_name(self):
"""Fan nomi"""
return self.nomi
def get_students(self):
"""Fanga yozilgan talabalar haqida ma'lumot"""
return [x.get_info() for x in self.talabalar]
def get_students_num(self):
"""Fanga yozilgan talabalar soni"""
return self.talabalar_soni
OBYEKTNING XUSUSIYATLARI VA METODLARINI KO'RISH
Obyektlar bilan ishlaganda, o'z-o'zidan shu obyektga tegishli xususiyatlar va metodlarni bilish talab qilinadi. Agar obyekt tegishli bo'lgan klassni o'zimiz yaratgan bo'lsak, istalgan payt klass ichini ko'rib olishimiz mumkin. Lekin boshqalar yaratgan klass haqida ma'lumot olish talab qilinsa, buning bir nechta yo'li bor.
dir() FUNKSIYASI
dir() funksiyasi yordamida istalgan obyekt yoki klassning xususiyatlari va metodlarini ko'rib olishimiz mumkin:
In [31]:
dir(Talaba)
Out[31]:
['__class__',
'__delattr__',
'__dict__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__le__',
'__lt__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'get_age',
'get_fullname',
'get_info',
'get_lastname',
'get_name',
'set_bosqich',
'update_bosqich']
Lekin bunda har bir klass bilan keluvchi maxsus dunder metodlar ham chiqib keldi. Dunder metodlar ikki pastki chiziq (__) bilan boshlanadi va maxsus holatlar uchun saqlab qo'yilgan. Biz hozircha faqat __init__ metodi bilan tanishdik, qolganlari bilan keyingi darslarimizda yana ko'rishamiz. Dunder metodlardan keyin esa biz murojat qilishimiz mumkin bo'lgan metodlar ro'yxati kelgan.
Do'stlaringiz bilan baham: |