{"id":61,"date":"2019-03-19T12:03:44","date_gmt":"2019-03-19T12:03:44","guid":{"rendered":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvaraarendus\/chapter\/tarkvaraprotuubi-naiteprogrammid\/"},"modified":"2020-12-28T13:49:46","modified_gmt":"2020-12-28T13:49:46","slug":"tarkvaraprotuubi-naiteprogrammid","status":"publish","type":"chapter","link":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/chapter\/tarkvaraprotuubi-naiteprogrammid\/","title":{"raw":"Tarkvaraprotot\u00fc\u00fcbi n\u00e4iteprogrammid","rendered":"Tarkvaraprotot\u00fc\u00fcbi n\u00e4iteprogrammid"},"content":{"raw":"Tarkvaraarenduse kursuse ja ka \u00f5piku saab tinglikult jaotada kaheks - klassikalised programmeerimise teemad ja tarkvaraarendus. Tarkvaraarenduse n-\u00f6 t\u00f6\u00f6stuslikku vaadet k\u00e4sitleme j\u00e4rgmises osas, siin aga on toodud n\u00e4iteprogrammid, mis v\u00f5ivad aidata oma programme luua. Programmeerimise kursuste \u00fcks loomingulisemaid osi on kahtlemata ise ja omal teemal programmi koostamine. Kuna kursuse maht on v\u00e4ike, siis p\u00e4ris suurt tarkvara arendada ei j\u00f5ua. Nimetagemgi siis loodavat programmi tarkvaraprotot\u00fc\u00fcbiks - k\u00f5ik ei pruugi veel t\u00e4ies mahus toimida, aga aimu v\u00f5imalikust l\u00f5pptulemusest juba saab.\r\n\r\nKursuse raames ja IT-t\u00f6\u00f6stuses tarkvara loomise protsesside sarnasused ja erinevused on v\u00e4ga huvitav temaatika. Mis teil endal t\u00f6\u00f6stusliku tarkvaraarendusega v\u00f5rreldes sarnaselt v\u00f5i erinevalt l\u00e4heb?\r\n<h1>N\u00e4iteprogrammid Githubis<\/h1>\r\n<a href=\"https:\/\/github.com\/kaareltonisson\/prog-kursused\/tree\/master\/protot%C3%BC%C3%BCbi%20n%C3%A4iteid\">Githubi repositoorium<\/a>\r\n\r\nGithubi repositooriumis on toodud m\u00f5ned terviklikud n\u00e4iteprogrammid, mida v\u00f5ib kasutada nii ideeliseks inspiratsiooniks kui ka otseste koodin\u00e4idetena, mille komponente saab enda programmis kasutada. Programmide ehitus ning nende t\u00f6\u00f6 etapid on kirjeldatud repositooriumi README-failis.\r\n<h1>L\u00fchikesi koodin\u00e4iteid<\/h1>\r\nSiin on toodud l\u00fchikesed n\u00e4itekoodid, millest v\u00f5ib olla abi terviklike n\u00e4iteprogrammide m\u00f5istmisel.\r\n<h2>CSV-faili lugemine j\u00e4rjendisse<\/h2>\r\n<h3>Ilma p\u00e4iseta (veergude nimedeta)<\/h3>\r\nAvame CSV-faili nimega <code>minufail.csv<\/code>, kus igal real on semikoolonitega (s\u00fcmbol \";\") eraldatud v\u00e4\u00e4rtused. Igast reast moodustub j\u00e4rjend, neid j\u00e4rjendeid hoiustame j\u00e4rjendis <code>andmed<\/code><em>.<\/em>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import csv\r\n\r\nfailinimi = \"minufail.csv\"\r\n\r\ncsv_fail = open(failinimi, encoding=\"UTF8\")     # Avame faili\r\ncsv_reader = csv.reader(csv_fail, delimiter = \";\")  # Anname selle CSV lugejale, semikoolonit loeme eraldusm\u00e4rgiks\r\nandmed = []                         # Siia j\u00e4rjendisse kogume ridade j\u00e4rjendid (\"andmed\" on kahem\u00f5\u00f5tmeline j\u00e4rjend)\r\nfor rida in csv_reader:             # muutuja \"rida\" on j\u00e4rjend \u00fchelt realt loetud v\u00e4\u00e4rtustest\r\n    andmed.append(rida)\r\ncsv_fail.close()<\/pre>\r\n<h3>Koos p\u00e4isega (veergude nimedega)<\/h3>\r\nKui CSV-faili esimesel real on veergude pealkirjad, siis tuleb need kuidagi \u00fclej\u00e4\u00e4nud andmetest eraldada. \u00dcks viisidest on j\u00e4rgmine:\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import csv\r\n\r\nfailinimi = \"minufail.csv\"\r\ncsv_fail = open(failinimi, encoding=\"UTF8\")     # Avame faili\r\ncsv_reader = csv.reader(csv_fail, delimiter = \";\")  # Anname faili CSV lugejale, semikoolon eraldab v\u00e4\u00e4rtusi\r\nridade_loendur = 0\r\nandmed = []\r\nfor rida in csv_reader:             # CSV lugeja teeb igast reast j\u00e4rjendi\r\n    if ridade_loendur == 0:         # Esimesel real on veergude nimed, hoiustame need eraldi\r\n        print(\"veergude nimed:\"+str(rida))\r\n        veergude_nimed = rida\r\n    else:                           # \u00dclej\u00e4\u00e4nud ridadel on andmed, hoiustame neid j\u00e4rjendis\r\n        print(\"rea sisu:\"+str(rida))\r\n        andmed.append(rida)\r\n    ridade_loendur += 1\r\ncsv_fail.close()<\/pre>\r\n<h2>Kahem\u00f5\u00f5tmelise j\u00e4rjendi l\u00e4bimine<\/h2>\r\nKahem\u00f5\u00f5tmelise j\u00e4rjendi l\u00e4bimiseks kasutame tavaliselt kahekordset ts\u00fcklit.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">j\u00e4rjend = [[1,2,3],[4,5,6]] \r\n\r\nfor rida in j\u00e4rjend:\r\n   for v\u00e4\u00e4rtus in rida:\r\n      print(v\u00e4\u00e4rtus)<\/pre>\r\n<h2>Tkinteri kasutamine<\/h2>\r\nTkinteri graafikamoodul v\u00f5imaldab detailselt kontrollida programmi graafilist poolt. Meie n\u00e4idetes kasutame elementide paigutamiseks komponenti <a href=\"http:\/\/effbot.org\/tkinterbook\/frame.htm\"><em>frame<\/em><\/a> ning k\u00e4sku <a href=\"https:\/\/effbot.org\/tkinterbook\/pack.htm\">pack<\/a>, kuid tegelikult saab Tkinteriga elemente paigutada ka rohkematel viisidel.\r\n\r\nTkinteri programmid k\u00e4ivituvad k\u00e4suga <code>mainloop(). <\/code>Tuleb arvestada, et p\u00e4rast <code>mainloop<\/code>'i k\u00e4ivitamist Python edasiste ridadeni ei j\u00f5ua, kuniks k\u00e4ivitatud juuraken alles on. Seet\u00f5ttu on graafikaga programmi t\u00f6\u00f6ks vajalik k\u00f5ik oluline k\u00e4ivitada sellest k\u00e4sust eespool.\r\n\r\nElementide ilusaks paigutamiseks on tavaliselt vaja k\u00e4sule <code>pack()<\/code> anda sobivad argumendid. Geomeetriahalduri <a href=\"https:\/\/effbot.org\/tkinterbook\/pack.htm\">pack juhendist<\/a> v\u00f5ib olla abi sobivate argumentide leidmisel.\r\n<h3>Akna loomine<\/h3>\r\nTkinter vajab algatuseks juurakna loomist ning selle eraldi k\u00e4ivitamist.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk\r\n\r\nroot = tk.Tk()    # Loome juurakna, millesse lisame hiljem muid graafikaelemente\r\nroot.title(\"Pealkiri\")    # Anname juuraknale pealkirja\r\n\r\n####\r\n# siia vahele k\u00e4ivad k\u00f5ik tegevused, mida laseme graafikaliidesel teha\r\n####\r\n\r\nroot.mainloop()     # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles<\/pre>\r\n<h3>Sildi (teksti) lisamine<\/h3>\r\nSilt (ingl <em>label<\/em>) on element, millega kuvada teksti. Sildi sisu on v\u00f5imalik tagantj\u00e4rgi muuta.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk \r\n\r\nroot = tk.Tk() # Loome juurakna, millesse lisame hiljem muid graafikaelemente \r\nroot.title(\"Pealkiri\") # Anname juuraknale pealkirja \r\n\r\nframe = tk.Frame(root)    # Lisame juuraknale (n\u00e4htamatu) raamistiku, kuhu teisi elemente kinnitada\r\nframe.pack(side=tk.TOP)\r\n\r\nsildi_tekst = \"Terekest.\"        \r\nsilt = tk.Label(frame, text=sildi_tekst)   # Loome sildi meie m\u00e4\u00e4ratud tekstiga, seostame selle meie raamistikuga\r\nsilt.config(font=(\"Serif\", 44))      # Muudame sildi fonti ning teksti suurust\r\nsilt.pack(fill=tk.BOTH)              # Paigaldame sildi (silt muutub n\u00e4htavaks)\r\n\r\nroot.mainloop() # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles\r\n<\/pre>\r\n<h3>Nupu lisamine<\/h3>\r\nNuppude lisamisel on vajalik nupule vajutamisel juhtuv tegevus defineerida eraldi funktsioonis.\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk \r\n\r\ndef nupu_tegevus():         # Nupuga seotud tegevus peab olema loodud eraldi funktsioonina\r\n    print(\"vajutatud\")\r\n\r\nroot = tk.Tk() # Loome juurakna, millesse lisame hiljem muid graafikaelemente \r\nroot.title(\"Pealkiri\") # Anname juuraknale pealkirja \r\n\r\nframe = tk.Frame(root)  # loome raamistiku, kuhu nuppe paigutada\r\nframe.pack(side=tk.TOP)\r\n\r\nbutton = tk.Button(frame, \r\n                    text=\"Vajuta\", \r\n                    fg=\"black\",\r\n                    command=nupu_tegevus)     # Loome nupu, mida vajutades k\u00e4ivitub funktsioon \"nupu_tegevus\"\r\nbutton.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10) # paigutame nupu: alla serva (side=tk.BOTTOM), x-teljel t\u00e4itvalt(fill=tk.x), 10-pikslise servavahega\r\n\r\nroot.mainloop() # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles\r\n<\/pre>\r\n&nbsp;","rendered":"<p>Tarkvaraarenduse kursuse ja ka \u00f5piku saab tinglikult jaotada kaheks &#8211; klassikalised programmeerimise teemad ja tarkvaraarendus. Tarkvaraarenduse n-\u00f6 t\u00f6\u00f6stuslikku vaadet k\u00e4sitleme j\u00e4rgmises osas, siin aga on toodud n\u00e4iteprogrammid, mis v\u00f5ivad aidata oma programme luua. Programmeerimise kursuste \u00fcks loomingulisemaid osi on kahtlemata ise ja omal teemal programmi koostamine. Kuna kursuse maht on v\u00e4ike, siis p\u00e4ris suurt tarkvara arendada ei j\u00f5ua. Nimetagemgi siis loodavat programmi tarkvaraprotot\u00fc\u00fcbiks &#8211; k\u00f5ik ei pruugi veel t\u00e4ies mahus toimida, aga aimu v\u00f5imalikust l\u00f5pptulemusest juba saab.<\/p>\n<p>Kursuse raames ja IT-t\u00f6\u00f6stuses tarkvara loomise protsesside sarnasused ja erinevused on v\u00e4ga huvitav temaatika. Mis teil endal t\u00f6\u00f6stusliku tarkvaraarendusega v\u00f5rreldes sarnaselt v\u00f5i erinevalt l\u00e4heb?<\/p>\n<h1>N\u00e4iteprogrammid Githubis<\/h1>\n<p><a href=\"https:\/\/github.com\/kaareltonisson\/prog-kursused\/tree\/master\/protot%C3%BC%C3%BCbi%20n%C3%A4iteid\">Githubi repositoorium<\/a><\/p>\n<p>Githubi repositooriumis on toodud m\u00f5ned terviklikud n\u00e4iteprogrammid, mida v\u00f5ib kasutada nii ideeliseks inspiratsiooniks kui ka otseste koodin\u00e4idetena, mille komponente saab enda programmis kasutada. Programmide ehitus ning nende t\u00f6\u00f6 etapid on kirjeldatud repositooriumi README-failis.<\/p>\n<h1>L\u00fchikesi koodin\u00e4iteid<\/h1>\n<p>Siin on toodud l\u00fchikesed n\u00e4itekoodid, millest v\u00f5ib olla abi terviklike n\u00e4iteprogrammide m\u00f5istmisel.<\/p>\n<h2>CSV-faili lugemine j\u00e4rjendisse<\/h2>\n<h3>Ilma p\u00e4iseta (veergude nimedeta)<\/h3>\n<p>Avame CSV-faili nimega <code>minufail.csv<\/code>, kus igal real on semikoolonitega (s\u00fcmbol &#8220;;&#8221;) eraldatud v\u00e4\u00e4rtused. Igast reast moodustub j\u00e4rjend, neid j\u00e4rjendeid hoiustame j\u00e4rjendis <code>andmed<\/code><em>.<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import csv\r\n\r\nfailinimi = \"minufail.csv\"\r\n\r\ncsv_fail = open(failinimi, encoding=\"UTF8\")     # Avame faili\r\ncsv_reader = csv.reader(csv_fail, delimiter = \";\")  # Anname selle CSV lugejale, semikoolonit loeme eraldusm\u00e4rgiks\r\nandmed = []                         # Siia j\u00e4rjendisse kogume ridade j\u00e4rjendid (\"andmed\" on kahem\u00f5\u00f5tmeline j\u00e4rjend)\r\nfor rida in csv_reader:             # muutuja \"rida\" on j\u00e4rjend \u00fchelt realt loetud v\u00e4\u00e4rtustest\r\n    andmed.append(rida)\r\ncsv_fail.close()<\/pre>\n<h3>Koos p\u00e4isega (veergude nimedega)<\/h3>\n<p>Kui CSV-faili esimesel real on veergude pealkirjad, siis tuleb need kuidagi \u00fclej\u00e4\u00e4nud andmetest eraldada. \u00dcks viisidest on j\u00e4rgmine:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import csv\r\n\r\nfailinimi = \"minufail.csv\"\r\ncsv_fail = open(failinimi, encoding=\"UTF8\")     # Avame faili\r\ncsv_reader = csv.reader(csv_fail, delimiter = \";\")  # Anname faili CSV lugejale, semikoolon eraldab v\u00e4\u00e4rtusi\r\nridade_loendur = 0\r\nandmed = []\r\nfor rida in csv_reader:             # CSV lugeja teeb igast reast j\u00e4rjendi\r\n    if ridade_loendur == 0:         # Esimesel real on veergude nimed, hoiustame need eraldi\r\n        print(\"veergude nimed:\"+str(rida))\r\n        veergude_nimed = rida\r\n    else:                           # \u00dclej\u00e4\u00e4nud ridadel on andmed, hoiustame neid j\u00e4rjendis\r\n        print(\"rea sisu:\"+str(rida))\r\n        andmed.append(rida)\r\n    ridade_loendur += 1\r\ncsv_fail.close()<\/pre>\n<h2>Kahem\u00f5\u00f5tmelise j\u00e4rjendi l\u00e4bimine<\/h2>\n<p>Kahem\u00f5\u00f5tmelise j\u00e4rjendi l\u00e4bimiseks kasutame tavaliselt kahekordset ts\u00fcklit.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">j\u00e4rjend = [[1,2,3],[4,5,6]] \r\n\r\nfor rida in j\u00e4rjend:\r\n   for v\u00e4\u00e4rtus in rida:\r\n      print(v\u00e4\u00e4rtus)<\/pre>\n<h2>Tkinteri kasutamine<\/h2>\n<p>Tkinteri graafikamoodul v\u00f5imaldab detailselt kontrollida programmi graafilist poolt. Meie n\u00e4idetes kasutame elementide paigutamiseks komponenti <a href=\"http:\/\/effbot.org\/tkinterbook\/frame.htm\"><em>frame<\/em><\/a> ning k\u00e4sku <a href=\"https:\/\/effbot.org\/tkinterbook\/pack.htm\">pack<\/a>, kuid tegelikult saab Tkinteriga elemente paigutada ka rohkematel viisidel.<\/p>\n<p>Tkinteri programmid k\u00e4ivituvad k\u00e4suga <code>mainloop(). <\/code>Tuleb arvestada, et p\u00e4rast <code>mainloop<\/code>&#8217;i k\u00e4ivitamist Python edasiste ridadeni ei j\u00f5ua, kuniks k\u00e4ivitatud juuraken alles on. Seet\u00f5ttu on graafikaga programmi t\u00f6\u00f6ks vajalik k\u00f5ik oluline k\u00e4ivitada sellest k\u00e4sust eespool.<\/p>\n<p>Elementide ilusaks paigutamiseks on tavaliselt vaja k\u00e4sule <code>pack()<\/code> anda sobivad argumendid. Geomeetriahalduri <a href=\"https:\/\/effbot.org\/tkinterbook\/pack.htm\">pack juhendist<\/a> v\u00f5ib olla abi sobivate argumentide leidmisel.<\/p>\n<h3>Akna loomine<\/h3>\n<p>Tkinter vajab algatuseks juurakna loomist ning selle eraldi k\u00e4ivitamist.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk\r\n\r\nroot = tk.Tk()    # Loome juurakna, millesse lisame hiljem muid graafikaelemente\r\nroot.title(\"Pealkiri\")    # Anname juuraknale pealkirja\r\n\r\n####\r\n# siia vahele k\u00e4ivad k\u00f5ik tegevused, mida laseme graafikaliidesel teha\r\n####\r\n\r\nroot.mainloop()     # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles<\/pre>\n<h3>Sildi (teksti) lisamine<\/h3>\n<p>Silt (ingl <em>label<\/em>) on element, millega kuvada teksti. Sildi sisu on v\u00f5imalik tagantj\u00e4rgi muuta.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk \r\n\r\nroot = tk.Tk() # Loome juurakna, millesse lisame hiljem muid graafikaelemente \r\nroot.title(\"Pealkiri\") # Anname juuraknale pealkirja \r\n\r\nframe = tk.Frame(root)    # Lisame juuraknale (n\u00e4htamatu) raamistiku, kuhu teisi elemente kinnitada\r\nframe.pack(side=tk.TOP)\r\n\r\nsildi_tekst = \"Terekest.\"        \r\nsilt = tk.Label(frame, text=sildi_tekst)   # Loome sildi meie m\u00e4\u00e4ratud tekstiga, seostame selle meie raamistikuga\r\nsilt.config(font=(\"Serif\", 44))      # Muudame sildi fonti ning teksti suurust\r\nsilt.pack(fill=tk.BOTH)              # Paigaldame sildi (silt muutub n\u00e4htavaks)\r\n\r\nroot.mainloop() # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles\r\n<\/pre>\n<h3>Nupu lisamine<\/h3>\n<p>Nuppude lisamisel on vajalik nupule vajutamisel juhtuv tegevus defineerida eraldi funktsioonis.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">import tkinter as tk \r\n\r\ndef nupu_tegevus():         # Nupuga seotud tegevus peab olema loodud eraldi funktsioonina\r\n    print(\"vajutatud\")\r\n\r\nroot = tk.Tk() # Loome juurakna, millesse lisame hiljem muid graafikaelemente \r\nroot.title(\"Pealkiri\") # Anname juuraknale pealkirja \r\n\r\nframe = tk.Frame(root)  # loome raamistiku, kuhu nuppe paigutada\r\nframe.pack(side=tk.TOP)\r\n\r\nbutton = tk.Button(frame, \r\n                    text=\"Vajuta\", \r\n                    fg=\"black\",\r\n                    command=nupu_tegevus)     # Loome nupu, mida vajutades k\u00e4ivitub funktsioon \"nupu_tegevus\"\r\nbutton.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10) # paigutame nupu: alla serva (side=tk.BOTTOM), x-teljel t\u00e4itvalt(fill=tk.x), 10-pikslise servavahega\r\n\r\nroot.mainloop() # K\u00e4ivitame graafika. Siit edasi programmiridu ei k\u00e4ivitu, kuniks juuraken on alles\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"author":3,"menu_order":2,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-61","chapter","type-chapter","status-publish","hentry"],"part":63,"_links":{"self":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/61","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/users\/3"}],"version-history":[{"count":3,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/61\/revisions"}],"predecessor-version":[{"id":491,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/61\/revisions\/491"}],"part":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/parts\/63"}],"metadata":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapters\/61\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/media?parent=61"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/pressbooks\/v2\/chapter-type?post=61"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/contributor?post=61"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/web.htk.tlu.ee\/digitaru\/tarkvara2\/wp-json\/wp\/v2\/license?post=61"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}