Shanraq.org Shanraq.org
Айнымалылар мен типтер: «260» мен 260 неге екі басқа нәрсе
IT

Python: деректен өз есебіңізге дейін 4-сабақ (барлығы 56)

Айнымалылар мен типтер: «260» мен 260 неге екі басқа нәрсе

Python курсының төртінші сабағы. Бөтен файлдан дерек мәтінмен келеді, ал мәтін санға айналмайынша оны қосудың мағынасы жоқ: «260» + «260» 260260 береді. Ақшаның басты ережесі де өлшенді: 0.1 + 0.2 0.3-ке тең емес, ал Decimal — тең. Қоса None, сондай-ақ == пен is.

Не үшін керек

Бірінші сабақта біз сандарды Дүниежүзілік банктен алдық, олар дайын күйінде келді. Өмірде олай сирек болады: көбіне сандар жолмен келеді — CSV-ден, формадан, бөтен есептен. Сонда "260" мен 260 Python үшін екі басқа нәрсе екені, оларды бірдей қосу мүмкін емесі белгілі болады.

Сабақтың жазылуының екінші себебі: ақшаны мектепте үйреткендей санауға болмайды. Неге екенін шығыстың үшінші блогынан көресіз.

Бірден тұтас

tipter.py файлы. Іске қосу: ортадан python tipter.py.

Бағдарлама ұзын — алпыс жол. Есте ұстау керегі — бірінші жартысы: жолды санға айналдыру, ақшаны Decimal-мен санау. Қалғанын (None, ақиқаттық, is) бет-жүзінен танып қойса жеткілікті, кездескенде оралуға болады.

"""4-сабақ: айнымалылар мен типтер — жолмен келген сандарда.

CSV-ден, формадан және кәдімгі мәтіндік файлдан мәндер көбіне мәтінмен келеді.
Мәтін санға айналмайынша, оны қосудың мағынасы жоқ: жолдарды қосу күткен
нәрсені бермейді.
"""

from decimal import Decimal

# Айнымалы — мәннің аты. Атты кіші әріппен жазады, сөздерді астыңғы сызықпен
# бөледі: бүкіл Python-да солай қабылданған.
price_text = "260"
count = 2

print("== сырты бірдей, мәні басқа")
print("жол:", price_text, type(price_text))
print("сан:", 260, type(260))
print("жол + жол:", price_text + price_text)
print("сан + сан:", 260 + 260)

print()
print("== мәтінді санға айналдырамыз")
price = int(price_text)
print("int(\"260\"):", price, type(price))
print("бос орындармен де:", int("  260  "))
print("бөлшек:", float("260.5"), type(float("260.5")))
print("қайта мәтінге:", str(price) + " теңге")
print("сома:", price * count, "теңге")

print()
print("== ал мынау айналмайды")
try:
    int("260,5")
except ValueError as err:
    print("int(\"260,5\") →", type(err).__name__, "—", err)

print()
print("== ақшаны неге float-пен санамайды")
print("0.1 + 0.2 =", 0.1 + 0.2)
print("0.1 + 0.2 == 0.3 →", 0.1 + 0.2 == 0.3)
print("тиынға дейін дөңгелектедік:", round(0.1 + 0.2, 2))
print("Decimal-мен:", Decimal("0.1") + Decimal("0.2"))
print("Decimal шыншыл салыстырады →", Decimal("0.1") + Decimal("0.2") == Decimal("0.3"))

print()
print("== иә, жоқ және бос")
print("bool(0):     ", bool(0))
print("bool(260):   ", bool(260))
print('bool(""):    ', bool(""))
print('bool("0"):   ', bool("0"), "← жол бос емес, демек ақиқат")
print("bool(None):  ", bool(None))
print("None — нөл де, бос жол да емес:", None == 0, None == "")

print()
print("== салыстыру мен логика")
budget = 1000
print("екеуіне жетеді:", price * count <= budget)
print("жетеді әрі данасы 300-ден қымбат емес:", price * count <= budget and price <= 300)
print("не арзан, не аз:", price <= 100 or count <= 2)
print("300-ден қымбат емес:", not price > 300)

