Shanraq.org Shanraq.org
Есептегі сандар: пішімдер, дөңгелектеу және өлшем бірліктері
IT

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

Есептегі сандар: пішімдер, дөңгелектеу және өлшем бірліктері

Python курсының отыз бесінші сабағы. `1234567.891` пен `1 234 567,89` — бір сан және екі түрлі есеп. Пішім жолдары, бізше бөлгіштер, жұпқа қарай дөңгелектейтін `round`, ақшаға арналған `Decimal` және дөңгелектелген сомаға тең келмейтін дөңгелектелгендердің сомасы.

Не үшін керек

Есеп жиналды, бет ашылады, ал ұяшықта 11.539999999999999 тұр. Немесе 1234567.891 — оқырман үш саннан бөліп көзбен санайтын, әрі бәрібір қателесетін сан.

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

Бірден тұтас

chisla.py файлы.

"""35-сабақ: есептегі сандар.

Бір санның жеті түрлі көрінісі және есептің қорытындысын шатастыратын үш
дөңгелектеу тұзағы.
"""

from decimal import Decimal, ROUND_HALF_UP

amount = 1234567.891

print("== бір сан, жеті түрі")
print("сол күйінде:     ", amount)
print("екі белгі:       ", f"{amount:.2f}")
print("бөлгішпен:       ", f"{amount:,.2f}")
print("бізше:           ", f"{amount:,.2f}".replace(",", " ").replace(".", ","))
print("миллионмен:      ", f"{amount / 1_000_000:.1f} млн")
print("таңбасымен:      ", f"{amount:+,.0f}")
print("ені 16 бағанда:", f"|{amount:>16,.2f}|")

print()
print("== үлес: пайыз — бұл пішім, көбейту емес")
share = 0.1274
print("қолмен:", round(share * 100, 1), "% | пішіммен:", f"{share:.1%}")

print()
print("== бірінші тұзақ: round жұпқа қарай дөңгелектейді")
for value in (0.5, 1.5, 2.5, 3.5):
    print(f"  round({value}) = {round(value)}")
print("  бұл қате емес, ереже: жартылар жұпқа кетеді")

print()
print("== екінші тұзақ: ақша үшін Decimal алынады")
money = Decimal("2.675")
print("  round(2.675, 2) =", round(2.675, 2), "— екілік бөлшек 2.675-ке тең емес")
print("  ROUND_HALF_UP бар Decimal =", money.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))

print()
print("== үшінші тұзақ: дөңгелектелгендердің сомасы ≠ дөңгелектелген сома")
rows = [10.005, 10.005, 10.005, 10.005]
rounded = [round(value, 2) for value in rows]
print("  жолдар:", rounded)
print("  дөңгелектелгендердің сомасы:", round(sum(rounded), 2))
print("  дөңгелектелген сома:", round(sum(rows), 2))
print("  айырма:", round(sum(rows) - sum(rounded), 2))

Шығысы:

== бір сан, жеті түрі
сол күйінде:      1234567.891
екі белгі:        1234567.89
бөлгішпен:        1,234,567.89
бізше:            1 234 567,89
миллионмен:       1.2 млн
таңбасымен:       +1,234,568
ені 16 бағанда: |    1,234,567.89|

== үлес: пайыз — бұл пішім, көбейту емес
қолмен: 12.7 % | пішіммен: 12.7%

== бірінші тұзақ: round жұпқа қарай дөңгелектейді
  round(0.5) = 0
  round(1.5) = 2
  round(2.5) = 2
  round(3.5) = 4
  бұл қате емес, ереже: жартылар жұпқа кетеді

== екінші тұзақ: ақша үшін Decimal алынады
  round(2.675, 2) = 2.67 — екілік бөлшек 2.675-ке тең емес
  ROUND_HALF_UP бар Decimal = 2.68

== үшінші тұзақ: дөңгелектелгендердің сомасы ≠ дөңгелектелген сома
  жолдар: [10.01, 10.01, 10.01, 10.01]
  дөңгелектелгендердің сомасы: 40.04
  дөңгелектелген сома: 40.02
  айырма: -0.02

Талдау

Пішім жолы: қос нүктеден кейін не тұрады

f"{amount:,.2f}" — фигуралық жақшаның ішінде, қос нүктеден кейін санды қалай көрсету керегі жазылған:

Жазу Не істейді
.2f нүктеден кейін әрқашан екі белгі
, мыңдық бөлгіш
+ оң санда да таңба
>16 ені 16 болып оңға туралау
.1% үлесті пайыз етіп: 0.12712.7%
,.0f бөлгіші бар бүтін сан

