Садржај
Увод

6. Директива activecode и Пајтон

Садржај

Директива activecode омогућава да се програм на Пајтону или другом програмском језику изврши у веб страни. Изглед и могућности активне компоненте контролишемо помоћу опција, које наводимо испод директиве activecode.

6.1. Дугмад активне компоненте

Нормално, активна компонента има само дугмад run и show_in_codelens. Кроз примере који следе разумећете како се ова два дугмета користе, а затим и како можете да избаците неко од ових дугмета, и/или да убаците нека друга.

6.1.1. Пример - Активна компонента без подешавања

Ово је подразумевани изглед активне компоненте (без наведених опција у директиви)

reST - целокупан кôд активне компоненте (компонента се налази испод кода)

.. activecode:: default_look

    print(u"Здраво")
    a = 2
    b = 2
    print(u'Резултат је', a+b)

и у браузеру се приказује овако:

Кôд који се налази у едитору ове компоненте може да се мења и извршава више пута, а извршава се кликом на дугме run.

Дугме show_in_codelens омогућује кориснику да дебагује програм у браузеру. Када кликне на ово дугме, ниже ће се појавити прозор у коме може да извршава програм корак по корак, притисцима на дугме next (притиском на дугме prev извршавате програм уназад). Током извршавања корак по корак могу да се виде тренутне вредности променљивих.

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

Дугме play_task омогућава да корисник изврши кôд који се не види, а који обично показује шта треба да ради тражени програм. Ово посебно може бити корисно у ситуацијама у којима je кориснику важно да види решење до кога треба да дође, или ефекте које треба да постигне.

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

Напиши програм у којем корњача исцртава знак за штриклирање. Окреће се ка југоистоку, иде затим 50 корака, онда се окреће ка североистоку и иде 100 корака. Знак исцртај плавим дужима, дебљине 5.

Да бисмо искористили ову могућност, користимо playtask опцију директиве activecode. Кôд који желимо да сакријемо, а учинимо извршивим кликом на дугме play_task, стављамо испод кода који ће корисник моћи да види у едитору и одвајамо га помоћу четири знака једнако``====``.

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:

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

Да бисмо искористили ову могућност, користимо опцију 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 биће кориснику видљив након клика на дугме show_help.

При клику на дугме show_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. Пример - Копирање кода

Дугме copy се обично додаје када постоје фиксни делови кода, јер они не могу ни да се селектују и копирају тастерима Ctrl+C. Умсто тога, дугме copy омогућава да се копира цео програм (укључујући и иначе недоступне делове), нпр. да би био извршен у другом окружењу. Дугме copy укључујемо помоћу опције 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

Кôд који се извршава на дугме play_task такође може да буде увезен, што радимо помоћу опције 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. Пример - Увожење делимично скривеног решења

Можете да поставите задатак са следећим особинама:

  • комплетно решење проблема је у једном екстерном фајлу са изворним кодом;

  • почетни и завршни део кода су дати и видљиви кориснику, тако да их он наслеђује и не може да их мења;

  • део између је невидљив кориснику (тај део се очекује од корисника);

  • корисник може да изврши ваше решење притиском на дугме play_task;

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 ???:
            ???

Допуни следећи кôд, тако да проналази најјефтинију и најскупљу продавницу.

(Created using Swinx, RunestoneComponents and PetljaDoc)
© 2022 Petlja
A- A+