print()
print("== == мәндерді салыстырады, is — бір нысан ба")
first = [260, 2]
second = [260, 2]
print("first == second:", first == second)
print("first is second:", first is second)
print("first is first:  ", first is first)
nothing = None
print("бос мәнді дұрыс тексеру: nothing is None →", nothing is None)

Шығатыны:

== сырты бірдей, мәні басқа
жол: 260 <class 'str'>
сан: 260 <class 'int'>
жол + жол: 260260
сан + сан: 520

== мәтінді санға айналдырамыз
int("260"): 260 <class 'int'>
бос орындармен де: 260
бөлшек: 260.5 <class 'float'>
қайта мәтінге: 260 теңге
сома: 520 теңге

== ал мынау айналмайды
int("260,5") → ValueError — invalid literal for int() with base 10: '260,5'

== ақшаны неге float-пен санамайды
0.1 + 0.2 = 0.30000000000000004
0.1 + 0.2 == 0.3 → False
тиынға дейін дөңгелектедік: 0.3
Decimal-мен: 0.3
Decimal шыншыл салыстырады → True

== иә, жоқ және бос
bool(0):      False
bool(260):    True
bool(""):     False
bool("0"):    True ← жол бос емес, демек ақиқат
bool(None):   False
None — нөл де, бос жол да емес: False False

== салыстыру мен логика
екеуіне жетеді: True
жетеді әрі данасы 300-ден қымбат емес: True
не арзан, не аз: True
300-ден қымбат емес: True

== == мәндерді салыстырады, is — бір нысан ба
first == second: True
first is second: False
first is first:   True
бос мәнді дұрыс тексеру: nothing is None → True

Талдау

Айнымалы — мәннің аты

price_text = "260"
count = 2

= белгісі «тең» емес, «меншікте» деген сөз: оң жақта мән, сол жақта ат, енді ол сол атпен белгілі. Аттарды кіші әріппен жазады, сөздерді астыңғы сызықпен бөледі — PriceText емес, price_text. Бұл қыңырлық емес: бүкіл Python солай жазады, сондықтан бөтен код үйреншікті оқылады.

Тип — мәннің не істей алатыны

type() мәннің не екенін көрсетеді:

жол: 260 <class 'str'>
сан: 260 <class 'int'>

Экранда олар бірдей көрінеді. Ал өздерін басқаша ұстайды: "260" + "260" 260260 береді — жолдар жабысты; 260 + 260 520 береді.

Python бұл кезде ешқандай қате жасаған жоқ. Ол не қалағаныңызды болжамайды: жолдарды қосудың өз мағынасы бар, ол сол мағынаны пайдаланды. Байқамасаңыз, қатені сіз жасар едіңіз.

Ұзаққа жететін төрт тип: int — бүтін, float — жылжымалы нүктелі, str — жол, bool — ақиқат немесе жалған. Бесіншісі — None, ол туралы төменде.

Айналдырулар мен олардың шегі

int("260") сан береді. int(" 260 ") да: шеттегі бос орындарға шыдайды. Ал int("260,5") істей алмайды:

int("260,5") → ValueError — invalid literal for int() with base 10: '260,5'

Ондық бөлгіш ретіндегі үтір — қазақстандық және ресейлік жүктемелерде әдеттегі нәрсе, ал Python ол туралы білмейді. Мұндай жолды алдымен жөндейді (replace(",", ".")), содан кейін float-қа айналдырады.

Кері айналдыру — str(260) — санды мәтінге жабыстыру керек болғанда қажет. Дегенмен бұл үшін өткен сабақтағы f-жолды жиірек алады.

Елестетіп көріңіз. Қағазға жазылған телефон нөмірі мен қоңыраудың өзі. Қағазда бұл — мәтін: оны көшіруге, басқасына жабыстыруға болады. Тергенше, оған қоңырау шалу мүмкін емес.

Ақшаны неге float-пен санамайды

Сабақтағы ең маңыздысы:

0.1 + 0.2 = 0.30000000000000004
0.1 + 0.2 == 0.3 → False

Бұл Python-ның қатесі де, ерекшелігі де емес. float санды екілік жүйеде сақтайды, ал 0.1 екілікте — ондықтағы 1/3 сияқты шексіз бөлшек. Дөңгелектеуге тура келеді, ал үтірден кейінгі үшінші таңбада құйрық шығады.