Мұның бәрі — кітапхана емес, тілдің өзі, әрі print-те де, f-жолда да, format()-та да бірдей істейді.

Бөлгіштер: бізде әдепкідей емес

Python әдепкі күйінде 1,234,567.89 деп жазады — мыңдықта үтір, бөлшекте нүкте. Бізде керісінше: мыңдықта бос орын, бөлшекте үтір. Мысалдағы тәсіл содан:

f"{amount:,.2f}".replace(",", " ").replace(".", ",")

Рет маңызды: алдымен үтірлер бос орынға айналады, сосын нүкте — үтірге. Керісінше жасасаңыз, былық шығады.

Бос орынды ажырамайтын етіп алған жөн (\u00a0): кәдімгі бос орынды браузер басқа жолға тасымалдайды, әрі 1 234 кестенің екі жолына бөлініп кетуі мүмкін.

Мұны өзі істей алатын locale модулі бар, бірақ ол бүкіл процеске бірден бапталады әрі жүйеде қандай локальдер тұрғанына тәуелді — серверде жұмыс істейтін бағдарламада бұл көбіне көмектеспей, кедергі келтіреді. Үш replace адалырақ.

Басты ереже: өлшем бірлігі әр ұяшықта емес, баған тақырыбында тұрады. Үстінде сома, ₸ және астында таза сандар оқылады, ал әр жолдағы 1 240 500,00 ₸ — жоқ.

round жұпқа қарай дөңгелектейді

Бірінші тұзақ, әрі бұл Python-ның қатесі емес: round(0.5) 0 береді, round(2.5) 2 береді, ал round(1.5) мен round(3.5)2 және 4. Жартылар жұпқа кетеді, әрі бұл — стандарт: дөңгелектеу көп болғанда қате бір жаққа жинақталмайды.

Мектептегідей «жартысы жоғары» керек болса, бұл — ROUND_HALF_UP бар Decimal.

Ақша — float емес, Decimal

round(2.675, 2) 2.68 емес, 2.67 береді. Кінәлі round емес, 2.675 санының екілік бөлшекте 2.675-тен сәл кем болуы (төртінші сабақ).

Ақша үшін Decimal("2.675") алынады — саннан емес, жолдан, — әрі анық дөңгелектеу ережесі бар quantize. Ереже қарапайым: ақшаны Decimal-мен немесе бүтін тиынмен санайды, ал float-ты физика мен статистикаға қалдырады.

Дөңгелектелгендердің сомасы ≠ дөңгелектелген сома

Үшінші тұзақ — есепте «бір тиын сәйкес келмейтін» сол тұзақ. 10.005-тен төрт жол: әрқайсысы 10.01-ге дөңгелектенеді, дөңгелектелгендердің сомасы — 40.04, ал дөңгелектелген сома — 40.02.

Мұнымен не істейді:

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

Жасауға болмайтыны — қорытындыны дөңгелектелген жолдармен санап, оны сома деп атау.

Масштаб: 1.2 млн қашан 1 234 567-ден жақсы

Адамға арналған есепте ірі сандарды әдетте мыңмен немесе миллионмен көрсетеді: 1.2 млн ₸ бір қараған бойда оқылады, 1 234 567 ₸ — жоқ. Бірақ салыстыратын не қосатын кестеде толық санды қалдырады: миллионға дейін дөңгелектеу кесте ашылған сол айырманы жасырады.

Қарапайым ереже: мәтін мен тақырыпта — ірі, кестеде — дәл.

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

Сабақ картасы: пішім, дөңгелектеу және өлшем

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

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

  1. round(2.5) неге 2 береді, әрі бұл қате ме?
  2. Дөңгелектелген жолдардың сомасы дөңгелектелген сомамен неге сәйкес келмеуі мүмкін?
  3. Өлшем бірлігі қайда тұруға тиіс — ұяшықта ма, баған тақырыбында ма?

Жаттығу

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

1. Болжаңыз. Бұл бағдарлама не басып шығарады?

amount = 45678.4
print(f"{amount:.0f}")
print(f"{amount:,.2f}")
print(f"{amount:+.1f}")
print(f"|{amount:>12,.1f}|")
print(f"{amount / 1000:.1f} мың")

2. Бос орынды толтырыңыз. ... орнына санды жергілікті түрге келтіріңіз: мыңдықта бос орын, бөлшекте үтір.

# әдепкі күйінде Python 1,234,567.89 деп жазады
amount = 1234567.891
print(f"{amount:,.2f}"...)

3. Түзетіңіз. Үлес 1274.0% болып басылды.

# пайыз — бұл пішім, әрі ол өзі көбейтеді
share = 0.1274
print(f"үлес: {share * 100:.1%}")

