skip to navigation
skip to content

feed icon RSS хранилка

Четвърта задача

Публикувано на 20.03.2007 23:18 от Стефан
Последна промяна на 03.04.2007 1:11
Тази публикация е от предишно издание на курса, моля не разчитайте на актуалността на информацията.

Краен срок: 4 Април 2007, 19:00 часа
Тема на форумите с въпроси
Формуляр за изпращане

Да се напише клас представящ интервал от числа (с име Interval), който да отговаря на следните изисквания.
Концептуални изисквания:

  • Да работи с числа с плаваща запетая (float), но да е толерантен и към цели числа (т.е., да може да приема и int и long, преобразувайки ги до float).
  • Интервалите да са затворени.
  • Да поддържа отворени интервали към безкрайност, т.е. (-∞, 3], [4, +∞) и (-∞, +∞).
  • Да поддържа ред операции, които са изброени по-долу.

Изисквания към кода:

  • Класът да се казва Interval.
  • Да има двуаргументен конструктор, в който първият аргумент да е лявата граница, а втория - дясната. Ако вместо число се подаде None, тогава това да се третира като безкрайност.
  • Да дефинира repr по смислен начин - така че eval(repr(Interval)) да работи, ако името Interval съответства на вашия клас (т.е. да връща неща от рода на Interval(0, 10).

Да дефинира следните методи:

  • leftOpen() - да връща True или False в зависимост от това дали интервала е отворен отляво
  • rightOpen() - да връща True или False в зависимост от това дали интервала е отворен отдясно
  • open() - връща True ако интервала е отворен или от ляво, или от дясно, или от двете страни. Иначе False
  • left() - да връща границата на интервала отляво. В случай че leftOpen() връща True, този метод няма да се вика от клиентски код.*
  • right() - да връща границата на интервала отляво. В случай че rightOpen() връща True, този метод няма да се вика от клиентски код.*
  • expand(left=0, right=0) - разширява интервала от ляво или от дясно със съответната стойност. Аргументите са незадължителни. Interval(0, 10).expand(-1, 1) връща нов интервал Interval(1, 11). Ако от ляво или отдясно имате безкрайност, разширяването не се отразява по никакъв начин на тази страна. Ако интервал е невалиден (left() > right()), можете да върнете None или да хвърлите грешка (напр. ValueError).
  • intersect(interval) - взема интервал и връща сечението на двата интервала. Ако то е празно, връща None.
  • intersects(intarval) - взема интервал и връща дали той се пресича с този, на който метода е извикан. True или False.
  • contains(interval) - връща True или False в зависимост от това дали подадения като аргумент интервал се съдържа в този, върху който е извикан метода. Всеки интервал съдържа себе си. Interval(0, 10).contains(2, 5) == true.

Операции, които Interval трябва да дефинира.

  • == и != - Два интервала са равни, ако граничните им стойности са равни
  • in (n in interval) - Ако n е число, оператора връща дали то се съдържа в интервала; ако n е интервал, то оператора връща дали interval съдържа изцяло n.
  • hash - да има валидна хеш функция (дори тя да не е много ефективна)
  • len(interval) - връща дължината на интервала като цяло число, загръглено нагоре. При безкрайни интервали дължината е 0. Т.е., len(Interval(0, 3.5)) == 4), len(Interval(1, 2)) == 1, len(Interval(0, None)) == 0.
  • събиране (+) - Ако два интервала се пресичат, сбора им е най-малкия интервал който обхваща и двата. Например, Interval(0, 10) + Interval(5, 15) == Interval(0, 15). Ако не се пресичат, хвърляйте ValueError
  • изваждане (-) (interval1 - interval2) - връща интервал, който съдържа всички стойности на interval1, които не се съдържат в interval2 (без граничните стойности). Ако това изваждане би довело до два интервала, хвърляйте ValueError. Ако ще доведе до празен интервал, връщайте None. Например Interval(0, 10) - Interval(0, 5) == Interval(5, 10); Interval(1, 2) - Interval(0, 10) == None; Interval(0, 10) - Interval(3, 4) хвърля ValueError.
  • сравняване (<, >, <=, >=) - Дефинирайте a < b като „b съдържа a“ (аналогично a > b като „a съдържа b„). Т.е., един интервал е по-голям от друг, ако го съдържа изцяло. Два интервала са равни, ако съвпадат. a <= b ако a < b или a == b. Обърнете внимане, че има интервали които са несравними - Interval(0, 10) и Interval(5, 20). <, <=, >, >= и == връщат False за тези два интервала.

ВАЖНО: Нито един от методите не е мутатор, т.е., навсякъде връщайте нов интервал.

Забележки:
* Това значи, че ако един интервал е отворен отляво, не е легално да се вика метода му left(). Можете спокойно да връщате None, да хвърляте изключение или каквото си искате. Нещо като leftOpen() == false е precondition за извикване на left()