График үшін бұл маңызды емес. Ақша үшін — маңызды: тиындар жиналады, содан чектің сомасы кассадағы қорытындымен сәйкес келмейді.

Екі шешім, екеуі де шығыста:

  • көрсеткенде дөңгелектеу: round(0.1 + 0.2, 2) 0.3 береді. Бухгалтерияға емес, адамға санағанда жарайды;
  • Decimal-мен санау: Decimal("0.1") + Decimal("0.2") дәл 0.3 береді, ал салыстыру True қайтарады. Назар аударыңыз: Decimal-ды float-тан емес, жолдан алады, — әйтпесе құйрық қосудан бұрын ішке түседі.

True, False және None

bool — екі мән: True мен False. Бірақ ақиқаттық бәрінде бар, тұзақ та осында:

bool(0):      False
bool(""):     False
bool("0"):    True ← жол бос емес, демек ақиқат
bool(None):   False

"0" жолы — ақиқат, өйткені ол бос емес. Мәтінмен келген дерек мұнда әсіресе құлықпен өтірік айтады: CSV-ден келген "0" if value: тексеруінде ақиқат болып шығады, нөлді білдірсе де.

None — «ештеңе жоқ» дегенді білдіретін бөлек мән. Бұл нөл де, бос жол да емес: None == 0 False береді. Ол деректе жетіспейтін мән болғанда керек — ал нағыз кестелерде жетіспейтін мән әрқашан бар.

and, or, not

Белгінің орнына үш сөз — сөйлем сияқты оқылады:

print("жетеді әрі данасы 300-ден қымбат емес:", price * count <= budget and price <= 300)

and — екеуі де ақиқат болғанда ақиқат. or — ең болмағанда біреуі. not — аударып тастайды. Күмәндансаңыз, жақша қойыңыз: олар тегін, ал кейін талдау қымбат.

== мәндерді, is нысандарды салыстырады

first == second: True
first is second: False

Ішіндегісі бірдей екі түрлі тізім тең, бірақ бұл бір нысан емес. == «іші бірдей ме» деп сұрайды, is — «бұл жадтағы бір нәрсе ме».

Тәжірибелік ереже: is тек None-мен қолданылады — if value is None:. Қалғанының бәріне ==. if value == None деп жазсаңыз, ол көбіне істейді, бірақ олай жазбайды.

Сабақ картасы

Сабақ картасы: мәтін, сан және ақиқат

Өз сөзіңізбен айтыңыз

Қарамай, дауыстап немесе қағазға жауап беріңіз. Жауаптар — сабақтың соңында.

  1. Нәтиже керегі емес болса да, "260" + "260" неге қате емес?
  2. 0.1 + 0.2-нің несі дұрыс емес және ақшаны қалай санау керек?
  3. bool("0") неге ақиқат?

Жаттығу

Тапсырмаға дейінгі үш қысқа қадам: болжау, толықтыру, жөндеу. Жауаптары — сабақтың соңында, бірақ алдымен өзіңіз жауап беріңіз.

1. Болжаңыз. Бұл жол не басып шығарады? + екі жағдайда әртүрлі жұмыс істейтініне назар аударыңыз.

print(int("8") + 1, "8" + "1")

2. Бос орынды толтырыңыз. ... орнына жолды float қабылдайтындай дайындаңыз.

text = " 1,15 "
clean = ...
print(float(clean))

3. Жөндеңіз. Мән бар, ол нөлге тең, ал бағдарлама мән жоқ дейді. Тексеруді дұрысымен ауыстырыңыз.

value = 0.0
print("мән жоқ:", not value)

Тапсырма

Міндетті. Берілгені:

first = " 1,15 "
second = "0,25"
third = None

Алғашқы екеуін санға айналдырыңыз: бос орындарды алып тастап, үтірді нүктеге ауыстырыңыз. Әрқайсысын типімен бірге басып шығарыңыз, содан кейін бөлек жолмен — үшіншісі бос па, сосын — нөл жетіспейтін мән па, ал соңында сомасын екі таңбамен және орташасын үш таңбамен.

Күтілетін шығу:

біріншісі: 1.15 кг, типі float
екіншісі: 0.25 кг, типі float
үшіншісі бос: True
ал нөл — бұл мән: False
барлығы 1.40 кг, орташа 0.700 кг

