skip to navigation
skip to content

feed icon RSS хранилка

Пета задача

Публикувано на 25.04.2008 17:12 от Стефан
Последна промяна на 01.05.2008 18:55
Тази публикация е от предишно издание на курса, моля не разчитайте на актуалността на информацията.

Брой точки, които дава задачата: 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%, но поне ще ви гарантира, че не сте допуснали глупава грешка, която да ви коства всички точки.