6. Директива activecode и Пајтон¶
Директива activecode
омогућава да се програм на Пајтону или другом програмском језику изврши у веб страни. Изглед и могућности активне компоненте контролишемо помоћу опција, које наводимо испод директиве activecode
.
6.1. Дугмад активне компоненте¶
Нормално, активна компонента има само дугмад и . Кроз примере који следе разумећете како се ова два дугмета користе, а затим и како можете да избаците неко од ових дугмета, и/или да убаците нека друга.
6.1.1. Пример - Активна компонента без подешавања¶
Ово је подразумевани изглед активне компоненте (без наведених опција у директиви)
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: default_look
print(u"Здраво")
a = 2
b = 2
print(u'Резултат је', a+b)
и у браузеру се приказује овако:
Кôд који се налази у едитору ове компоненте може да се мења и извршава више пута, а извршава се кликом на дугме .
Дугме омогућује кориснику да дебагује програм у браузеру. Када кликне на ово дугме, ниже ће се појавити прозор у коме може да извршава програм корак по корак, притисцима на дугме (притиском на дугме извршавате програм уназад). Током извршавања корак по корак могу да се виде тренутне вредности променљивих.
6.1.2. Додавање текста задатка у активну компоненту¶
Додатно, ако желите да текст задатка буде укључен у директиву и да се у браузеру приказује у истом елементу као и активна компонента, текст задатка треба додати изнад кода у оквиру директиве activecode
одвојен од кода са четири тилде ~~~~
reST - пример активне компоненте која укључује и текст задатка
.. activecode:: tekst_zadatka
Напиши програм који штампа "Здраво", и штампа резултат сабирања 2 променељиве
~~~~
print("Здраво")
a = 2
b = 2
print('Резултат је', a+b)
и у браузеру се приказује овако:
Напиши програм који штампа „Здраво”, и штампа резултат сабирања 2 променељиве
6.1.3. Блокирање могућности едитовања делова кода¶
У одређеним случајевима, желећемо да направимо задатак тако да корисник одређене делове кода не може да мења. То радимо тако што у сам код који представља тело директиве activecode
додајемо коментаре који означавају да одређени делови кода неће моћи да буду промењени. Ти делови биће затамњени и биће увек видљиви кориснику у едитору.
# -*- acsection: general-init -*- овај коментар означава да се у коду налазе делови који ће бити фиксни (приказују се на тамнијој позадини)
# -*- acsection: var-init -*- овај коментар означава да је испод њега почетни фиксни део
# -*- acsection: main -*- овај коментар означава да почиње део кода који корисник може да мења
# -*- acsection: after-main -*- овај коментар означава се завршио део кода који корисник може да мења и да почиње завршни фиксни део
Пример активне компоненте у којој су делови кода непроменљиви за корисника
.. activecode:: blokiranje_delova_koda
Сваки аутобус има 55 места за путнике.
Одредити потребан број аутобуса, ако је дат број путника.
Доврши дати програм, тако да решава задатак.
~~~~
# -*- acsection: general-init -*-
# -*- acsection: var-init -*-
br_putnika = 237
# -*- acsection: main -*-
# израчунај број аутобуса
br_autobusa = 0
if br_putnika % 55 > 0:
br_autobusa = 1
# -*- acsection: after-main -*-
print(br_autobusa)
Претходни програм ће у браузеру дати овакав резултат
Сваки аутобус има 55 места за путнике. Одредити потребан број аутобуса, ако је дат број путника.
Доврши дати програм, тако да решава задатак.
Овакво обележавање делова кода биће значајно за низ опција које нуди директива activecode
, о чему ће бити речи у наставку.
6.1.4. Пример - Без дебаговања - nocodelens
¶
Дугме за дебаговање може да се избаци. Ово можете да урадите тако што ћете испод директиве activecode
да додате опцију :nocodelens:
То ћете можда хтети да урадите ако у програму користите библиотеке за чији кôд није подржано извршавање корак по корак, или ако имате много другух дугмади.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: no_debugging
:nocodelens:
print("Овај програм не може")
print("да се извршава корак по корак,")
print("него само одједном.")
6.1.5. Пример - Само за читање - passivecode
¶
Могуће је подесити активну компоненту и тако да кôд не може да се мења и извршава. Ово радимо тако што директиву activecode
позивамо са опцијом passivecode
којој додељујемо вредност true
.
Ово је згодно када само објашњавате неке ствари. Можете да користите кôд који није сасвим комплетан или није сасвим синтаксно исправан (псеудокод):
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
**Општи облик наредбе** ``if``
.. activecode:: read_only_no_execution
:passivecode: true
if логички услов:
наредба 1-1
наредба 1-2
...
наредба 1-м
else:
наредба 2-1
наредба 2-2
...
наредба 2-н
Општи облик наредбе if
6.1.6. Пример - Шта треба да се добије - playtask
¶
Дугме омогућава да корисник изврши кôд који се не види, а који обично показује шта треба да ради тражени програм. Ово посебно може бити корисно у ситуацијама у којима je кориснику важно да види решење до кога треба да дође, или ефекте које треба да постигне.
При решавању следећег задатка, кориснику ће помоћи да види решење како би знао да ли његов кôд производи добро решење.
Напиши програм у којем корњача исцртава знак за штриклирање. Окреће се ка југоистоку, иде затим 50 корака, онда се окреће ка североистоку и иде 100 корака. Знак исцртај плавим дужима, дебљине 5.
Да бисмо искористили ову могућност, користимо playtask
опцију директиве activecode
. Кôд који желимо да сакријемо, а учинимо извршивим кликом на дугме , стављамо испод кода који ће корисник моћи да види у едитору и одвајамо га помоћу четири знака једнако``====``.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: prikazi_primer
:nocodelens:
:playtask:
import turtle
# dovrši program
====
import turtle
turtle.color("blue")
turtle.width(5)
turtle.right(45)
turtle.forward(50)
turtle.left(90)
turtle.forward(100)
6.1.7. Пример - Аутоматска провера решења на више примера - :runortest:
¶
Дугме омогућава да се програм аутоматски изврши више пута, за разне вредности улазних података. За свако извршавање програма се формира један ред табеле, у коме се добијене вредности пореде са очекиваним. Ако су добијене и очекиване вредности једнаке, ред је означен зеленом бојојм, а ако нису, ред је означен црвеном бојом.
Да бисмо искористили ову могућност, користимо опцију runortest
директивe activecode
. Код који служи за тестирање пише се као део скривеног кода након програма који је видљив кориснику. У програмима у којима постоји тестирање неопходно је употребити коментаре који делове кода чине непроменљивим за корисника. У главном делу (делу између # -*- acsection: main -*- и # -*- acsection: after-main -*-) ставља се део кода за који се очекује да га корисник реши, у део # -*- acsection: var-init -*- стављају се варијабле док се у секцију # -*- acsection: after-main -*- најчешће ставља наредба принт.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: automatic_testing
:runortest: a, zbir
Дата је величина *A*. Величина *B* је за 4321 већа од *A*,
а величина *C* је два пута већа од *B*.
Довршити програм, тако да исписује збир ове три величине.
(програм треба исправно да ради и ако се величина A промени).
~~~~
# -*- acsection: general-init -*-
# -*- acsection: var-init -*-
a = 380
# -*- acsection: main -*-
b = ???
c = ???
zbir = a + b + c
# -*- acsection: after-main -*-
print(zbir)
====
from unittest.gui import TestCaseGui
class myTests(TestCaseGui):
def testOne(self):
for data_velicina in (123, 567):
ocekivani_izlaz = data_velicina + 3 * (data_velicina+4321)
self.assertEqual(
acMainSection(a = data_velicina)["zbir"],
ocekivani_izlaz,
u"Ако A = %s, онда је збир = %s." % (data_velicina, ocekivani_izlaz))
myTests().main()
Дата је величина A. Величина B је за 4321 већа од A, а величина C је два пута већа од B.
Довршити програм, тако да исписује збир ове три величине. (програм треба исправно да ради и ако се величина A промени).
Кôд који се користи за писање тестова користи библиотеку unittest, чији су елементи у највећем делу достпуни у оквиру Петљадок-а.
6.1.8. Пример - Приказивање помоћи - help
и includexsrc
¶
Дугме „Show help” омогућава кориснику који не зна како да започне програм, да добије неки почетни костур кода. Ово дугме додајемо тако што употребљавамо опције help
и includexsrc
. Опцији includexsrc
као вредност додељујемо путању ка фајлу у коме се налази изворни код за наш пример. Фајл са изворним кодом се обично смешта у фолдер _src, који треба да стоји у root-у нашег петљадок пројекта. У овом фајлу треба да буду означени фиксни делови у коду. Кориснику ће бити видљиви сви делови кода осим главног дела (део између # -*- acsection: main -*- и # -*- acsection: after-main -*-). Код који напишемо у оквиру директиве activecode
са употребљеном опцијом help
биће кориснику видљив након клика на дугме .
При клику на дугме биће изгубљен кôд који је евентуално претходно унет.
Напиши програм који исписује редом бројеве 5, 10, 15, … 100, сваки у посебном реду.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: show_partially_written_code
:includexsrc: _src/help_shell.py
:help:
for i in range(???, ???, ???):
print(i)
reST - целокупан кôд изворног фајла help_shell.py
, који је укључен помоћу includexsrc
# -*- acsection: general-init -*-
# pocetak programa
# -*- acsection: main -*-
for i in range(5, 101, 5):
print(i)
# -*- acsection: after-main -*-
# kraj programa
6.1.9. Пример - Копирање кода¶
Дугме се обично додаје када постоје фиксни делови кода, јер они не могу ни да се селектују и копирају тастерима Ctrl+C
. Умсто тога, дугме омогућава да се копира цео програм (укључујући и иначе недоступне делове), нпр. да би био извршен у другом окружењу. Дугме укључујемо помоћу опције enablecopy
, која нема аргументе.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: enable_code_copy
:enablecopy:
:nocodelens:
Измени програм тако да израчунава и исписује вредност збира производа
бројева a и b и разлике бројева c и d, користећи при томе помоћне променељиве.
~~~~
# -*- acsection: general-init -*-
# -*- acsection: var-init -*-
a = 3
b = 4
c = 4
d = 1
# -*- acsection: main -*-
proizvod = 0 # popravi ovaj red
razlika = 0 # popravi ovaj red
zbir = 0 # popravi ovaj red
# -*- acsection: after-main -*-
print(zbir)
Измени програм тако да израчунава и исписује вредност збира производа бројева a и b и разлике бројева c и d, користећи при томе помоћне променељиве.
6.2. Специјално понашање активне компоненте¶
6.2.1. Пример - Аутоматско извршавање - autorun
¶
Активну компоненту можете да подесите да изврши програм одмах по учитавању стране, што се ради коришћењем опције autorun
, која нема аругменте.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: automatic_execution
:autorun:
print(u"Резултат извршавања овог програма се види одмах")
6.2.2. Пример - Извршавање у модалном прозору - modaloutput
¶
Активна компонента може да се извршава у модалном прозору. То је погодно за програме са графиком. Ову могућност активирамо помоћу опције modaloutput
, која нема аргументе.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: execution_in_modal_window
:nocodelens:
:modaloutput:
import pygame as pg
pg.init()
prozor = pg.display.set_mode((200, 200))
pg.display.set_caption(u"Слика")
prozor.fill(pg.Color("white"))
pg.draw.circle(prozor, pg.Color("darkgreen"), (100, 100), 50)
pg.display.update()
while pg.event.wait().type != pg.QUIT:
pass
pg.quit()
6.2.3. Пример - Надовезивање на претходни програм - include
¶
Почетак скрипта (програма) можете да дате у једној компоненти, у којој нпр. задајете полазне податке. Може да буде згодно да ову компоненту подесите да буде само за читање (што не морате да урадите).
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: first_part
:passivecode: true
prodavnice = [
(u"Код комшије", 250),
(u"Навали", 280),
(u"Још мало па нестало", 220),
(u"Миле попуст", 240)
]
У следећим компонентама можете дате податке да користите за неко рачунање (или да тражите од корисника да то уради). Oво радите тако што користите опцију include
, која као аргумент узима ID активне компоненте коју желите да укључите (укључени кôд из претходне компоненте неће бити видљив у новој компоненти у коју је укључен).
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: second_part
:include: first_part
NAZIV, CENA = 0, 1
najjeftinija = prodavnice[0]
najskuplja = prodavnice[0]
for prodavnica in prodavnice:
if najjeftinija[CENA] > prodavnica[CENA]:
najjeftinija = prodavnica
elif najskuplja[CENA] < prodavnica[CENA]:
najskuplja = prodavnica
print(u'Најјефтиније је у продавници', najjeftinija[NAZIV])
print(u'Најскупље је у продавници', najskuplja[NAZIV])
6.3. Уметање кода из другог фајла¶
6.3.1. Пример - Просто додавање из изворног фајла includesrc
¶
Комплетан изворни кôд Пајтон програма може да се увезе из фајла коришћењем опције includesrc
која као аргумент узима путању ка жељеном фајлу. Препоручујемо да се тај фајл налази у фолдеру _src у root-у петљадок пројекта.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: external_source
:includesrc: _src/simple_code.py
reST - целокупан кôд који се налази у изворном фајлу
print(u'Изворни код ове наредбе је у посебном фајлу')
6.3.2. Пример - Комбиновање увезеног и дописаног кода¶
Увезени кôд може да се комбинује са дописаним, али не и са другим увезеним кодом.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: combined_external_and_embeded_source
:includesrc: _src/simple_code.py
print(u'Овај део кода је дописан у компоненти')
6.3.3. Пример - Увожење скривеног решења includehsrc
¶
Кôд који се извршава на дугме такође може да буде увезен, што радимо помоћу опције includehsrc
, која као аргумент узима путању ка фајлу који желимо да укључимо. Ово нам омогућује да корисник види само резултат извршавања кода који је смештен у фајл који смо увезли, али не и сам кôд.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: combined_hidden_and_embeded_source
:playtask:
:includehsrc: _src/problem1_solution.py
Измени следећи кôд, тако да исписује бројеве 2, 4, 6, 8, 10
(сваки у посебном реду).
~~~~
for i in range(1, 11):
print(i)
Измени следећи кôд, тако да исписује бројеве 2, 4, 6, 8, 10 (сваки у посебном реду).
reST - целокупан кôд фајла из кога смо увезли решење
for i in range(2, 11, 2):
print(i)
6.3.4. Пример - Увожење делимично скривеног решења¶
Можете да поставите задатак са следећим особинама:
комплетно решење проблема је у једном екстерном фајлу са изворним кодом;
почетни и завршни део кода су дати и видљиви кориснику, тако да их он наслеђује и не може да их мења;
део између је невидљив кориснику (тај део се очекује од корисника);
корисник може да изврши ваше решење притиском на дугме ;
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: partially_visible_source
:playtask:
:enablecopy:
:includexsrc: _src/problem2_solution.py
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.
~~~~
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.
6.3.5. Пример - Комбиновање делимично скривеног и започетог решења¶
Претходни тип задатка може да се комбинује са започетим решењем преосталог дела програма.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: combined_partially_visible_and_embeded_source
:playtask:
:enablecopy:
:includexsrc: _src/problem2_solution.py
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.
~~~~
najjeftinija = prodavnice[0]
najskuplja = prodavnice[0]
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.
6.3.6. Пример - Комбиновање делимично скривеног решења и помоћи¶
Још једна могућност је да се комбинују делимично видљиво решење и помоћ која се добија на захтев.
reST - целокупан кôд активне компоненте (компонента се налази испод кода)
.. activecode:: combined_partially_visible_and_help_source
:playtask:
:enablecopy:
:help:
:includexsrc: _src/problem2_solution.py
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.
~~~~
najjeftinija = prodavnice[0]
najskuplja = prodavnice[0]
for prodavnica in prodavnice:
if ???:
???
elif ???:
???
Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.