Пета задача
Брой точки, които дава задачата: 5 + 3 (за елегантно решение).
Краен срок: 14 май 2008г., 19:00 часа.
Накратко
Да се напише клас за рационално число, който да поддържа стандартните операции, плюс няколко допълнителни.
Представяне и конструкция
- Класът да се казва
rational
(малка буква) - Да се конструира с две цели числа — числител и знаменател, в този ред:
rational(2, 3)
. - Да може да се конструира и само с едно цяло число. По стойност да е равно на него.
- Да има методи
num()
иden()
, които да връщат съответно числителя и знаменателя. - Числото винаги да се пази съкратено. Ако се конструира като
rational(4, 6)
, да се свежда доrational(2, 3)
. Това важи за всички операции — текстово представяне,num()
иden()
и прочее. - Ако числото е отрицателно, това значи отрицателен числител и положителен знаменател.
rational(2, -3)
да се преобразува доrational(-2, 3)
.rational(-1, -8)
доrational(1, 8)
. - Нулата се представя като
rational(0, 1)
. - Ако като втори аргумент на
rational()
бъде подадена0
, да се вдигаValueError
. - Във всички случаи на типово-некоректен вход на
rational()
и на неговите методи няма значение какво ще правите, тъй като няма да бъдат подавани типово-некоректни данни.
Операции
==, !=, <, <=, >, >=
. Учили сте математика, досещате се как тези операции трябва да бъдат дефинирани.+, -, /, *
. Събиране, изваждане, умножение и деление. Имплементирайте тези операции да работят и с цели числа (int, long), както от лявата, така и от дясната страна.**
. Повдигане на цяла степен. Недефинирана (без значение) за рационални или реални степени.- Унарен
-
. ~
. Реципрочност. Да се имплементира като~rational(1, 6) == rational(6, 1)
.~rational(0)
да вдигаValueError
.
Методи
str()
иrepr()
да връщат стрингове, подобни съответно на-1/3
иrational(-1, 3)
(няма да проверяваме това).lcd(other)
намира най-малкия общ знаменател на две рационални числа (връща цяло число)r.partition()
връща наредена двойка(x, y)
. x е най-голямото цяло число, по-малко по абсолютна стойност от r, а y е рационално число от интервала (-1, 1), така че x + y = r. Т.е.,rational(42, 9).partition() == (4, rational(2, 3))
. При 2/3 резултатът е(0, rational(2, 3))
. При 4 е(4, rational(0, 1))
, а при -6/5 ще имаме (-1, rational(1, 5)).int(), long(), float()
. Направете така, че вашите типове да могат да се конвертират до цели или реални числа. При целите закръглявате надолу, катоint(rational(6, 5))
е 1, ноint(rational(-6, 5))
е -1.
Елеганти решения
Ако смятате, че се сте справили много добре, моля кандидатствайте за елегантно решение. Този път има една уловка - ако искате бонус точки, трябва да имплементирате операциите за сравнение така, че да работят и с цели числа. Т.е. 2 == rational(4, 2)
да връща истина. За целта трябва да проучите как работи __coerce__.
Примерен тест
Връзка: p5-sample.py
Теста може да изпълните като свалите файла, заедно с него в една директория запазите своето решение, именувано p5.py
и изпълните p5-sample.py
. Крайната ви цел е да получите OK някъде из резултата.
Тестът не гарантира, че сте си решили задачата на 100%, но поне ще ви гарантира, че не сте допуснали глупава грешка, която да ви коства всички точки.