ПСИ/Јун 2022

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу

Јунски испит 2022. године одржан је 10. јуна. Трајао је 165 минута, укупно је носио 40 бодова (теоријски део 12, практични 28), практични део се радио већином на рачунару а теоријски у потпуности на папиру и радили су се истовремено. Штампана литература није била дозвољена, док је за радне оквире који су се користили на практичном делу (Дјанго, Ларавел, ЦодеИгнитер) била доступна документација. Текст испита доступан је са странице предмета, као и фајлови за имплементацију и скрипт базе.

1. задатак

Поставка

Размотримо следећи фрагмент написан на објектно-оријентисаном псеудојезику:

public class Button {
    private Lamp itsLamp;
    // other necessary instance variables
    public void poll() {
        if (/* some condition */)
            itsLamp.turnOn();
    }
    // other necessary methods
}
  1. Који СОЛИД принцип(и) дизајна су прекршени? Помоћ: класа Button не треба да види "изнутрице" класе Lamp.
  2. Поправити и допунити дати псеудокод да не крши СОЛИД принципе и да се правилно иницијализује инстанце класе Button.

Решење

СОЛИД принцип који је овде прекршен је Депенденцy Инверсион Принципле (ДИП), јер класа Button зависи од класе Lamp, која је класа нижег нивоа, директно, уместо преко апстракције. Исправљен код би изгледао овако:

abstract class Button {
    private ILamp itsLamp;
    public void poll() {
        if (/* some condition */)
            itsLamp.turnOn();
    }
    public Button(ILamp itsLamp) {
        this.itsLamp = itsLamp;
    }
}
interface ILamp {
    void turnOn();
}

2. задатак

Поставка

Жели се имплементирати скуп целих бројева (класа TreeSet) помоћу бинарног стабла претраге, чији су чворови описани класом Node. Дат је непотпун УМЛ дијаграм који описује такву имплементацију.

Дијаграм из поставке другог задатка.
  1. Која од следећих ограничења се могу изразити кардиналностима на дијаграму? За она која могу заокружите Т и унесите кардиналност на дијаграм, а за она која не могу заокружите Ф.
    1. [Т / Ф] Стабло састављено од Node чворова је ациклично.
    2. [Т / Ф] А TreeSet може бити празан скуп.
    3. [Т / Ф] Чвор Node не мора имати деце.
    4. [Т / Ф] Чвор Node може имати једно дете.
    5. [Т / Ф] Чвор Node може имати највише двоје деце.
    6. [Т / Ф] Стабло чворова Node је уравнотежено, тако да пут од кореног чвора до најудаљенијег листа није више него двоструко дужи од путање од кореног чвора до најближег листа.
    7. [Т / Ф] Чворови Node не деле се међу различитим TreeSet скуповима.
    8. [Т / Ф] Цео број се може појавити у било ком TreeSet скупу.
    9. [Т / Ф] Сваки чвор Node има тачно један целобројни кључ.
    10. [Т / Ф] Подстабла се не деле у оквиру стабла Node чворова.
    11. [Т / Ф] TreeSet нема више од једног кореног чвора.
  2. За класе TreeSet и Node напишите одговарајуће моделе у неком ОРМ фрејмворку који је помињан на предавањима и вежбама.

Решење

Решења ставки првог задатка су следећа:

  1. (Ф) Стабло састављено од Node чворова је ациклично. (УМЛ не може да гарантује да се у објектима не може наћи циклус)
  2. (Т) А TreeSet може бити празан скуп. (На дијаграму код root стоји 0-1, дакле може да нема чвора ту)
  3. (Т) Чвор Node не мора имати деце. (На дијаграму код children стоји 0-2, дакле може да нема деце ту)
  4. (Т) Чвор Node може имати једно дете. (На дијаграму код children стоји 0-2, дакле може да има једно дете ту)
  5. (Т) Чвор Node може имати највише двоје деце. (На дијаграму код children стоји 0-2, дакле може да има двоје деце ту, али не може троје и више)
  6. (Ф) Стабло чворова Node је уравнотежено, тако да пут од кореног чвора до најудаљенијег листа није више него двоструко дужи од путање од кореног чвора до најближег листа. (Ово не може да се осигура УМЛ кардиналностима)
  7. (Т) Чворови Node не деле се међу различитим TreeSet скуповима. (На дијаграму је на релацији TreeSetNode додата кардиналност на страни стабла)
  8. (Т) Цео број се може појавити у било ком TreeSet скупу. (На дијаграму је на страни Node код везе са Integer постављено *)
  9. (Т) Сваки чвор Node има тачно један целобројни кључ. (На страни Integer стоји 1)
  10. (Т) Подстабла се не деле у оквиру стабла Node чворова. (Исти разлог као под 7)
  11. (Т) TreeSet нема више од једног кореног чвора. (На дијаграму код root стоји 0-1, дакле може да не више од једног чвора ту)
Допуњени дијаграм из другог задатка.

Решење друге ставке задатка је следеће:

class TreeSet(models.Model):
    root = models.ForeignKey(Node, null=True, on_delete=models.CASCADE)

class Node(models.Model):
    tree = models.ForeignKey(TreeSet, on_delete=models.CASCADE)
    value = models.IntegerField()
    child1 = models.OneToOneField(Node, on_delete=models.CASCADE)
    child2 = models.OneToOneField(Node, on_delete=models.CASCADE)

3. задатак

Поставка

Посматра се информациони систем за услуге резервисања рафтинга, смештаја за рафтинг и додатних активности. Систем омогућава пријаву која захтева избор рафтинг туре, броја ноћења, броја гостију и опциони избор једне или више додатних активности.

Свака рафтинг тура има свој назив и цену. Исто важи и за сваку од додатних активности. Цена ноћења зависи од броја ноћења, тако да су ниже цене ако се резервише већи број ноћења. За сваку од изабраних додатних активности, као и за рафтинг који је обавезно укључен, потребан је по један дан боравка, тако да систем при пријави резервације, осим провере да ли су сва захтевана поља попуњена, треба да провери и да ли је изабрани број ноћења одговарајући. Пријава је валидна и ако је изабрани број ноћења такав да неки дани буду без активности или није изабрана ниједна додатна активност. Обавезно поље Носилац пријаве треба да садржи име и презиме особе која је главни гост који резервише туру, а број гостију (укључујући носиоца) је обавезно поље где треба уписати нумеричку вредност између 2 и 10.

У случају да је форма за пријаву исправно попуњена, обрачунава се и на новој страници приказује укупна цена боравка и кориснику даје опција да потврди резервацију или се врати на страницу за креирање пријаве. Укупна цена се рачуна на основу цене ноћења, рафтинг туре, укључених додатних активности и броја гостију . У случају повратка на страницу за креирање пријаве, претходни садржај форме за пријаву треба да буде сачуван. Ако корисник потврди да жели резервацију, подаци из форме за резервацију и укупна цена боравка се чувају и приказује се почетни екран са поруком о успешној пријави.

У случају да форма за пријаву није била исправно попуњена, на истој страници се приказује порука о грешци, без брисања садржаја форме за пријаву. Порука треба да кратко и јасно образложи каква је грешка направљена при попуњавању пријаве (није попуњено једно или више поља, изабрано више додатних активности него што је могуће на основу броја ноћења итд.).

  1. Реализовати МВЦ (Модел-Виеw-Цонтроллер) апликацију коришћењем програмског језика ПХП или Пyтхон. Имплементацију је могуће радити коришћењем објектно оријентисаног ПХП кода, или коришћењем радних оквира ЦодеИгнитер, Ларавел или Дјанго МТВ (Модел-Темплате-Виеw). Апликација је потребно да садржи искључиво део система који се односи на пријаву рафтинг туре.
    Очекивани резултат задатка 3а): читав пројекат веб апликације компримовати у ЗИП архиву и ископирати на диск Рад (L:). Исто је потребно урадити и уколико се ради у радном оквиру.
  2. Коришћењем алата Селениум ИДЕ, написати тест примере којим ћете тестирати форму за пријаву рафтинг туре, која је описана у тексту задатка и имплементирана у тачки а).
    Очекивани резултат задатка 3б): пројекат окружења Селениум ИДЕ, са свим тестовима, снимити као фајл са екстензијом .сиде и прекопирати на диск Рад (L:) . Довољно је тестове покренути само у окружењу Гоогле Цхроме или Мозилла Фирефоx.
  3. Нацртати дијаграм секвенце за функционалност пријаве рафтинг туре, према описаној спецификацији система.
    Очекивани резултат задатка 3ц): дијаграме нацртати на овом папиру.

Решење

  • Дјанго и Селениум ИДЕ пројекат као и СтарУМЛ дијаграм
    • За покретање потребно је следеће:
      1. Направити rafting базу
      2. Имати Дјанго инсталиран на рачунару
      3. У jun2022/settings.py изменити креденцијале за базу са is1 / tubic на корисника који постоји и његову лозинку
      4. Закоментарисати поља rafting_putanja и dodatne_aktivnosti у rafting/forms.py
      5. Покренути python manage.py migrate
      6. Откоментарисати горенаведене линије
      7. Покренути python manage.py shell а у њему покренути:
        from db_init import init
        init()
        exit()
        
      8. Покренути python manage.py runserver
      9. Посетити http://127.0.0.1:8000
  • ЦодеИгнитер пројекат и СQЛ скрипта (Решење 1)
    • За покретање потребно је следеће:
      1. Покренути СQЛ скрипту која ће направити базу и попунити је подацима
      2. У app/Config/Database.php изменити креденцијале за базу са is1 / tubic на корисника који постоји и његову лозинку
      3. Имати Цомпосер инсталиран
      4. Покренути composer install како би се инсталирати потребни пакети за пројекат
      5. Покренути php spark serve
      6. Посетити http://127.0.0.1:8080
Дијаграм секвенце тражен у трећој ставци трећег задатка.