Тапсырма

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

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

бап                сома, ₸    үлес      өзгеріс, ₸
жалдау        1 240 500,00   67,4%       62 500,00
тамақ           348 210,34   18,9%      -12 400,00
жанармай        190 880,67   10,4%        4 300,00
байланыс         59 941,00    3,3%               —
барлығы       1 839 532,00  100,0%

тексеру:
  қорытынды дөңгелектеуге дейін есептелген: True
  дөңгелектелген жолдардың сомасы: 1 839 532,01
  дөңгелектелген қорытынды:        1 839 532,00
  айырма: 0.01
  үлестер қосындысы: 100,0%

Дайын болғаны: шығыс жол-жолымен сәйкес келеді; пішімдеу әр жолда қайталанбай, функцияларға шығарылған; қорытынды бастапқы сандардан есептеледі; айырма жасырылмай, есептеліп басылады.

Өз деректеріңізде. Ақшасы бар кез келген кестеңізді алып, оны екі рет басып шығарыңыз: қорытындысы дөңгелектелмегендермен және дөңгелектелген жолдармен. Сандар сәйкес келсе — жол санын көбейтіңіз, сонда олар ажырайды. Есепке қайсысын қоятыныңызды және қасына не жазатыныңызды алдын ала шешіңіз.

Қалауыңыз бойынша.

  • Кәдімгі бос орынды ажырамайтынға (\u00a0) ауыстырып, тар терезеде браузерде не өзгергенін қараңыз.
  • Сол сомаларды Decimal-мен санап, қорытындыны float-пен салыстырыңыз.
  • CSS-те бағанға font-variant-numeric: tabular-nums қосып, сандардың қалай тураланғанын қараңыз.

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

Он бесінші қадам: жиынтықта sholu/pishim.py пайда болады — санның мәтінге айналатын жалғыз орны. Үш функция: number — бізше бос орын мен үтір, signed — таңбасы бар өзгеріс (әрі дөңгелектелген нөл плюссіз), percent — сол үтірмен берілген үлес. Үшеуінде де жетіспейтін мән сызықшаға айналады.

Бет пішімдеуді баған атына қарап содан алады, әрі ұяшықта 8.690822 емес, 8,69 тұрады. Қоса стильде font-variant-numeric: tabular-nums жолы пайда болды: онсыз цифрлардың ені әртүрлі, әрі баған қанша пішімдесең де тураланбайды.

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

Жауаптар

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

Сұрақтарға

  1. Өйткені Python жартыларды жұпқа қарай дөңгелектейді: 0.50, 1.52, 2.52, 3.54. Бұл қате емес, стандарт: дөңгелектеу көп болғанда қате бір жаққа жинақталмайды. «Жартысы жоғары» ROUND_HALF_UP бар Decimal арқылы жасалады.
  2. Өйткені әр жол дөңгелектегенде өз жағына жылжиды, әрі бұл жылжулар қосылады. 10.005-тен төрт жол дөңгелектелгенде 40.04, ал дөңгелектелген сомамен 40.02 береді. Қорытындыны дөңгелектелмегендермен санайды, ал айырманы не көрсетеді, не ең үлкен жолға қосып жазады.
  3. Баған тақырыбында. Сонда ұяшықтағы сандар сан болып оқылады әрі разряды бойынша тураланады; әр жолда қайталанған өлшем көзге де, салыстыруға да кедергі.

Жаттығуға

  1. Әр пішім дәл бір нәрсе істейді: .0f бөлшек бөлігін алып тастайды, , бөлгіштерді қояды, + таңбаны көрсетеді, >12 ені бойынша туралайды, ал мыңға бөлу — бұл пішім емес, басқа өлшем бірлігі.
45678
45,678.40
+45678.4
|    45,678.4|
45.7 мың
  1. .replace(",", " ").replace(".", ",") — дәл осы ретпен.
amount = 1234567.891
print(f"{amount:,.2f}".replace(",", " ").replace(".", ","))
1 234 567,89
  1. :.1% жүзге өзі көбейтеді. Оған дейін көбейту — мұны екі рет жасау деген сөз.
share = 0.1274
print(f"үлес: {share:.1%}")
print(f"немесе былай: {share * 100:.1f} %")
үлес: 12.7%
немесе былай: 12.7 %

Тапсырмаға

Пішімдеу money мен percent-ке әдемілік үшін шығарылған жоқ: сомалар мен пайыздардағы бірдей үтір — кестені біртұтас ұстап тұрған нәрсе. Оны бір жерде өзгертсеңіз болды — кесте екі кестедей көріне бастайды.

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

Дереккөздер

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

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

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

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

Пікірлер (0)

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