Skip to main content

Petlja publishing system

Project description

PetljaPub - систем за збирке задатака из програмирања

Систем PetljaPub служи за креирање збирки задатака, уџбеника и других едукативних материјала за учење програмирања. Решења задатака се могу писати на различитим програмским језицима и омогућено је њихово аутоматско тестирање пре укључивања у збирку. Збирке се граде укључивањем појединих задатака, њихових одабраних решења, као и пропратних текстова (најчешће прегледа теорије).

Изворни код поставки задатака и објашњења решења пише се у формату MarkDown. Одабир задатака и текстова који ће бити укључени у збирку врши се кроз датотеку у формату YAML.

Инсталација и конфигурација (configure)

Систем је имплементиран у језику Python и доступан је преко PyPI (https://pypi.org/project/petljapub/). За коришћење система неохподно је да је на рачунару инсталиран Python, у верзији бар 3.7. На рачунарима на којима је инсталиран Python, систем PetljaPub се може инсталирати из командне линије командом:

pip install petljapub

Да би систем било могуће користити потребно је да је из командне линије доступан преводилац за C++ (било GNU преводилац g++, било Microsoft-ов преводилац cl), који подржава стандард C++ 14. Пожељно је да уз C++ буде доступан и неки преводилац за C# (било Microsoft-ов преводилац csc или dotnet, било Mono преводилац mono или mcs) и преводилац за C (на пример, GNU преводилац gcc). За припрему штампаних верзија збирке потребно је и да је инсталиран и из командне линије доступан систем Pandoc (https://pandoc.org/).

Након инсталације система PetljaPub потребно је конфигурисати га командом petljapub configure. Након успешне конфигурације добија се порука следећег типа.

INFO: ---------- checking python --------------------
INFO: Found python3 3.8.10
INFO: ---------- checking C++ compilers -------------
INFO: Found g++ 8.4.0
INFO: ---------- checking C compilers ---------------
INFO: Found gcc 8.4.0
INFO: ---------- checking C# compilers --------------
INFO: Found mono 6.8.0.123
INFO: ---------- checking pandoc --------------------
INFO: Found pandoc 2.11.0.4
INFO: ---------- Final report  ----------------------
INFO: Configuration writen in /home/user/.config/petljapub/conf.json

Ако неки компилатор није пронађен, систем ће пријавити упозорење, али ће моћи да се користи његова функционалност која се не односи на тај компилатор. Ако из командне линије није доступан компилатор за C++ систем ће пријавити фаталну грешку приликом конфигурације и неће моћи да се користи док се не инсталира и не подеси компилатор за C++ и систем поново не конфигурише (командом petljapub configure).

Након конфигурације, систем се покреће и користи из командне линије, командом petljapub којој се наводе одговарајући параметри. Команде за рад са појединачним задатком се по правилу позивају из директоријума тог задатка, док се команде за рад са целом збирком (колекцијом задатака) по правилу позивају из кореног директоријума збирке.

Команде за рад са појединачним задатком

Сваки задатак мора бити смештен у директоријуму чији је назив почиње са две цифре из којих иде размак, црта или подвлака (нпр. коректни називи су 01 zadatak, 34_zadatak или 58-zadatak).

Креирање задатка (new)

Након креирања директоријума задатка, рад на новом задатку се започиње позиционирањем унутар тог директоријума и издавањем команде petljapub new. Њоме се креирају "клице" свих датотека, које је даље потребно модификовати. Опис појединачних датотека дат је у наставку овог документа.

Превођење програма (compile)

Превођење програма врши се командом petljapub compile <lang> или скраћено petljapub c <lang>. У склопу команде је потребно задати и ознаку програмског језика <lang> (то су најчешће cpp за C++, cs за C#, py за Python или c за C), а опционо је могуће задати и редни број решења које се преводи (опцијом --sol, скраћено -s). На пример.

  • petljapub compile cpp или petljapub c cpp преводе основно решење у језику cpp (решење {zadatak_id}.cpp).

  • petljapub c cs -s 1 преводи прво алтернативно решење у језику C# (решење {zadatak_id}-ex1.cs).

  • petljapub c c -s 3 преводи треће алтернативно решење у језику C (решење {zadatak_id}-ex3.c).

Покретање програма (run)

Покретање програма врши се командом petljapub run <lang> или скраћено petljapub r <lang>, при чему <lang> представља ознаку програмског језика. Ако програм није преведен пре покретања, аутоматски се врши његово превођење. Ако се не подеси другачије, покренути програм ради интерактивно тј. чита податке са стандардног улаза и исписује их на стандардни излаз. У склопу команде је потребно задати и ознаку програмског језика, а опционо је могуће задати и редни број решења које се покреће (опцијом --sol, скраћено -s). На пример:

  • petljapub run cpp или petljapub r cpp покреће основно решење у језику cpp (решење {zadatak_id}.cpp).

  • petljapub r cs -s 1 покреће прво алтернативно решење у језику C# (решење {zadatak_id}-ex1.cs).

  • petljapub r c -s 3 покреће треће алтернативно решење у језику C (решење {zadatak_id}-ex3.c).

Програм може бити покренут и тако да се улаз чита из неког од тест примера, при чему се излаз приказује на стандардном излазу. Тест-примери морају бити генерисани пре покретања програма (командом petljapub tests-gen). Покретање програма на појединачним тест-примерима врши се следећим параметрима команде run:

  • --testcase, скраћено -t или --generated, скраћено -g уз редни број тест-примера проузрокује да се програм изврши на задатом генерисаном тест-примеру.

  • --example, скраћено -e уз редни број тест-примера проузрокује да се програм изврши на задатом примеру који је издвојен из поставке задатка.

  • -crafted, скраћено -c уз редни број тест-примера проузрокује да се програм изврши на задатом примеру који је задат помоћу ручно креиране улазне датотеке.

На пример, petljapub r cpp -s 2 -e 1 извршава друго решење у језику C++ (задато датотеком {zadatak_id}-ex2.cpp) читајући улаз из првог тест-примера задатог у поставци задатка.

Генерисање тест-примера (tests-gen, tests-zip)

Тест-примери се генеришу командом petljapub tests-gen или скраћено petljapub tg.

Постоје три могуће врсте тест-примера:

  • тест-примери из текста задатка (очекивани улаз и излаз за сваки такав пример је описан у датотеци {zadatak_id}-st.md),

  • програмски генерисани тест-примери (генерисани C++ програмом датим у датотеци {zadatak_id}-tgen.cpp),

  • ручно направљени тест-примери (дати кроз колекцију *.in и евентуално *.out датотека у неком директоријуму)

Командом tests-gen се врши издвајање тест-примера из текста задатка, а затим и превођење и покретање генератора тест-примера. Очекивани резултат за сваки тест-пример се генерише коришћењем званичног решења у језику C++ (ако није преведено, оно се аутоматски преводи пре генерисања тест-примера). Ако генератор тест-примера (датотека {zadatak_id}-tgen.cpp) не постоји или је функција gen_tests празна, генерисање тест-примера се прескаче.

Ако се наведе параметар --crafted-dir, скраћено -c праћен путањом неког директоријума, тада се све *.in датотеке из тог директоријума (најчешће ручно креиране) додатно уврштавају у колекцију званичних тест-примера. Ако уз неку *.in датотеку постоји и одговарајућа *.out датотека она се сматра очекиваним резултатом за тај улаз, а ако таква датотека не постоји, тада се очекивани резултат аутоматски генерише коришћењем званичног решења у језику C++ (ако није преведено, оно се аутоматски преводи пре генерисања тест-примера).

Сви тест-примери се смештају у директоријум _build/testcases.

Командом petljapub tests-zip, скраћено petljapub tz се сви тест-примери генеришу изнова и пакују се у датотеку testcases.zip која се смешта у директоријум _build.

Тестирање програма (test, test-all)

Тестирање програма подразумева његово извршавање на тест-примерима, у оквиру задатог временског ограничења и поређење резултата са очекиваним.

Тестирање појединачних решења врши се командом petljapub test или скраћено petljapub t. У склопу команде је потребно задати и ознаку програмског језика, а опционо је могуће задати и редни број решења које се покреће. На пример:

  • petljapub test cpp или petljapub t cpp тестира основно решење у језику cpp (решење {zadatak_id}.cpp).

  • petljapub t cs -s 1 тестира прво алтернативно решење у језику C# (решење {zadatak_id}-ex1.cs).

  • petljapub t c -s 3 тестира треће алтернативно решење у језику C (решење {zadatak_id}-ex3.c).

Решење се тестира на свим тест-примерима и приказује се извештај за сваку појединачу групу тест-примера (оних задатих у тексту задатка, оних који су аутоматски генерисани и оних који су ручно припремљени, ако такви постоје).

Додатне опције које се могу навести су:

  • --timeout, скраћено -t -- допуштено време извршавања програма у секундама (подразумевана вредност је један секунд)

  • --verbosity, скраћено -v ниво детаљности порука. Опција -v 4 приказује списак свих тест примера током тестирања, док се опцијом -v 5 приказују и очекивани и добијени излаз на свим тест-примерима на којима се они разликују.

Могуће је покренути и тестирање појединачних тест-примера. Томе служе следећи додатни параметри:

  • --testcase, скраћено -t или --generated, скраћено -g уз редни број тест-примера проузрокује да се програм тестира на задатом генерисаном тест-примеру.

  • --example, скраћено -e уз редни број тест-примера проузрокује да се програм тестира на задатом примеру који је издвојен из поставке задатка.

  • -crafted, скраћено -c уз редни број тест-примера проузрокује да се програм тестира на задатом примеру који је задат помоћу ручно креиране улазне датотеке.

На пример, petljapub t cpp -s 2 -e 1 тестира друго решење у језику C++ (задато датотеком {zadatak_id}-ex2.cpp) на првом тест-примеру задатом у поставци задатка.

Командом petljapub test-all покреће се тестирање свих решења задатка. Да би се неко решење тестирало, мора бити наведено у заглављу формулације задатка (на почетку датотеке {zadatak_id}-st.md, у делу solutions).

Упоређивач (checker)

За поређење добијеног и очекиваног излаза се користи одговарајући упоређивач (checker). Ако другачије није наведено користи се подразумевани упоређивач који је имплемтиран у језику Python, уграђен у систем. Ако у директоријуму у који је инсталиран систем PetljaPub постоји програм под називом DefaultChecker.exe, он ће се користити за проверу свих задатака. Могуће је да постоји и упоређивач који је специфичан за конкретан задатак. Он се имплементира кроз C++ програм {zadatak_id}-check.cpp. Аргументи командне линије овако имплементираног упоређивача су следећи:

  • први аргумент argv[1] је датотека са излазом који се проверава

  • други аргумент argv[2] је датотека са очекиваним излазом

  • трећи аргумент argv[3] је датотека са улазним подацима

Ако је решење коректно упоређивач завршава рад са повратним кодом 0. У супротном повратни код мора да буе различит од 0.

Ако постоји, упоређивач специфичан за задатак се аутоматски преводи пре тестирања решења. Превођење упоређивача се може покренути и експлицитно, командом petljapub compile-checker.

Мерење времена извршавања (runtime)

Командом petljapub runtime приказују се времена извршавања на свим генерисаним тест-примерима. Команда може да прими и следеће параметре:

  • --timeout, скраћено -t -- временско ограничење за извршавање решења задатка у секундама (подразумевано ограничење је једна секунда).

  • --repeat, скраћено -r -- ради боље прецизности времена се одређују тако што се сваки програм покрене неколико пута и израчуна се средишње време. Овим параметром се контролише број покретања сваког решења задатка (подразумевана вредност је 3).

  • --plot, скраћено -p -- времена се приказују у виду стубичастог графикона.

Подразумевано се приказују времена извршавања свих решења у свим програмским језицима. Параметрима sol и lang могуће је ограничити приказ само на неке језике или неко решење.

HTML преглед (html-preview)

Командом petljapub html-preview гради се веб-страница која садржи поставку задатка, описе свих решења и њихове програмске кодове. Генерисана страница се чува у директоријуму _build под називом {zadatak_id}.html.

  • css - путања до CSS датотеке која ће се укључити у сваки HTML (подразумевано се користи стил pandoc.css, који се дистрибуира уз PetljaPub).

  • header - путања до датотеке са заглављем које ће се укључити на почетак MarkDown датотеке, пре њеног превођења у HTML (нпр. header.md, која садржи LaTeX макрое коришћене у задацима, која се дистрибуира уз PetljaPub)

Напомена: за ову функционалност потребно је да је инсталиран Pandoc и да је систем PetljaPub конфигурисан након тога -- након што се инсталира Pandoc, конфигурисање система PetljaPub је могуће поново покренути командом petljapub configure.

Команде за рад са збирком

Поред команди за рад са појединачним задацима, систем PetljaPub нуди и команде за рад са збиркама које представљају колекције текстова (прегледа теорије) и задатака. Свака збирка је одређена датотеком у формату YAML.

Генерисање LaTeX збирке (yaml-tex)

Командом petljapub yaml-tex <yaml> <dst> генерише се збирка у формату LaTeX. Обавезни параметри команде су:

  • <yaml> - путања до YAML датотеке у којој је дата спецификација збирке.

  • <dst> - путања резултујуће tex датотеке

Најважнији опциони параметри су:

  • tasks-dir - путања до кореног директоријума у ком су смештени сви задаци (ако се не наведе, подразумева се директоријум у који је смештена yaml датотека).

  • pub-dir - путања до кореног директоријума у ком су смештени сви пропратни текстови, најчешће прегледи теорије (ако се не наведе, подразумева се директоријум у који је смештена yaml датотека).

  • header - путања до датотеке са заглављем које ће се укључити на почетак обједињене MarkDown датотеке, пре њеног превођења у LaTeX (подразумевано се укључује датотека header.md, која садржи LaTeX макрое коришћене у задацима и која се испоручује у склопу система PetljaPub)

  • tex-template - шаблон LaTeX датотеке који ће се користити за збирку (подразумевано се користи датотека default.latex која се испоручује у склопу система PetljaPub)

  • lat - ако је наведена ова опција, цела збирка се аутоматски преводи у латиницу

Типичан пример коришћења ове команде је:

petljapub yaml-tex "_zadaci/02 Zbirka_2/zbirka.yml" "_pdf/zbirka.tex" -t "_zadaci/"

Генерисање HTML збирке (yaml-html)

Командом petljapub yaml-html <yaml> <dst> генерише се збирка у формату HTML. Обавезни параметри ове команде су:

  • <yaml> -- путања до YAML датотеке у којој је дата спецификација збирке.

  • <dst> -- назив директоријума или зип архиве у коју ће бити смештен резултат.

Најважнији опциони параметри су:

  • tasks-dir - путања до кореног директоријума у ком су смештени сви задаци (ако се не наведе, подразумева се директоријум у који је смештена yaml датотека).

  • pub-dir - путања до кореног директоријума у ком су смештени сви пропратни текстови, најчешће прегледи теорије (ако се не наведе, подразумева се директоријум у који је смештена yaml датотека).

  • header - путања до датотеке са заглављем које ће се укључити на почетак обједињене MarkDown датотеке, пре њеног превођења у LaTeX (подразумевано се укључује датотека header.md, која садржи LaTeX макрое коришћене у задацима и која се испоручује у склопу система PetljaPub)

  • tex-template - шаблон LaTeX датотеке који ће се користити за збирку (подразумевано се користи датотека default.latex која се испоручује у склопу система PetljaPub)

  • lat - ако је наведена ова опција, цела збирка се аутоматски преводи у латиницу

  • css - путања до CSS датотеке која ће се укључити у сваки HTML (нпр. pandoc.css је датотека која се )

Типичан пример коришћења ове команде је:

petljapub yaml-html "_zadaci/02 Zbirka_2/zbirka.yml" "_html/zbirka" -c "pandoc.css" -t "_zadaci/"

Тестирање целе збирке (yaml-test)

Командом petljapub yaml-test <yaml> покреће се тестирање свих решења задатака наведених у задатој YAML датотеци. Извештај о тестирању сваког задатка се бележи унутар _build директоријума тог задатка. У наредним покретањима тестирања тестирају се само задаци који су измењени од претходног тестирања.

Формати датотека за опис задатака и збирки задатака

У овом документу се описују улазни формати датотека којима се описују делови збирки задатака. Обрадом ових датотека коришћењем пратеће софтверске инфраструктуре могуће је креирати збирке у формату PDF (спремну за штампу) и формату HTML (спремну за објављивање на вебу).

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

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

Описи појединачних задатака

Задаци се описују у формату MarkDown, док се метаподаци о задатку задају у формату YAML. Сваки задатак обавезно садржи наредне датотеке, све смештене у исти директоријум:

  • {zadatak_id}-st.md - овај документ садржи прецизно описану поставку задатка, описану у формату MarkDown. Спецификација садржи прецизан текст задатка, опис улазних података и опис излазних податка.
  • {zadatak_id}-sol.md - овај документ садржи прецизан опис решења задатка, такође у формату MarkDown.
  • {zadatak_id}.cpp - основно решење задатка у језику C++.
  • {zadatak_id}.cs - основно решење задатка у језику C#.
  • {zadatak_id}.py - основно решење задатка у језику Python 3.
  • {zadatak_id}-tgen.cpp - generator test primera napisan u programskom jeziku C++ (uz pomoć biblioteke tgen.hpp, која је део инсталације система PetljaPub и може се снимити у текући директоријум наредбом petljapub tgen-hpp). Test primeri treba da budu što reprezentativniji i da pokriju sve karakteristične slučajeve u programu.

Сваки задатак може да садржи и додатна, алтернативна решења задатака. Они имају суфикс -ex1, -ex2, ... На пример:

  • {zadatak_id}-ex1.cpp - прво алтернативно решење задатка у језику C++.
  • {zadatak_id}-ex1.cs - прво алтернативно решење задатка у језику C#.
  • {zadatak_id}-ex1.py - прво алтернативно решење задатка у језику Python 3.

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

Опис метаподатака о задатку и решењима

Метаподаци о задатку се уписују на почетак описа задатка у датотеци {zadatak_id}-st.md, у формату YAML. Почетно YAML заглавље је од пратећег Markdown описа раздвојено линијом која садржи текст ---.

title: Факторијели од 1 до n
timelimit: 0.074 # u sekundama
memlimit: 64 # u MB
owner: filipmaric # vlasnik je onaj ko radi na zadatku
origin:  # izvor odakle je zadatak preuzet (može ostati prazno)
tags: [] # dodatne oznake zadatka

Основне ознаке су:

  • title - назив задатка;
  • timelimit - временско ограничење у секундама - попуњава се аутоматски, приликом калибрације збирке коришћењем пратеће софтверске инфраструктуре;
  • memlimit - меморијско ограничење у мегабајтима - попуњава се аутоматски, приликом калибрације збирке коришћењем пратеће софтверске инфраструктуре;
  • owner - власник тј. аутор задатка;
  • origin - извор одакле је задатак преузет (на пример, такмичење, нека друга збирка, неки грејдер, испит). Може остати празно, ако аутор не осећа потребу да наведе извор.
  • tags - додатне ознаке које се могу користити за претрагу задатака.

Након овога, потребно је навести списак свих решења задатка. На пример:

solutions:
   - name: ex0
     desc: "Инкрементално израчунавање на основу рекурентне везе"
     lang: [py, cpp, cs]
     tags: []
   - name: ex1
     desc: "Функција за израчунавање факторијела"
     lang: [py, cpp, cs]
     tags: []

Свако решење описано је следећим атрибутима:

  • name - ознака решења (ex0 за главно решење, а ex1, ex2 итд. за алтернативна);
  • desc - информативни опис решења;
  • lang - листа програмских језика у којима је то решење имплементирано;
  • tags - додатне ознаке решења (могу се користити за претрагу задатка).

Опис поставке задатка

Поставка задатка се описује у наредном формату.

Текст задатка.

## Улаз 

Опис формата улазних података.

## Излаз

Опис формата очекиваних излазних података.

## Пример

### Улаз

~~~
primer ulaznih podataka
~~~

### Излаз

~~~
primer izlaznih podataka
~~~

### Објашњење

Објашњење примера

Објашњење примера не мора бити наведено. Опис задатка може може садржати и већи број примера улаза и излаза.

Опис решења задатака

Решења задатака су одређена програмским кодом у разним програмским језицима (датотекама .cpp, .cs, .py) и садржајем датотеке {zadatak_id}-sol.md описаним у формату Markdown. Та датотека садржи описе свих решења задатака (и главног и евентуалних алтернативних решења ex1, ex2 итд.). Унутар Markdown описа и унутар програмског кода решења задатка специјалним "магичним коментарима" врше се додатна семантичка обележавања садржаја. Коментари личе на коментаре у језику HTML, али се уместо две цртице користе три.

Описи сваког појединачног решења задатка задају се између коментара следећег облика:

<!--- sol:ex0 --->
...
<!--- sol:end --->

Главно решење је обележено са ex0 (иако датотеке са кодовима решења не садрже ту ознаку).

Делови описа решења карактериснични за одређени програмски језик обележавају се коментарима следећег облика:

<!--- lang:cpp --->
...
<!--- lang:end --->

Овим је обележен део описа специфичан за језик C++. Ознаке језика се поклапају са коришћеним екстензијама датотека са програмским кодом решења (cpp, cs, py, c, ...). Могуће је означити и делове описа заједничке за неколико програмских језика. На пример,

<!--- lang:c,cpp,cs --->
...
<!--- lang:end --->

Неки делови описа означавају се посебним семантичким ознакама, што омогућава да се прикажу на неки истакнути начин (у неком уоквиреном "боксу" тј. "диву"). За то се користи ознака div. На пример, наредним ознакама се означава део решења у ком се приказује пример извршавања програма.

<!--- div:example --->
...
<!--- div:end --->

Могуће је употребљавати ознаке са наредног списка (али уводити и нове ознаке, при чему је за њих потребно у CSS или LaTeX документима описати како се визуелно форматирају).

  • example - пример извршавања програма
  • note - споредна општа напомена
  • formal - формалан садржај (најчешће доказ коректности алгоритма)
  • complexity - анализа сложености израчунавања

Ради уштеде простора у збирку могу бити укључени само делови програмског кода решења, што се описује магичним коментарима у изворном коду. Коментари су једнолинијски. Линије изворног кода могу бити приказане или сакривене. Подразумевано су линије приказане. Коментаром -*- hide -*- прелази се у режим сакривања линија, а коментаром -*- show -*- у режим приказивања линија. Коментар -*- ellipsis -*- такође преводи у режим сакривања линија (као и -*- hide -*-), једино што се на излазу приказују три тачке. На пример, ако се програм обележи на следећи начин

// -*- hide -*-
#include <iostream>
#include <algorithm>

using namespace std;

// pretvara ugao dat u stepenima(s) i minutima (m) u
// ugao samo u minutima
int uMinute(int s, int m) {
  return s * 60  + m;
}

int main() {
// -*- show -*-
  // ucitavamo uglove u stepenima i minutima
  int ugao1_s, ugao1_m, ugao2_s, ugao2_m, ugao3_s, ugao3_m;
// -*- ellipsis -*-
  cin >> ugao1_s >> ugao1_m;
  cin >> ugao2_s >> ugao2_m;
  cin >> ugao3_s >> ugao3_m;

// -*- show -*-
  // pretvaramo ih u uglove date samo u minutima
  int ugao1 = uMinute(ugao1_s, ugao1_m);
  int ugao2 = uMinute(ugao2_s, ugao2_m);
  int ugao3 = uMinute(ugao3_s, ugao3_m);
// -*- hide -*-
}

у збирци ће бити приказано

  // ucitavamo uglove u stepenima i minutima
  int ugao1_s, ugao1_m, ugao2_s, ugao2_m, ugao3_s, ugao3_m;
  ...

  // pretvaramo ih u uglove date samo u minutima
  int ugao1 = uMinute(ugao1_s, ugao1_m);
  int ugao2 = uMinute(ugao2_s, ugao2_m);
  int ugao3 = uMinute(ugao3_s, ugao3_m);

Реферисање задатака

У поставкама и решењима задатака (датотекама {zadatak_id}-st.md и {zadatak_id}-sol.md) могуће је реферисати се на друге задатке. За реферисање се користи формат референци дефинисан формату MarkDown, при чему је уместо линка довољно навести само јединствени идентификатор задатка, док опис може остати празан. На пример

Ова техника је описана у задатку [](trening).

Приликом обраде збирке линкови се попуњавају одговарајућим путањама, а за текст везе се узима назив реферисаног задатка (прочитан из метаподатка title наведеног у датотеци {zadatak_id}-st.md).

Препоручује се да се линк експлицитно обележи, да би се изоставио уколико у збирку није укључен задатак на који се рефереше.

<!--- span:link --->
Ова техника је описана у задатку [](trening).
<!--- span:end --->

Уметање слика

У поставке и решења задатака (датотеке {zadatak_id}-st.md и {zadatak_id}-sol.md) могуће је укључити и слике. Слика мора бити сачувана у директоријум задатка, а укључује се коришћењем MarkDown описа следећег облика.

![Судоку](sudoku.png){ width="200px" }

На овом месту се укључује слика sudoku.png, назив слике је Судоку, док је резултујућа ширина слике (у генерисаним PDF или HTML документима) 200 пиксела.

Распоред задатка у структури директоријума

Сваки задатак смештен је у засебан директоријум, чије је име облика 00 {zadatak_id}. Име директоријума мора почети бројем записаним помоћу две цифре. Бројеви служе за једноставнији преглед директоријума унутар датотечког система и ни на који начин не утичу на редослед задатака у збирци.

Директоријуми са задацима могу бити на произвољан начин организовани унутар хијерархије поддиректоријума једно централног директоријума (зовемо га репозиторијум задатака), али је битно да се директоријуми са задацима не садрже поддиректоријуме (осим, помоћних, аутоматски генерисаних, попут директоријума _build који садржи извршиве кодове и тест-примере ). На пример, организација задатака унутар репозиторијума може бити следећа:

.
└── zadaci
    ├── 01 aritmetika
    │   ├── 01 cena
    │   └── 02 obim
    └── 02 iteracija
        ├── 01 zbir_brojeva
        └── 02 faktorijel

Опис збирке

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

Спецификација датотека од којих се добија садржај збирке наводи се у формату YAML, у посебној датотеци.

Метаподаци

На почетку YAML спецификације наводе се одређени метаподаци. На пример,

title: Збирка задатака - основни ниво
authors: Фондација Петља
thumb: logo.png
short-description: >
   Збирка обухвата почетне нивое учења програмирања и припреме
   за такмичарско програмирање.
full-description: index.md
languages: [cpp]

Метаподаци се спецификују навођењем следећих атрибута:

  • title - одређује наслов збирке;
  • authors - одређује списак аутора;
  • thumb - одређује датотеку са сличицом која илуструје збирку. Путања до датотеке је релативна у односу на директоријум у ком се налази YAML спецификација.
  • short-description - кратак текстуални опис збирке;
  • full-description - дужи текстуални опис збирке. Уместо самог текста могуће је навести и путању до датотеке у формату MarkDown која садржи тај опис. Путања до датотеке је релативна у односу на директоријум у ком се налази YAML спецификација.
  • languages - програмски језик или списак програмских језика који се користе за приказ решења у збирци.

Садржај збирке

Датотеке које садрже делове садржаја збирке могу бити организоване унутар хијерархије директоријума смештене унутар једног кореног директоријума који садржи саму YAML спецификацију збирке (ту хијерархију директоријума називамо репозиторијум збирке). То може, али не мора бити идентична хијерархија као она у којој се налазе задаци (подсетимо се, они су смештени унутар директоријума који називамо репозиторијум задатака). Називи директоријума унутар репозиторијума збирке могу бити нумерисани, ради једноставније прегледа унутар датотечког система, међутим, то није обавезно. Редослед укључивања садржаја у збирку одређен је искључиво редоследом навођења унутар YAML спецификације и не зависи од евентуалне нумерације директоријума унутар репозиторијума збирке.

Подела садржаја збирке на главе и поглавља одређена је искључиво ознакама наслова унутар MarkDown датотека и никако не зависи од хијерархије директоријума у којима су те датотеке смештене.

Садржај збирке описује се YAML спецификацијом, у склопу атрибута content.

content:
  - predgovor.md
  - 01 aritmetika:
     - 01 formule:
        - trening:
           print: full
        - ocene:
           print: full
           solution: [ex0, ex1]
           code: [ex1]
  - 02 iteracija:
     - 01 petlje:
        - brojevi_od_a_do_b:
           print: statement
        - while.md
        - ocene:
           print: full
           solution: [ex2]
           code: [ex2]

Хијерархијска организација унутар YAML спецификације одговара структури директоријума унутар репозиторијума збирке. Приликом обраде спецификације, за сваки наведени директоријум проверава се да ли садржи датотеку index.md и ако садржи, она се укључује у садржај збирке.

Поред индексних датотека наведених директоријума, у збирку је могуће укључити и друге *.md датотеке (као, на пример, predgovor.md или while.md у претходној спецификацији). Оне се морају налазити у репозиторијуму збирке, а путања до њих одређена је хијерархијом директоријума наведених у YAML спецификацији (на пример, predgovor.md налази се у кореном директоријуму, док ће путања до датотеке while.md бити 02 iteracija/01 petlje/while.md).

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

Претходна спецификација подразумева овакву организацију и садржај директоријума унутар репозиторијума збирке.

.
├── zbirka.yml
├── logo.png
├── index.md
├── 01 aritmetika
│   ├── index.md
│   └── 01 formule
│       └── index.md
└── 02 iteracija
    ├── index.md
    └── 01 petlje
        ├── index.md
        └── while.md

Zbirka ће бити добијена спајањем следећих датотека:

predgovor.md
01 aritmetika/index.md
01 aritmetika/01 formule/index.md
[zadatak trening, kompletan]
[zadatak ocene, opis rešenja ex0 i ex1, kod rešenja ex1]
02 iteracija/index.md
02 iteracija/01 petlje/index.md
[zadatak brojevi_od_a_do_b, samo postavka]
02 iteracija/01 petlje/while.md
[zadatak ocene, opis i kod rešenja ex2]

Задаци trening, ocene и brojevi_od_a_do_b налазе се у репозиторијуму задатака. Ако се не планира креирање више збирки над истим овим задацима, најприродније решење је да се репозиторијум задатака и репозиторијум збирке преклпају.

.
├── zbirka.yml
├── logo.png
├── index.md
├── 01 aritmetika
│   ├── index.md
│   └── 01 formule
│       ├── index.md
│       ├── 01 trening
│       └── 02 ocene
└── 02 iteracija
    ├── index.md
    └── 01 petlje
        ├── index.md
        ├── while.md
        └── 01 brojevi_od_a_do_b

Приметимо да се задатак ocene може укључити и у поглавље о петљама, иако је у хијерархији директоријума смештен само у поглавље о аритметици. То је могуће захваљујући томе што се задаци у репозиторијуму задатака проналазе на основу њиховог јединственог идентификатора, а не на основу путање одређене положајем унутар YAML спецификације.

Параметри укључивања задатака

Приликом укључивања задатка у збирку потребно је спецификовати делове задатка који се на том месту укључују.

  • Атрибут print одређује да ли се укључује само само поставка задатка (вредност statement), или и поставка и решење (вредност full).
  • Атрибут solutions одређује која ће се решења задатка укључити. Изостављањем вредности овог атрибута приказују се сва доступна решења.
  • Атрибут code одређује који програмски кôд ће бити укључен. Изостављањем овог атрибута приказују се програмски кодови за сва решења која су одређена атрибутом solutions (ако неко решење није укључено навођењем или изостављањем атрибута solutions, програмски кôд тог решења неће бити штампан иако се експлицитно наведе атрибутом code).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

petljapub-1.0.13.tar.gz (99.7 kB view details)

Uploaded Source

Built Distribution

petljapub-1.0.13-py3-none-any.whl (86.9 kB view details)

Uploaded Python 3

File details

Details for the file petljapub-1.0.13.tar.gz.

File metadata

  • Download URL: petljapub-1.0.13.tar.gz
  • Upload date:
  • Size: 99.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.50.1 CPython/3.8.10

File hashes

Hashes for petljapub-1.0.13.tar.gz
Algorithm Hash digest
SHA256 577033a9b91998d9f49a85f5dc0481cdf4658d8969e2cc74d7503382fdfaae6a
MD5 4bc89c6b4d0bfa83fc138795b574d32d
BLAKE2b-256 aa080ff3180567518aa4b5a98914aa92423dfd4cb192eb0b74dabf9621f32a81

See more details on using hashes here.

File details

Details for the file petljapub-1.0.13-py3-none-any.whl.

File metadata

  • Download URL: petljapub-1.0.13-py3-none-any.whl
  • Upload date:
  • Size: 86.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.22.0 requests-toolbelt/0.9.1 tqdm/4.50.1 CPython/3.8.10

File hashes

Hashes for petljapub-1.0.13-py3-none-any.whl
Algorithm Hash digest
SHA256 81210b54ce6abdd843ad014914847118732bd74d30268a14757afd507bec921a
MD5 5dad892f4785477549007551484a9017
BLAKE2b-256 3b286e44e1dcee8c17d6c99f5ee6d2d71e0599ca29409724e2da8e9702981747

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page