Дайын болғаны: шығу жол-жолмен сәйкес келеді; жетіспейтін мән «бос па» деп емес, is None арқылы тексеріледі; бірде-бір жол strip-сіз және үтірді ауыстырмай санға айналмайды.

Өз деректеріңізде. Чектен үш салмақты алыңыз — олар бөлшекпен жазылады, сабақ не үшін жазылғаны дәл соларда көрінеді: "1,15", " 0,25 ", "0,2" (килограмм). Әрқайсысын санға айналдырыңыз (екеуі жөндеуді қажет етеді), қосыңыз да, соманы екі таңбалы f-жолмен басып шығарыңыз. Содан кейін сол соманы Decimal арқылы санап, екі нәтижені == арқылы салыстырыңыз.

Басылған жолдар бірдей болады — екеуі де 1.60 көрсетеді, — ал == False қайтарады. Ақшаны неге Decimal-мен санайтынының жауабы осы.

Қалауыңызша.

  • Тексеріңіз: 0.1 + 0.2 + 0.3 == 0.6 ме? Ал round(0.1 + 0.2 + 0.3, 2) == 0.6 ше?
  • 5, 5.0, "5", True, None үшін type() басып шығарыңыз — бес түрлі жауап.
  • Бір бос орыннан тұратын " " жолы үшін bool(" ") нешеге тең екенін өз мысалыңызда анықтаңыз.

Жобада бұл қайда тұрады

Шолу бөтен деректе жұмыс істеудің бірінші ережесін алады: мәтінмен келді — санға келтір де, не шыққанын тексер. Әрі қарай бұл мәндерді тізімге, содан кейін кестеге жинаймыз.

Қарыздар. Бір жолды қолмен жөндедік, ал файлда олар мыңдап болады — бұл циклдер. Ештеңе сақтаған жоқпыз — бұл тізімдер мен сөздіктер. Оның үстіне «айналдыру шықпаса — жолды өткізіп жібер» дей алмаймыз: бұл — ерекше жағдайлар сабағы.

Жауаптар

Жауаптарды көрсету

Сұрақтарға

  1. Өйткені жолдарды қосудың өз мағынасы бар — жабыстыру, — Python соны пайдаланды. Ол ниетті болжамайды; типтерді жазған адам қадағалауға тиіс.
  2. float сандарды екілік жүйеде сақтайды, онда 0.1 — шексіз бөлшек, сондықтан 0.30000000000000004 құйрығы шығады. Адамға көрсету үшін round жетеді, ақша үшін Decimal алады да, оны жолдан жасайды. Ал float пен Decimal-ды == арқылы салыстыру — нашар келісім: не екеуін де керекті таңбаға дейін дөңгелектеңіз, не бірінші таңбадан соңғысына дейін Decimal-мен санаңыз.
  3. Өйткені жолдың ақиқаттығы мазмұнымен емес, ұзындығымен анықталады: "0" бос емес, демек ақиқат. Бос жол "" — жалған.

Жаттығуға

  1. 9 81. Сол жақта int("8") сан береді де, + қосады. Оң жақта екеуі де жол, әрі сол + оларды жабыстырады. Таңба біреу, әрекет екеу, айырманы тип шешеді.
9 81
  1. text.strip().replace(",", "."). Шеттегі бос орындарды float кешіреді, ал үтірді — жоқ: float("1,15") ValueError-мен құлайды.
text = " 1,15 "
clean = text.strip().replace(",", ".")
print(float(clean))
1.15
  1. not value «бос па» деп сұрайды, ал Python нөлді де, бос жолды да, бос тізімді де бос санайды. Мәннің болмауы — бұл None, әрі ол туралы тікелей сұрайды:
value = 0.0
print("мән жоқ:", value is None)
мән жоқ: False

Дереккөздер

Мәтінде қате не теру қатесі кездессе, бізге айтыңыз

Тапсырманы тексеру

Алдымен VS Code-та шешіп, іске қосыңыз — редактор қатені сол жерде көрсетеді. Дайын шешімді осында қойыңыз. Тексеретін — модель: ол қатені атап көрсетеді, бірақ дайын жауапты бермейді.

Тексеру үшін кіру керек. Кіру

Пікірлер (0)

Әзірге пікір жоқ. Бірінші болыңыз.