csPlugin attribuutit
Lue myös: YAML-kieli TIMissä.
1. Arvonta
Kaikkiin alla esiteltyihin attribuutteihin voi soveltaa arvontaa, jolloin attribuuteille voi saada satunnaisia arvoja. Tilanteesta toki sitten riippuu, saadaanko tällä aikaiseksi hyvää vai pahaa :-) Mutta oikein käytettynä arvonnalla voidaan saada opiskelijoille toisistaan eroavia tehtäviä.
2. Vastauskertojen rajoittaminen
``` {plugin="csPlugin" #itseisarvo}
type: cs,comtest,doc
answerLimit: 5
...
Jos answerlimit
rajaa ei anna, on oletus ääretön muille plugineille paitsi mmcq
:lle (monivalintakysymykselle) se on yksi. Jos kirjoittaa
answerLimit:
niin vastauskertojen lukumäärä on rajaton vaikka olisi kyse mistä tahansa pluginista.
Vastausaikaa voidaan rajoittaa:
starttime: '2016-08-25 23:00:05'
deadline: '2016-08-25 23:10:05'
Näistä jompikumpi voi puuttua, jolloin sen rajan väli ei rajoita. Aika tulkitaan UTC:na.
3. Pisteiden antaminen
Alla on lueteltu pisteiden antamisen vaihtoehdot. Pisteet lasketaan yhteen, jollei ole cumulative: false
, jolloin korkeimman pistemäärän tuottava osio otetaan huomioon. Tällöin myös jos ajaa testit eivätkä ne mene läpi, niin tuloksena voi olla 0 p, vaikka koodi kääntyisikin, jos testin kääntymisestä ei ole annettu erikseen pisteitä.
Kaikkia alla olevia vaihtoehtoja ei ole pakko käyttää kerralla.
answerLimit: 5 # montako kertaa tehtävää saa yrittää
-pointsRule: # tämän alle säännöt miten pisteitä saa
multiplier: 1.0 # Millä luvulla kerrotaan tehtävästä saadut pisteet
maxPoints: "Voit saada max 2 pistettä" # teksti, jolla kuvataan pisteiden kertyminen
min_points: 0 # estetään negatiivisten pisteiden saaminen (oletus 0)
max_points: 5 # estetään ettei pisteiden summa tule tätä korkeammaksi (oletus 1e100)
readpointskeep: false # jätetäänkö seuraavassa pisteet tulosteeseen
readpoints: "Pisteet: (.*)\n" # etsitään (regex ja poistetaan ellei edellä ole true)
# tulosteesta rivi Pisteet:
# ja otetaan tuosta sulkujen välinen osa pisteiden arvoksi.
# pisteet menevät output-osioon
allowUserMin: 0 # minimipistemäärä, jonka käyttäjä saa itse antaa, oletus = 0
allowUserMax: 2 # maksimipistemäärä, jonka käyttäjä saa itse antaa
code: 0.8 # montako pistettä expecCode antaa. jos puuttuu, niin oletus on 1
expectCode: | # reg exp koodista, joka pitää täyttää, jotta saa code-pisteet
pappa
borde
spela
\.
expectCode: byCode # voi sanoa näinkin, jos halutaan, että byCode-attribuutti
# sellaisenaan on oikea vastaus
# pitää kuitenkin huomata, että regexp merkit aiheuttavat
# haasteita :-!
expectCodePlain: "kissa"
# vastauksen pitää olla täsmälleen tämä teksti
# (voi olla montakin riviä)
expectCodePlain: byCode: # ehkä järjestelytehtävään paras valinta, jos on olemassa
# vain oikea tai väärä järjestys, eli ei tarvita regexpejä
compile: 0.1 # käännöksen onnistumisesta saa 0.1 pistettä
run: 0.2 # jos ajo menee virheittä 0.2 pistettä
output: 0.8 # out vastaa vaadittua (oletus 1 p)
expectOutput: '.*Summa.*5$' # regexp outputille
expectOutputPlain: 'Summa on 5'
# ohjelman tuloksen pitää olla täsmälleen tämä teksti
# paitsi lopun välilyöntien ja rivinvaihtojen määrä saa heittää
test: 1 # testien läpimeno tuottaa 1 p
doc: 0.1 # jos ajetaan dokumentit, niin saa 0.1 pistettä edellyttäen, että
# muita pisteitä on jo vähintään doc_limit verran
doc_limit: 0.5 # raja, jota enemmän pitää olla muita pisteitä, että saa doc-pisteet.
# oletus on 0.5. Jos tähän laittaa 0, saa aina doc-pisteet
Mitähän regexp-formaattia TIM tässä käyttää?
- VL: Python 3.x
Katso myös numberRuler käyttöohjeista.
Mikäli pisterajoittimissa on allowUserMax
, niin silloin käyttäjä saa antaa pisteitä noissa rajoissa. Käyttäjän pisteet tällöin voittavat mahdollisen automaatin antamat pisteet. Mikäli mitään muita pistesääntöjä ei ole, silloin käyttäjän on itse annettava pisteet.
Tekstivastauksessa voisi olla vaikkapa lyhimmillään
-pointsRule:
expectCode: .{10,} # eli vähintään 10 merkkiä niin saa 1 p (koska code puuttuu)
Tuossa ei saa olla rivinvaihtoa noissa 10:ssä merkissä, koska oletuksena piste (.
) ei tarkoita rivinvaihtoa. Jos halutaan että myös rivinvaihto lasketaan noihin 10 merkkiin, muoto pitää olla jompikumpi seuraavista:
expectCode: '(.|\s){10,}'
expectCode: '[\S\s]){10,}'
Pelkästään ajettavaksi tarkoitetuissa ohjelmissa, joissa outputtia ei voi vertailla järkevästi, voisi käyttää esim
-pointsRule:
compile: 0.3
run: 0.7
Lyhyen säännön voi kirjoittaa myös seuraavasti:
-pointsRule: { run: 1 }
-pointsRule: { expectCode: ".{10,}" }
Toisaalta voidaan antaa cumulative
attribuutti (oletus=true), jolla saadaan pisteiden lasku niin, että jokainen toteutuva ominaisuus lisää pisteitä, esim:
-pointsRule:
cumulative: true
compile: 0.1
run: 0.1
output: 0.3
testcompile: 0.1
testrun: 0.1
test: 0.3
expectOutput: ".*Summa.*5$"
Tällöin testien ajaminen ei nollaa tavallisesta ajosta saatuja pisteitä.
Lisää regular expressioneista:
Example where the user code must include text like:
f=25
f = 25
-pointsRule:
code: 2.0
expectCode: "(.*\n)*.*f *= *25.*(.*\n)*"
Explanations:
(.*\n) row that can contain anything
. = anything
* = 0-n times
* previous () any time 0-n
.* anything in this line before letter f
f the letter f must be there
* any number of spaces
= equal sign must be there
* again any number of spaces, even *
25 there must be letters 2 and 5
.* after that there might be any text on that line
(.*\n)* and again any number of lines whatever text
Minimissään pistesäännöt pitää olla:
-pointsRule: {}
ja tämä riittää esim. MathCheckille, koska sille on oletuksena
readpoints: '<!--!points! (.*) -->'
ja MathCheck tuottaa pisteet tällaiseen muotoon. Mikäli ei haluta arvostelua, jätetään pointsRule
kokonaan pois.
Mikäli maxPoints
arvo puuttuu, näytetään käyttäjälle pointRules
-säännöistä tuleva maksimipistemäärä tyyliin
3 / 5
Mikäli on maxRules: details
, niin näytetään yksityiskohdat joista maksimi tulee tyyliin:
Pisteet: 1.5 / output:0.8 + run:0.1 + test:0.5 + doc:0.1 = 1.5
Jos maksimin näyttö halutaan estää, voidaan tämä tehdä kahdella tavalla:
maxPoints:
maxPoints: ""
Jos maxPoints
sisältää jonkin muun arvon, se näytetään sellaisenaan.
Automaattisesti maxPoints näyttämisestä seuraa se ongelma, että jos esimerkiksi postprogram
laskee maksimista poikkeavia arvoja, niin näyttöön voi tulla max-tieto pointsRule perustella ja silloin voisi näkyä esimerkiksi
5 / 1
Tällöin ratkaisu olisi laittaa
maxPoints: "5"
Katso myös:
4. Koodin hakeminen toisesta tiedostosta
Attribuuteilla file:
tai byFile
voi hakea pohjaksi valmiin lähdekoodin esim. versionhallinnasta:
``` {plugin="csPlugin" #AstiaD7}
type: java/jcomtest/doc
header: "Astia-luokka muutoskuuntelijalla"
stem: "Tässä muuteltu Astia-luokka, jossa muutoskuuntelija. Tälle ei tarvitse tehdä muuta kuin kääntää."
maxrows: 15
path: user/d7
justCompile: true
button: Käännä
byFile: https://svn.cc.jyu.fi/srv/svn/ohj2/esimerkit/k2016/demot/tehtavat/src/demo/d7/Astia.java
```
Tässä on se "vika", että TIM tallentaa nopeussyistä haetut tiedostot omaan sisäiseen välimuistiin. Tällöin alkuperäistiedostoon tehdyt muutokset eivät näy enää plugineissa.
Välimuistin voi tyhjentää eri plugineista komennoilla:
https://tim.jyu.fi/cs/refresh
https://tim.jyu.fi/svn/refresh
jolloin seuraavalla pluginin käyttökerralla TIM hakee tiedostot alkuperäisestä lähteestä.
5. Tehtävän tuloksen laittaminen välimuistiin
5.1 Miksi?
Jos "tehtävä" on sellainen, että sen tuloksen ei ole tarkoitus muuttua tekijän toimenpiteiden seurauksena, niin silloin tehtävään kannattaa laittaa päälle attribuutti cache: true
, jolloin ajon tuottama kuva ja/tai teksti tallennetaan välimuistiin ja annetaan sieltä seuraavalla katselukerralla.
Periaatteessa osan cache
-attribuutin ominaisuuksista saa sillä, että tekee tavallisen pluginin ja sitten ajaa sen ja ottaa kuvakaappauksen, jonka lataa TIMiin kuvana. Mutta tällöin jokaisen muutoksen jälkeen kuvakaappauksen joutuisi ottamaan ja lataamaan uudelleen. Cachen ansiosta riittää vain tehdä muutos kuvan lähdekoodiin ja kuva on TIMissä aina automaattisesti oikein valmiina.
Attribuutin cache
aikana tehty kuva näytetään vain niille, joilla on oikeus nähdä dokumentti. Kuvasta ei muodostu verkon yli kenen tahansa haettavissa olevaa kuvaa.
5.2 Peruskäyttö
Esimerkiksi:
``` {plugin="csPlugin" #uml2}
type: run
cache: true
isHtml: true
cmds: java -jar /cs/java/plantuml.jar -tsvg uml.txt; cat uml.svg
filename: uml.txt
fullprogram: |!!
@startuml
Alice -> Bob: Soita mulle
Bob --> Alice: Saatan soittaakkin
Alice -> Bob: Kivaa
Alice <-- Bob: Ring
@enduml
!!
```
Eli jos edellä on "vain" tarkoitus että käyttäjälle näytetään tuo kuva, mutta käyttäjän ei ole tarkoitus muuttaa koodia, saadaan suoritus erittäin paljon nopeammaksi cache: true
-attribuutilla. Mikäli pluginin tekijä muuttaa pluginin koodia, suoritetaan ajo uudelleen automaattisesti ja uuden ajon tuottama kuva tallennetaan välimuistiin. Silloin entisen ajon tuottama kuva tuhotaan sieltä.
Attribuutti isHtml: true
tarvitaan, mikäli ohjelma tuottaa outputtiin kuvan HTML-muotoisena, eli esimerkiksi SVG-kuvan kuten plantuml
tuottaa. Tällöin tulosta ei laiteta console-tyyliseen kehykseen. Mikäli ohjelma tuottaa PNG-kuvan, ei tätä attribuuttia tarvita.
Kuvan tuottamiseen tarvittavan koodin kehittämisen aikana voi olla järkevää pitää cache
-attribuutti kommentissa (esimerkiksi niin, että aloittaa rivin #
-merkillä) ja ajaa kuvan tekemistä tavallisena pluginina. Kun kuva on mieleinen, voi kommenttimerkin riisua cache
-attribuutin edestä pois.
Tätä toimintoa voidaan käyttää minkä tahansa ohjelman kanssa, joka tuottaa kuvan tai tekstiä, esimerkiksi Python:
``` {plugin="csPlugin" #pythonkuvaaja}
type: py
cache: true
imgsource: image.png
fullprogram: |!!
import numpy as np
import matplotlib.pyplot as plt
BYCODEBEGIN
plt.plot([1, 3, 2,1,6,9,1 ])
BYCODEEND
plt.savefig('image.png')
!!
```
Huomaa, että cache-tilassa ajetaan se koodi, mikä ajetaan sen jälkeen kun painetaan reset
linkkiä tehtävätilassa. Eli käyttäjän mahdollisesti tekemät muutokset eivät vaikuta cache-kuvaan. Siksi mahdolliset muutokset pitää ensin kopioida "tehtävän" lähdekoodiin ja sitten laittaa cache-attribuutti todeksi.
5.3 Tyhjentämisen estäminen
Joskus on kuitenkin tapauksia, jolloin entisen kuvan tuhoaminen ei ole järkevää. Esimerkki tällaisesta tapauksesta on sellainen, jossa ajettava koodi muuttuu käyttäjäkohtaisesti. Esimerkiksi edellä haluttaisiin Bob
in tilalle käyttäjän nimi:
``` {plugin="csPlugin" #uml2}
type: run
cache: true
cacheClear: false
isHtml: true
cmds: java -jar /cs/java/plantuml.jar -tsvg uml.txt; cat uml.svg
filename: uml.txt
fullprogram: |!!
@startuml
Alice -> %%username%%: Soita mulle
%%username%% --> Alice: Saatan soittaakkin
Alice -> %%username%%: Kivaa
Alice <-- %%username%%: Ring
@enduml
!!
```
Tällöin attribuutilla cacheClear: false
, voidaan estää vanhan kuvan tuhoaminen. Ilman tuota attribuuttia jokaisen käyttäjän kohdalla kuva laskettaisiin uudelleen ja välimuistin hyöty menisi hukkaan. Kieltämällä tuhoaminen jää välimuistiin jokaiselle käyttäjälle valmiiksi hänelle laskettu kuva. Toki tämä kuluttaa välimuistia ja se voidaan tämän takia välillä tyhjentää, mutta sitten kun kuvia tarvitaan, ne lasketaan automaattisesti uudelleen.
Jos kuvassa on esimerkiksi päiväykseen tms. liittyvä muuttuva tekijä, niin silloin cacheClear: false
a ei kannata käyttää, koska kuva kuuluukin laskea kaikille käyttäjille uudelleen päiväyksen vaihtuessa ja silloin vanhan kuva saadaankin tuhota.
5.4 Otsikot
Kuvan alle saa normaaliin tapaan alaotsikon footer
-attribuutilla:
footer: Kuva 7, binääripuu
Mikäli haluaa säilyttää osin plugin välillä normaalikäytössä ja silloin käyttää eri alaotsikkoa, voi cache-käyttöä varten antaa oman alaotsikon cacheFooter
-attribuutilla
cacheFooter: Kuva joka on tehty käyttäjää %%username%% varten
5.5 Tyylit
Mikäli ohjelma tulostaa esimerkiksi tekstiä näytölle, niin se tulee oletuksena console
-tyylillä.
``` {plugin="csPlugin" #shell}
type: shell
cache: true
fullprogram: echo 'Hello World!'
```
Hello World!
Haluttaessa tyyliä voidaan vaihtaa attribuutilla cacheClass
:
``` {plugin="csPlugin" #shell2}
type: shell
cache: true
cacheClass: htmlresult
fullprogram: echo 'Hello World!'
```
Luokan voi myös jättää tyhjäksi:
cacheClass:
jolloin teksti tulostuu normaalilla TIMin tyylillä.
Kuville oletuksena on htmlResult
, joka keskittää kuvan. Jos kuva halutaan vasempaan reunaan, voi luokan laittaa tyhjäksi.
5.6 Vakiosisältö
Joskus voi olla tilanteita, joissa esimerkiksi ohjelman tuottamaa kuvaa pitää vielä käsin muokata. Silti ohjelman lähdekoodin säilyttäminen helposti saatavilla olisi mukavaa.
Tällöin voidaan menetellä seuraavasti:
Lisää csPlugin, jossa on ohjelma, joka piirtää ajettaessa kuvan selaimelle.
Aja ja muokkaa ohjelmaa, kunnes kuva on muokkaamista vaille valmis
Ota kuvasta kuvakaappaus
Muokkaa kuvaa tarpeen mukaan
Lataa kuva TIMiin, kopioi osoite talteen
Lisää pluginin koodiin attribuutti tyyliin:
cacheHtml: <img src="/static/images/tim-logo.svg" alt="TIM logo"width="42">
Jos kuva pitää toistaa uudelleen, kommentoi rivi
cacheHtml
laittamalla#
sen eteen ja jatka kohdasta 2.
5.7 Käyttö LaTeX-tulostuksia varten
Toistaiseksi tämä ei toimi automaattisesti LaTeX-pohjaisten tulostusten kanssa, vaan niitä varten pitää ottaa kuvakaappus ja ilmoittaa kuva erikseen LaTeXin tulostukseen, ks. Tulostuksen ohje.
6. Muita attribuutteja
Attribuuttien nimet ja oletukset.
Jos oletusta ei ole sanottu, se on tyhjä. Jos attribuutin nimi aloitetaan "-" -merkillä, sitä ei lähetetä palvelimelle. Useiden attribuuttien eteen voidaan laittaa tuo miinus. Jos alla olevassa listassa nimi alkaa "-"-merkillä, niin silloin se on kirjoitettava.
"type","cs" - pluginin tyyppi
"mode" - ACE-editorin moodi. Oletuksena se, mikä tulee kielestä.
"file" - mikä tiedosto haetaan pohjaksi. Yleensä joku kohta
korvataan replace-attribuutin avulla byCode
tai byFile-sisällöllä.
"program" - kuten file, mutta ohjelman sisältö voidaan kirjoittaa
TIMissä.
"fullprogram" - katso tarkempi selostus omassa luvussaan
"fullfile" - katso tarkempi selostus omassa luvussaan
"filename" - millä nimellä käyttäjän syntynyt tiedosto tallennetaan
Jos tyyppinä text/args, tämä on se mitä käyttäjä
kirjoittaa args-kohtaan
"nosave",false - dataa ei tallenneta, vaikka siihen jotakin kirjoittaisi
"nocode",false - koodi poistetaan levyalueelta käännöksen jälkeen
tällä voi olla sivuvaikutus että ei näe käännösvirheitä
"upload" - näyteään upload-painike
"uploadbycode" - näytetään upload-painke, mutta upload ei mene palvelimelle,
vaan käyttäjän kirjoittaman koodin tilalle;
tiedstojen yhteenlaskettu koko rajoitettu vastauksen kokoon
(ks. luku 9.2)
"uploadstem" - upload-painikkeen eteen tuleva teksti
"uploadautosave", false - kun tekstipohjainen upload on tehty,
tallenetaanko (ja ajetaan) automaattisesti
"lang" - kieli, vaihtoehdot fi ja en, oletus en
"width" - iframe-pluginin leveys
"height" - iframe-pluginin korkeus
"-min-height" - pienin korkeus jonka plugin vie. Asettamalla tämän voi
vähentää "hyppelyä". Esim: -min-height: 400px
"-max-height" - suurin korkeus jonka plugin enintään vie.
Jos plugin vie enemmän tilaa, tulee vierityspalkki reunaan.
Esim: -max-height: 800px
"iframeopts","" - optiot iframelle. csPluginissa oletus on:
iframeopts: 'seamless="seamless"
sandbox="allow-scripts allow-forms allow-same-origin"'
"table" - taunon alustus, esim. table: s10 tai
table: "1,2,3,4,5,6&ma=4&mb=5&ialku=0&iloppu=5"
"variables" - taunon muuttujat, esim: a=3;b=2;c
"indices" - taunon indkesimuuttujat, esim: i=3;j=2;k
"replace" - mikä sana riviltä pitää löytyä, jotta se
korvataan byCode-koodilla
"taunotype" - vaihtoehtona ptauno, jolloin alkiot näkyvissä, muuten piilossa
"stem" - pluginin tekstiksi tuleva osa
"header" - ennen pluginia tuleva teksti (otsikko)
"footer" - plugin jälkeen tuleva teksti (esim. kuvatekstin tapaan)
"iframe",false - tuleeko iframe
"usercode","" - käyttäjän kirjoittama koodi (ei siis varsinaisesti attribuutti)
"codeunder",false - näytetäänkö kokonaiskoodi alapuolella
"codeover",false - näytetäänkö kokonaiskoodi yläpuolella
"open",!scope.isFirst - avataanko sisältö automaattisesti
"viewCode",false - näytetäänkö koko koodi oletuksena
"rows",1 - montako riviä tekstialueeseen pohjaksi
"maxrows",100 - montako riviä korkeintaan ennen kuin rupeaa rullaamaan
"byCode" - teksti, jolla replace-kohdassa sanottu rivi korvataan ja
jonka tilalle tulee käyttäjän kirjoittama koodi
"byFile","" - tekee saman kuin byCode, mutta hakee sisällön tiedostosta.
Ei saa olla yhtäaikaa byCode kanssa. Mikäli program tai file
puuttuu, niin tämä tulee kokonaisuudessaan editoitavaksi
pohjaksi.
"notFoundError", "File not found: " + url
- jos tiedostoa ei löydy, tulee tämä ilmoitus. Oletuksena
näkyy myös tiedoston nimi, joka ei aina ole haluttua.
"-outReplace","" - ennen tuloksen lähettämistä outputtiin tullut teksti korvataan,
regexpinä
Jos halutaan monta korvausta, voidaan tämä esittää
listana tyyliin
outReplace:
- replace: Kissa
by: Koira
- replace: Kana.*
by: Lintu
Mikäli by puuttuu, käytetään jokaisessa outBy arvoa
(oletuksena tyhjä)
"-errReplace","" - ennen tuloksen lähettämistä err tullut teksti korvataan,
regexpinä
Jos halutaan monta korvausta, voidaan tämä esittää
listana tyyliin
errReplace:
- replace: Kissa
by: Koira
- replace: Kana.*
by: Lintu
Mikäli by puuttuu, käytetään jokaisessa errBy arvoa
(oletuksena tyhjä)
"-outBy","" - millä outReplace korvataan?
"-errBy","" - millä errReplace korvataan?
"placeholder","Write your code here"
- jos syöttöalue jää tyhjäksi, mitä näytetään
"inputplaceholder","Write your input here"
- jos input-alue jää tyhjäksi, mitä näytetään
"argsplaceholder",scope.isText ? "Write file name here" : "Write your program args here"
- jos argumenttien syöttöalue jää tyhjäksi, mitä näytetään
"argsstem",scope.isText ? "File name:" : "Args:"
- argumentti-alueen otsikko
"userinput","" - pohjateksti input-alueeseen
"userargs",scope.isText ? scope.filename : ""
- pohja argumenttikohtaan
"inputstem","" - input-alueen otsikko
"inputrows",1 - input alueen rivimäärä
"toggleEditor",scope.isSimcir ? "True" : false
- voiko editorin piilottaa
"indent",-1 - sisennyksen minimimäärä
"user_id" - käyttäjän tunnus
"isHtml",false - jos ajon palaute on html, poisteen XML-otsikko-osa siitä
"autorun", false - ajetaanko plugin heti, kun dokumentti aukeaa
"autoupdate",false - päivitetäänkö sisältö automaattisesti. Jos jokin ms aika,
niin käytetään sitä aikaväliä
"noConsoleClear", false - kielletään tulostuskonsolin tyhjennys ajojen välillä;
lähinnä järkevä autoupdaten kanssa
"canvasWidth",700 - piirtoalueen koko
"canvasHeight",300
"button","" - Aja-painikkeeseen tuleva teksti
"noeditor",scope.isSimcir ? "True" : false
- piilotetaanko editori oletuksena
"norun",false - piilotetaanko Aja-painike
"normal","Tavallinen" - Tavallisen editorin linkin teksti
"highlight","Highlight" - ACE-editorin teksti
"parsons","Parsons" - Parsons-editorin asetukset, ks:
https://tim.jyu.fi/view/tim/ohjeita/parsons
"jsparsons","JS-Parsons" - JavaScript-parsons editorin teksti
"editorMode",-1 - mikä on aloitusindkesi editorin rullaamiselle
-1 = käytetään käyttäjen edellistä valintaa
"showCodeOn","Näytä koko koodi" - teksti kokokoodin näyttämisen linkille
"showCodeOff","Piilota muu koodi" - teksti koko koodin piilottamiselle
"resetText","Alusta" - Alusta-linkin teksti
"blind",false - piilotetaanko vastaajan tiedot
"usercodeEdit" - Lista moukkauskomentoja tyyliin:
[{ replace: "###(.|\r|\n)*", by: "" }]
jos esimerkiksi Parsons tehtävässä halutaan
että kaikki ###-rivin jälkeiset jätetään huomiotta.
Toimii vain palvelimen kautta validoitaessa.
"editorModes","01" - mitä editoreja rullataan editorin vaihdosta
0 = tavallinen
1 = ACE
2 = Parsons
3 = JS_parsons (kevyempi, poistettu???)
"path" - mihin hakemistoon. Järkevä vaihtoehto on "user", jolloin
käyttäjälle tehdään oma "pysyvä" hakemisto ja
sitä voi käyttää peräkkäisillä ajokerroilla.
Katso tästä attribuutista lisää omasta luvustaan.
"savestate" - mihin tiedostoon tallennetaan shell-ikkunan tila, jotta
seuraava käynnistys jatkuu samasta kohdasta. Oletuksena
tilaa ei tallenneta. Arvo voisi olla esim.
savestate: "~/run/.state"
Samassa dokumentissa voi olla useita eri "tiloja".
webconsolet vaihtavat tilariviä sen mukaan, mitä niihin
liittyvissä savestateissa on polkuna.
"buttons" - rivinvaihdoilla eroteltu lista painikkeista, jotka tulee
editorin alapuolelle ja joita painamalla
painikkeessa oleva teksti kopioidaan edit-alueeseen
Esim:
buttons: |!!
$
\int
^
_
{
}
!!
Katso lisää omasta luvusta.
"cmd" - komento, joka ajetaan, jos type: run tai useimmilla kääntäjillä
normaalin ajokomennon sijaan.
Jos type: run, tiedoston nimi liitetään perään.
Mahdollinen userargs liitetään komennon perään.
Esim:
filename: example/Laskuja.java
type: run
cmd: javac
"cmds" - Pythonin format-jono, jolla voidaan tehdä ajokomento,
johon liitetään tiedoston nimi kohtaan {0}.
userargs liitetään kohtaan {1}.
Esim:
type: run
button: Käännä
filename: example/Laskuja.java
cmds: "javac {0}"
Tai:
type: cc
cmds: valgrind -q --leak-check=full {0}
"runargs","" - agumentit, jotka liitetään em. komennon perään ja tämän perään
tulee vielä käyttäjän antaman argumentit
"justCompile",false - tekee pelkän käännöksen
"justCmd",false - ei käännä, tekee vain cmd tai cmds attribuutissa
sanotun komennon
"justSave",false - vain tallentaa (mutta voi käyttää oikean kielen tyyppiä)
"languages",all - puolipisteellä eroteltu lista kieliä, joita
käytetään, mikäli type:ssä on ensimmäisenä sana all.
Ilman tätä attribuuttia kaikki kielet ovat listassa
"selectedLanguage",type - mikä on kielilistan oletuskieli
"delay",0 - kuinka kauan (ms) odotetaan ennen kuin kaapataan
kuva Java-ajossa.
Jos arvo on negatiivinen, ajetaan itse ohjelma eri säikeessä
Esim. JavaFX tarvitsee tämän negatiivisen arvon
(n. -700 toimii).
rect, - alue, josta kuva kaapataan muodossa x,y,leveys,korkeus
opt, - C/C++ kääntäjille menevät optiot
"validityCheck","" - minkälainen regexp suoritetaan käyttäjän "koodille"
ennen kuin se edes päästetään ajoon selaimen päässä
"validityCheckMessage","" - mikä teksti, jos em. ehto ei täyty. Mikäli ei anneta,
tulostaa em. ehdon.
"validityCheckForceSave",false - tallentaa vaikka tarkastus ei mene läpi
"wrap","-1" - kuinka pitkiä rivejä saa kirjoittaa. Jos >=0,
näkyy editorin alapuolella pieni input-kenttä, jossa arvoa
saa vaihtaa. 0 tai pienempi ? ei-wrap. text-tyypille
oletuksena 70.
"maxConsole",20000 - pisin sallittu konsolitulostus
"extrafiles" - attribuutti ylimääräisten tiedostojen käsittelyyn.
Pidempi selitys alempana.
"emptyResult","No result" - mikä tulos näytetään, jos SQL-kyselyn tulos on tyhjä
"errorcondition", "" - RegExp ehto, jonka löytyessä käyttäjän koodista
ajaminen jätetään
tekemättä ja näytetään errormessage
"errormessage": "Not allowed to use: " + errorcondition
"warncondition: "" - RegExp ehto, jonka löytyessä käyttäjän koodista
ajaminen tehdään,
mutta ajon jälkeen näytetään warnmessage
"warnmessage: "Not recommended to use: " + warncondition
"dockercontainer", "timimages/cs3": oletuksena ajetaan cs3-imageilla
"mockconsole", "True" Toistaiseksi vain C# - konsoli, joka kaiuttaa inputin näyttöön
niin syöttö vaikuttaa aidommalta. Filttereitä varten kannattaa
ottaa pois käytöstä.
"showRuntime", "False" Näytetäänkö suoritusajat oikeaan alanurkkaan?
"savedText", "Saved {0}" Teksti joka näytetään ei-ajettavien
tallentamisesta. {0} korvataan tiedoston nimellä.
"docaddr", "" Osoite josta muodostetaan dokumenttien säilytyspaikka.
Tämän ansiosta dokumenttien osoite on aina vakio.
"locpath", "" lokaali suhteellinen polku josta dokumenttejä ruvetaan
tekemään
"nofilesave", "False" editorin dataa ei tallenneta tiedostoon.
Hyödyllinen oikestaan vain massdokumentteja tehtäessä.
"git" asetukset gitRegille ja gitCheckille
"gitDefaults" oletusarvoja git lähteille, gitRegille ja gitCheckille
"rootPath", sama kuin path juuripolku, joka otetaan mukaan ajoon dockeriin
"masterPath" polku masters-kansiossa olevaan kansioon.
Käytetään master-tiedostolähteessä ja ExtCheckissä
"files" lista tiedostolähteistä (kts. ohje alempana). Tarvitaan vain, kun halutaan
palauttaa useampi tiedosto yhdessä pluginissa
"moreFiles" lista tiedostolähteistä (kts. ohje alempana).
"deleteFiles" lista poistettavista tiedostoista
"mounts" lista "mounteista jotka tehdään.
Toisteiseksi toimii vain:
mounts: [ohj1Content]
Tällöin käyttäjän hakemiston alla näkyy
Content-kansio, jossa on Ohj1-kurssin
kuvia.
Lista voidaan ylläpitäjien toimesta lisätä tarpeen vaatiessa.
"classname" mikäli C# luokantunistus ei löydä oikeaa pääluokkaa
voidaan se antaa tällä, esim
classname: Tankkipeli
classname: demo7.AngryLego
"sourcefiles" mitkä tiedostot käännetään. Toimii toistaiseksi vain C#.
Jypeli-ohjelemissa pitää sanoa myös Ohjelma.cs
Ellei pääohjelmaa ole itse tehty johonkin luokkaan.
Esim:
sourcefiles: Ohjelma.cs HangryDog.cs Luokat.cs
"jsBrowserConsole", "False" Käytetäänkö type: js ohjelmissa omaa konsolia (false)
vai selaimen konsolia (true)
"editorreadonly", "False" Onko editori readonly-tilassa
"save_video", "false" Tallennetaanko videota ajosta. Toistaiseksi
vain type: jypeli. Ks tarkemmin oma alaluku
"disableUnchanged", false Laitetaanko Tallenna harmaaksi tallennuksen jälkeen.
Toimii tyypeille: text, xml, css ja md.
undo: Tietue siitä miten undo toimii
button: "Palauta viimeisin" linkin teksti (oletus ei käytössä eli tyhjä)
title: "Palauttaa..." ohjeteksti
confirmation: "Haluatko.." Varmistusikkunan teksti (tyhjä => ei varmistusta)
"copyLink", "copy" Teksti joka tulee siihen millä editorin sisältö kopioidaan
"hide" Tietue jossa kerrotaan mitkä elemnetit piilotetaan. Toistaiseksi
{wrap: false, changed: false}
wrap: näytetäänkö wrap-ohjaimet
changed: näytetäänkö vasen vihreä palkki, että teksti on muuttunut
"saveRunCmd", None nimi tiedostolle, johon ajokomento tallennetaan. Käyttöä jos
halutaan ajaa ohjelma erillisen kommenon kautta esim testCmd.
"saveTestRunCmd", None nimi tiedostolle, johon testin ajokomento tallennetaan.
"testCmd" mikä komento ajetaan testien kanssa
"formulaEditor", false Lisää matematiikkaeditorin jos true
"uploadCopy", False Jos True, csPluginin kautta ladattu tiedosto (ks. upload -asetus) menee suoraan ajokonttiin.
Tämän avulla csPluginiin voi ladata mielivaltaisia tiedostoja, joita voi käyttää csPlugin-tehtävissä.
"uploadCopyFileName", "uploaded_file.{n}.{ext}" Ladatun tiedoston nimi. {n} korvataan tiedoston indeksillä ja {ext} tiedoston tiedostopäätteellä
"startLineNumber", None Mistä luvusta koodirivien lasku alkaa. Toimii vain ACE-editorille.
"targetCanvas", None Jos asetettu ja tehtävän tyyppi on 'md', näytetään "Kopioi kuva tehtävään" -painike,
joka kopioi käyttäjän vastauksen kuvana reviewCanvas-tehtävään.
Tehtävän ID on oltava sama kuin tämän attribuutin arvoksi asetettu merkkijono.
"-joinOutToErr", true Kun kuvaa kopoidaan tulostusta varten niin liitetäänkö out-teksti virheen perään
(vanhan yhteensopivuuden takia oletuksena True)
"-autoplot", "false" Jos Python koodissa on esim plot.show(), niin tehdään automaattisesti kuvan
kopiointi ja vahhdetaan show tilella savefig("...").
- ACE-editorin modeja voi katsoa esim: kitchen-sink.
- Parsons-editorista voi katsoa lisää Parsons-dokumentista.
7. buttons
Attribuutilla buttons
voidaan määritellä mitä painikkeita käyttäjälle tulee. Painikkeiden painaminen lisää editoriin tekstiä.
7.1 Perusmuoto
Perusmuodossa luetellaan allekkain painikkeiden tekstit. Silloin nämä samat tekstit tulevat editoriin sellaisenaan.
Esimerkiksi:
buttons: |!!
a = 5
print()
!!
saadaan painikkeet:
Jos haluatan että lisäyksen jälkeen kursori on tietyssä kohdassa, voidaan tämä paikka merkitä kursorimerkillä (⁞
, tulee editorin Charactres/Cursor
):
buttons: |!!
a = 5
print(⁞)
!!
7.2 Editoriin eri teksti kuin painikkeessa näkyy
Mikäli painikkeisiin tarvitaan enemmän toimintoja, esimerkiksi erilainen painikkeen teksti kuin mitä tekstiä lisätään editoriin, pitää käyttää muotoa jossa sanotaan taulukossa (eli haksulkeissa):
- näkyvä teksti
- editoriin lisättävä teksti
- mahdollinen ohjeteksti, joka näkyy kun kursori viedään painikkeen päälle
buttons: |!!
["sijoita 5", "a = 5\n", "sijoittaa arvon 5 muuttujaan a"]
["tulosta a", "print(a)"]
["⏎", "\n", "uusi rivi"]
!!
7.3 Arvojen kysyminen käyttäjältä
Vastaavasti jos halutaan "aukkoja", joihin käyttäjältä kysytään arvo ennen teksti sijoittamista, voidaan käyttää \\?
-merkintää kysyttävien arvojen kohdalla.
buttons: |!!
["sijoita", "a = \\?\n", "sijoittaa arvon muuttujaan a"]
["tulosta", "print(\\?)\n"]
["⏎", "\n", "uusi rivi"]
!!
Edellä tulee aina vakiokysymys. Usein halutaan muotoilla itse kysymystä ja mahdollisesti vielä käyttää oikeellisuustarkistusta, eli lisätään perään taulukoita, joiden sisältö on:
- oletusarvo
- kysymysteksti
- regexp jolla oikeellisuus tarkistetaan (optio)
- virheilmoitus (optio)
Toistaiseksi kaikki pitää saada yhdelle riville yhden painikkeen osalta
buttons: |!!
["sijoita", "\\? = \\?\n", "sijoittaa arvon muuttujaan", ["a", "Mihin muuttujaan sijoitetaan?", "^[A-Za-z][A-Za-z0-9]*$", "Pitää olla yksi kirjain ja mahdollisesti kirjaimia ja numeroita"], ["5", "Mikä arvo", "^[0-9]+$", "Pitää olla luku"]]
["tulosta", "print(\\?)\n","", ["a", "Mikä muuttuja tulostetaan"]]
["⏎", "\n", "uusi rivi"]
!!
7.4 Matematiikka ja painikkeet
Painiketekstit voi ajaa TeX-renderöijän läpi lisäämällä painikkeiden []
-muotoon merkkijono "math"
ja kirjoittamalla LaTeX-koodi \\( \\)
tai \\[ \\]
-merkkien sisään.
Huomaa, että YAML-syntaksin takia \
-merkit pitää kirjoittaa muodossa \\
.
Lisäämällä pluginiin miniSnippets
-luokan voi tehdä yksinkertaisen matikkaeditorin:
7.5 Painikkeiden ulkoasun muuttaminen
Mikäli painikkeiden ulkoasua halutaan muuttaa, voidaan tälle tehdä oma TIM-tyyli (ks: Tyylien laadintaopas) tai laittaa dokumentin tai preamblen css
-asetuksiin esimerkiksi:
css: |!!
p.csRunSnippets {
margin: 5px 0 0 0;
}
.csRunSnippets button {
font-size: 12px;
font-family: serif;
height: 18px;
}
!!
7.6 mdButtons
Attribuutilla mdButtons
voidaan määritellä samat asiat kuin edellä käyttäen YAML-syntaksia. Lisäetuna on että voidaan käyttää kaikkea MarkDown-syntaksia.
Aikaisempi esimerkki olisi tällä syntaksilla:
mdButtons:
- text: sijoita
data: \? = \?\n
expl: sijoittaa arvon muuttujaan
placeholders:
- default: a
text: Mihin muuttujaan sijoitetaan?
pattern: ^[A-Za-z][A-Za-z0-9]*$
error: Pitää olla yksi kirjain ja mahdollisesti kirjaimia ja numeroita
- default: "5"
text: Mikä arvo
pattern: ^[0-9]+$
error: Pitää olla luku
- text: tulosta
data: print(\?)\n
placeholders:
- default: a
text: Mikä muuttuja tulostetaan
- text: ⏎
data: \n
expl: "uusi rivi"
- text: md:![](https://tim.jyu.fi/static/images/tim-logo.svg)
data: "TIM"
Molempia syntakseja buttons
ja mdButtons
voi käyttää samassa pluginissa. Silloin ensin näytetään buttons
-attribuutilla määritellyt painikkeet.
7.7 Matematiikkaeditorin painikkeet
Jos formulaEditor-attribuutti on true, niin matematiikkaeditorille voi määrittää painikkeita. Tarkemmat ohjeet löytyvät tästä.
8. Cleaning the compiler error messages
Sometimes in the compiler error messages there might be something that is not meant to be shown to students. For example, the code might have some kind of check functions that checks the code. If there are compiler errors, the whole source code is shown to students. To remove the extra code, one can use cutErrors
.
Suppose the generated source code looks like:
public class Calculations {
public static void main(String[] args) {
int value = userFunction(params);
...
check();
}
public static int userFunction(...) {
...
}
// BEGINCHECK
public static void check() {
// call user function with different parameters and check
// if get right results
}
// ENDCHECK
}
Suppose one wants to remove everything between BEGINCHECK
and ENDCHECK
and remove the call to check()
function. The cutErrors
could be like:
cutErrors:
-
replace: "(// BEGINCHECK.* ENDCHECK)"
by: ""
-
replace: "( check\\(\\);)"
by: ""
If the value of by
attribute is empty, it can be dropped away like:
cutErrors:
-
replace: "(// BEGINCHECK.* ENDCHECK)"
-
replace: "( check\\(\\);)"
that can be shortened like:
cutErrors:
- replace: "(// BEGINCHECK.* ENDCHECK)"
- replace: "( check\\(\\);)"
or even:
cutErrors:
- "(// BEGINCHECK.* ENDCHECK)"
- "( check\\(\\);)"
If there is only one item to replace by ""
, the shortest allowed form is:
cutErrors: "(// BEGINCHECK.* ENDCHECK)"
The search rule is RegEx with dot matching also \n
. The area to replace must be in ()
. That means that to use chars (
and )
as normal characters, they must be prefixed by \\
(note two of them). As done in the example, to replace check()
, one must write:
check\\(\\)
9. Resurssien rajoittaminen
Oletuksena ohjelmat ajetaan rajoitetussa ympäristössä rajoitetuilla resursseilla. Resurssien rajoittamisella pyritään siihen, ettei käyttäjä voi omalla ohjelmallaan ylikuormittaa palvelinta.
Tällä hetkellä on käytössä seuraavia oletusrajoituksia:
- Ajokontin laskenta-aika max. 10 CPU-sekuntia
- Tarkoittaa, että kaikkien prosessorien laskenta-aikojen summa on korkeintaan 10 sekuntia
- Ajokonttien luomien tiedostojen koko max. 100000 tavua
- Ohjelman suorituspinon koko max. 2000 tavua
- Standardin tulosteen pituus max. 20000 tavua
9.1 Resurssirajoitusten muokkaaminen
Tehtävän laatija voi jossain määrin muokata rajoituksia, mikäli tehtävä sitä vaatii.
CPU-aika, tiedostojen koko ja muita resurssirajoituksia voi muokata ulimit
-asetuksella. Asetuksen arvoksi laitetaan halutunlainen ulimit-komento:
ulimit: ulimit -t 30 # Nostetaan suoritusaika 30 CPU-sekuntiin
Standardin tulosteen pituus puolestaan voi nostaa maxConsole
-asetuksella:
maxConsole: 300000
9.2 Tiedostonkoon kiinteät rajat
TIMissä tiedostot erotellaan kahteen tyyppiin, joilla on voimassa kaksi eri kokorajoitusta:
- Tehtävän vastaus kattaa kaikki ne teksimuotoiset tiedostot, jotka voi katsella ja muokata suoraan csPluginin koodieditorissa.
- Kokorajoitus: 250 kt yhteensä, ei voi muokata
- Liitteet ovat kaikki tiedostot, jotka ladataan tiedostolataajan kautta (
type: upload
) ja jotka tallenetaan erillisenä tiedostona, jota voi ladata muttei muokata csPluginin koodieditorissa (uploadbycode: false
).- Kokorajoitus: 700 Mt/tiedosto, voi muokata alemmaksi mm.
maxSize
-asetuksella
- Kokorajoitus: 700 Mt/tiedosto, voi muokata alemmaksi mm.
10. save_video
Attribuutilla save_video
voidaan määrittää Jypeli-ohjelma tallentamaan tietty pätkä videota ja sitten kuvan sijaan ohjelman alle tulee video.
Aliattribuutit:
frames: - kuinka monta ruutua kaapataan (oletus 60)
skip_farmes: - kuinka monta ruutua jätetään jo askeleessa väliin (oletus 0)
fps: - millä nopeudella video tehdään (oletus 30)
Oletuksilla, eli kirjoittamalla vain
skip_fames:
Saataisiin 60 kuvaa (joka vastaa 1 sek ajoa) ja se tehdään 30 fps videoksi, eli video kestää silloin 2 sek. Jos halutaan ajan kanssa 1:1, voi laittaa joko
fps: 60
tai
skip_frames: 1
Pitkissä videoissa joutuu sallittua ajoaikaa kasvattamaan.
Esimerkki:
``` {plugin="csPlugin" #lumiukko1}
type: jypeli/doc
nomain: true
filename: Lumiukko
ulimit: ulimit -t 30 -f 80000 # kasvatetaan suoritusaikaa (s)
timeout: 30000 # ja aikaa jonka selain odottaa vastausta (ms)
save_video:
frames: 600 # ajetaan 600 päivityskierrosta (normaalisti yhden sekunnin aikana ajetaan 60 päivitystä, tämä vastaa oletuksena 10 s)
skip_frames: "0" # Otetaan joka päivityskierroksesta kuva
fps: 30 # 30 otettua kuvaa/s = 20 s video
byCode: |!!
using Jypeli;
public class Lumiukko : PhysicsGame
{
public override void Begin()
{
Camera.ZoomToLevel();
Level.Background.Color = Color.Black;
Level.CreateBorders();
var p1 = new PhysicsObject(100.0, 100.0, Shape.Circle);
Add(p1);
p1.Hit(RandomGen.NextVector(1000, 1000));
}
}
!!
```
11. fullprogram ja fullfile
Jotta olisi helpompi ylläpitää ulkoisella IDE:llä ohjelmia, jotka samalla tarkistavat toimintaansa, on attribuutit fullprogram
ja fullfile
, joiden on tarkoitus tuottaa samaa sisältöä, mitä saataisiin joukolla replaceN
ja byCodeN
-attribuuteilla. Ideana on, että koko ohjelmaa voidaan sellaisenaan kehittää ja testata IDE:ssä ja sitten kopioida sisältö muuttamattomana TIMiin.
Esimerkki:
``` {#t1kuutosia plugin="csPlugin"}
type: cs/comtest/doc
-pointsRule:
readpoints: "RANDOMCHECK: (.*)\n"
-deleteLine: "(\n#[^\n]*)"
header: MontakoKuutosta
filename: Laskuja
stem: "Muuta funktio niin että se palauttaa kuutosten lukumäärän"
fullprogram: |!!
public class Laskuja
{
public static void Main()
{
int m = MontakoKuutosta(3, 5);
System.Console.WriteLine("Kuutosia oli " + m);
System.Console.WriteLine("Kuutosia oli " + MontakoKuutosta(1, 6));
Tarkista(); // REMOVELINE
}
#if true
// DELETEBEGIN
/// <summary>
/// Funktio palauttaa kuinka monta parametria on arvolla 6
/// </summary>
/// <param name="a">ensimmäinen luku</param>
/// <param name="b">toinen luku</param>
/// <returns>lukumäärän parametreista arvolla 6</returns>
/// <example>
/// <pre name="test">
/// Laskuja.MontakoKuutosta(1,1) === 0;
/// Laskuja.MontakoKuutosta(1,6) === 1;
/// Laskuja.MontakoKuutosta(6,6) === 2;
/// </pre>
/// </example>
public static int MontakoKuutosta(int a, int b)
{
int lkm = 0;
if (a == 6) lkm++;
if (b == 6) lkm++;
return lkm;
}
// DELETEEND
#else
// BYCODEBEGIN
/// <summary>
/// Funktio palauttaa suuremman luvuista a ja b
/// </summary>
/// <param name="a">ensimmäinen luku</param>
/// <param name="b">toinen luku</param>
/// <returns>suurempi luvuista a ja b</returns>
/// <example>
/// <pre name="test">
/// // Laskuja.Suurempi(2,1) === 2;
/// </pre>
/// </example>
public static int Suurempi(int a, int b)
{
if (a >= b)
{
return a;
}
return b;
}
// BYCODEEND
#endif
// REMOVEBEGIN
public static void Tarkista()
{
System.Console.WriteLine("-----------------------------------------------------------------");
double p = 0;
p += t(1, 1);
p += t(2, 6);
p += t(6, 2);
p += t(6, 6);
p += t(7, 6);
p *= 2.0 / 5;
System.Console.WriteLine("Pisteet: {0:0.00}", p);
System.Console.WriteLine("RANDOMCHECK: {0:0.00}", p);
}
public static int t(int a, int b)
{
int tuli = MontakoKuutosta(a, b);
int piti = Malli(a, b);
if (tuli == piti) return 1;
System.Console.WriteLine("Syöte: a={0}, b={1}, palautti: {2}, piti palauttaa {3}", a, b, tuli, piti);
return 0;
}
public static int Malli(int a, int b)
{
int m = 0;
if (a == 6) m++;
if (b == 6) m++;
return m;
}
// REMOVEEND
}
!!
```
Edellä on tarkoituksena saada koodi, jossa IDEssä ajettuna käytetään tuota mallivastauksena toimivaa #if true
osaa. TIMissä ajettuna käyttäjälle näytetään BYCODEBEGIN
/BYCODEEND
välillä olevaa pohjafunktiota, jonka on vain tarkoituksena toimia mallina miten funktio kommentoidaan ja testataan.
Käyttäjältä poistetaan näkyvistä REMOVEBEGIN
/REMOVEEND
välinen osa Näytä koko koodi
-näkymässä sekä myös mahdollisten virheilmoitusten tapauksessa. Samoin poistetaan pääohjelmassa oleva Tarkista
-rivi. Kuitenkin nämä rivit menevät kääntäjälle. Kokonaan käännöksestä TIMissä poistetaan DELETEBEGIN
/DELETEEND
väli sekä deleteLine
-attribuutilla sanotut rivit, eli tässä tapauksessa ne, jotka alkavat #
-merkillä. Alempana on esimerkki miltä näkymä näyttää TIMissä käyttäjälle.
Attribuutti fullprogram
voidaan korvata myös attribuutilla fullfile
, jolloin annetaan URL, josta ohjelma luetaan. Sisältö voi olla täysin samanlainen kuin edellä. Tämän tarkoituksena on mahdollistaa koodin ylläpito esimerkiksi versiohallinnassa. Mikäli attribuuttien edessä on miinus, ei käyttäjä näe muuta koodin osaa kuin pohjakoodiksi tulleen osan. Itse fullX
-osa ei koskaan tule käyttäjän näkyville.
Netistä haettavat tiedostot puskuroidaan, jolloin jos niitä muutetaan, on syytä tyhjentää puskurit:
Esimerkin avainsanojen merkitys:
REMOVEBEGIN
- aloittaa lohkon, joka poistetaan virheilmoituksista ja dokumentaatiosta. Käännettävään koodiin lohko jää. Koko rivi, jolla tämä avainsana poistuu. Tämä käytössä jos attribuuttiacutErrors
ei anneta.REMOVEEND
- lopettaa em lohkonDELETEBEGIN
- aloittaa lohkon joka poistetaan kaikkialtaDELETEEND
- lopettaa em lohkonBYCODEBEGIN
- aloittaa lohkon, joka korvataan käyttäjän vastauksella. tämän lohkon sisältö menee oletukseksi käyttäjän vastaukseenBYCODEEND
- lopettaa em. lohkonREMOVELINE
- regexp sääntö, jonka toteuttava osa poistetaan virheilmoituksista ja dokumentaatiostaDELETELINE
- regexp sääntö, jonka toteuttava osa tuhotaan kokonaanRANDOMCHECK
- jono, joka korvataan satunnaisella heksajonolla, joka on ainutkertainen jokaisella ajokerralla. Tällä pienennetään mahdollisuutta huijata pistelaskua liian yksinkertaisilla tavoilla#if
- C#-kielen makro, jolla voidaan säätää, meneekö joku koodinosa käännökseen vaiko ei. Edellä on haluttu, että käyttäjän syötteeksi tulee oletuksena aivan eri funktio, jota myös halutaan IDE:ssä helposti testata, mitä tulee tulokseksi. Varsinainen itse tehty funktio syödään TIMissä pois. Jatkossa voi tulla vielä avain sanatMODELANSWERBEGIN
jaMODELANSWEREND
. AttribuutilladeleteLine
tuhotaan TÄSSÄ esimerkissä #-alkuiset rivit pois näkyvistä. Python-koodissa eikä muissa tätä ole syytä olla ainakaan samassa muodossa.
Nuo REMOVE- yms alkuiset rivit kannattaa aloittaa ko. kielen kommentilla, siis Pythonissa #
-merkillä.
Huomaa että BYCODEBEGIN/BYCODEEND
lohkon sisällä ei saa olla muita "muokkaavia" lohkoja!
Edellä jää käyttäjälle vielä mahdollisuus huijata tekemällä omaksi vastauksekseen kutsun:
return Malli(a,b);
Tätä voidaan estää, mikäli mallifunktion nimessä käytetään satunnaisjonoa, eli korvataan funktion kutsu ja nimi tyyliin:
int piti = MalliRANDOMCHECK(a, b);
...
public static int MalliRANDOMCHECK(int a, int b)
jolloin ajon aikana funktion nimi voi olla mitä tahansa. Periaatteessa käyttäjä voi selvittää tämänkin nimen, mutta se vaatii jo enemmän osaamista. Toinen mahdollisuus, jota on hieman vaikeampi kiertää, on lisätä kutsuun ylimääräinen parametri:
int piti = Malli(a, b, "RANDOMCHECK");
...
public static int MalliRANDOMCHECK(int a, int b, string check)
{
if ( check != "RANDOMCHECK" ) ... huijaus ...
Alla jälkimmäisellä tavalla toteutettu plugin (tosin muutettu niin, että funktio on valmiiksi oikean niminen ja kääntyvä), jota saa yrittää saada toimimaan huijaamalla. Tavoitteena on saada itselleen tuosta 5 pistettä (oletuksena oikeasta tulee 2p).
11.1 Extra files
Yksi isompi attribuutti on extrafiles
, jolla on tarkoitus hakea mahdollisesti ajossa tarvittavia aputiedostoja. Muoto on:
-extrafiles:
-
name: temp/k6_with_NAND.txt
delete: true
text: |
{
"devices":[
{"type":"DC","id":"dev0","x":56,"y":144,"label":"DC"},
...
-
text: kissa # tämä saan nimekseen extrafile2
-
name: kuva.png
type: bin
file: "http://oma.com/kuva.png"
Eli kyseessä on taulukko, jossa luetellaan tarvittavat tiedostot. Tiedoston sisältö voidaan antaa tekstinä kuten 1. esimerkissä tai sitten hakea netistä. Jos tyyppiä ei anneta, haetaan tiedosto tekstinä. Attribuutti delete: true
aiheuttaa sen, että ajon jälkeen tiedosto tuhotaan.
Attribuuttia voidaan käyttää kaikkien tyyppien kanssa ja tiedostot haetaan ennen kääntämis- ja ajamiskomentoja.
12. Arvostelu extrafiles avulla
Esimerkki, jossa pitäisi antaa joku kissaeläimen nimi ja sitten saa pisteitä seuraavasti:
- tiikeri: 0.8 p
- kissa: 0.5 p
- muut 0 p
ja noista kustakin tulee joku palaute:
Koodi, jolla em. plugin on tuotettu:
``` {#lueKissa plugin="csPlugin"}
type: text
path: user
placeholder: "kirjoita joku kissaeläimen nimi tähän"
filename: vastaus.txt
-pointsRule:
readpoints: "Pisteet: (.*)\n"
cmd: "python3 arvostele.py vastaus.txt"
-extrafiles:
-
name: arvostele.py
text: |!!
import sys
import re
lines = open(sys.argv[1], 'r').read()
if re.match(".*tiikeri.*", lines):
print("Pisteet: 0.8")
print("Tämä oli hyvä")
elif re.match(".*kissa.*", lines):
print("Pisteet: 0.5")
print("Aika tavallinen")
else:
print("Pisteet: 0.0")
print("En tunne tätä kissaeläimeksi!")
!!
```
Edellä voitasiin Pisteet
-sanan tilalla käyttää sanaa RANDOMCHECK
, jos halutaan pienentää kaappauksen mahdollisuutta. Tosin tässä kun käyttäjä ei pääse kirjoittamaan ajettavaa koodia, on sen todennäköisyys aika pieni muutenkin.
Katso myös:
13. Palautteen antaminen HTML:änä tai kuvana
Palautteen voi antaa em. tavalla vaikka Python-skriptillä tekstinä tai sitten myös lisäksi kuvana tai HTML:nä lisäämällä attribuutit (kaikki tai vain yhden)
-replyImage: URLKUVAAN JONNEKIN
-replyHTML: |!!
<p>HTMLää joka näkyy vastauksen jälkeen</p>
!!
-replyMD: |!!
**Hyvä %%username%%!** Huomasit että se on $3x^2 + 2$
!!
Palaute tulee keskitettynä tehtävän alle. Jos haluat että kaikki dokumentin palautteet ovat jollakin eri tavalla, niin lisää dokumentin asetuksiin esimerkiksi:
css: |!!
.htmlresult {
text-align: left;
margin-left: 3em;
margin-right: 3em;
}
!!
14. Vinkkien ostaminen
Edellistä voisi käyttää hyväkseen esimerkiksi siten, että on "tehtävä", jonka ainoa toiminto on "ostaa vinkki". Tämän painamisesta annetaan vaikkapa -2p ja siten kun on painettu, näytetään vinkkiteksti.
``` {plugin="csPlugin" #xt2kaosto2}
type: text
wrap: -1
filename: Vinkki_käytetty
header: "Osta vinkki lukumäärän laskemisesta: (-2p)"
stem: 'md:Jos haluat vinkin ja mallivastauksen,
voit ostaa sen tästä. [Älä vaan osta]{.red} tätä jos et tarvitse, **ostoa ei voi palauttaa**!
Jos vinkki häviää näytöstä, saat sen takaisin ilman lisähintaa "ostamalla" uudelleen.
'
editorModes:
button: "Osta vinkki 2:lla pisteellä"
-pointsRule:
code: -2
expectCode: .*
min_points: -2
-replyMD: |!!
Aloita siitä, että **kissa** on hieno eläin!
!!
```
15. Pluginin tyyppi/Kielet
Pluginin type
attribuutti voi saada arvoja:
"jypeli", - C\# JyPeli-ohjelma
"java", - perus Java-ohjelma
"graphics", - Java-ohjelma, johon linkitetään Graphics-kirjasto
"cc", - C-ohjelma
"c++", - C++ -ohjelma
"shell", - shell -ohjelma
"py", - Python-ohjelma
"fs", - F# -ohjelma
"clisp", - CommonLisp -ohjelma
"jjs", - JavaScript palvelimella
"psql", - PostgreSQL
"sql", - SQLite
"alloy", - Alloy SAT-ratkaisija
"text", - pelkkä teksti, ainoastaan tallennetaan käyttäjän levylle
"cs", - C# (oletus)
"run", - komento, joka ajetaan
"md", - md (esim. ohjeiden kirjoittamista varten)
"js", - JavaScript selaimessa
"sage", - Sage-matematiikka
"simcir", - SimCir-piirisimulointi
"r" - R-kieli
"all" - mikä tahansa kieli, tällöin tulee valintalista, kielet
voi rajata languages attribuutilla
"xml" - periaatteesa sama kuin text, mutta syntax highlight xml:än mukaan
"css" - periaatteesa sama kuin text, mutta syntax highlight css:än mukaan
"octave" - Octave
"lua" - Lua
"upload" - tekee pluginista Upload-pluginin. Oletuksena poistetaan
kaikki muu turha. Upload voi olla käytössä yhtäaikaa
ilmankin tätä, kun käyttää upload-attribuuttia, mutta silloin
pitää itse poistaa turhia painikkeita yms., jos niitä ei haluta.
"html" - HTML opetukseen
"glowscript" - 3D java grafiikka
"vpython" - kuten em, mutta Pythonmaisella kielellä
"swift" - Applen uusi kieli
"octave" - Octave matematiikka
"processing" - Processing-kieli
"wescheme" - WeScheme
"kotlin" - Kotlin
"fortran" - Fortran
"scala" - Scala
"racket" - Racket (PLT Scheme)
"rust" - Rust
"pascal" - Free Pascal
"go" - GO, kääntäjä on, mutta ei vielä valmista toimintoa, käännä sh:lla
"extcheck" - ExtCheck, tarkemmat ohjeet myöhemmin
"gitreg" - GitReg, rekisteröintilaatikko ulkoiseen git palveluun.
"ts" - TypeScript
"mathcheck" - MathCheck
"maxima" - Maxima
Attribuutin type
yhteyteen voidaan kauttaviivalla liittää muitakin määreitä: language/modifier 1/modifier 2/...
language
määrää kielen ja modifier
eilla voidaan muokata käyttäytymistä. Esimerkkejä:
type: cs/comtest - voidaan ajaa ComTestejä ja tulee Test-painike
type java/input/args - tulee näkyviin input-alue ja args-alue
type: csconsole/shell - shell, jota käytetään erilaisesta konsolista
type: cs/doc - tulee myös Document-linkki, josta tulee Doxygen-dokumentti
type: all/comtest - tulee lista valittavista kielistä
input
-määreen lisäksi voidaan tarvita attribuutti stdin
, jolla kerrotaan, mikä tiedosto liitetään oletussyötteeseen:
stdin: input.txt
ACE-editorin korostusta vaihdetaan tyypin mukaan.
Attribuutin type
modifierit voi saada arvoja:
"jypeli", - C\# JyPeli-ohjelma
"graphics", - Java-ohjelma, johon linkitetään Graphics-kirjasto
"tauno" - Tauno
"tiny" - Pienempi laatikko
"input" - Lisää input laatikon
"args" - Lisää args laatikon
"doc" - Lisää Document-linkki, josta tulee Doxygen-dokumentti
"csconsole" - C# konsoli
"parsons" - Parsons editori
"gitcheck" - Tarkastaa, onko käyttäjä rekisteröitynyt
ulkoiseen git palveluun ja tekee asioita sen perusteella.
16. path-attribuutti
- Ei
path
attribuuttia (siellä pluginissa)- jokaiselle ajokerralle tulee uniikki oma polku ja tiedot tuhotaan ajon jälkeen
- ei sovi SQL-kurssille
path: user
- käyttäjälle luodaan TIMin
/tmp/user
hakemistoon oma käyttäjäkohtainen hakemisto (nimi salattu) eli/tmp/user/HASH
ja sen alle dokumenttikohtainen hakemisto, johon tehtävän data (tiedostot, käännökset yms) tallentuu. Eli hakemisto on/tmp/usr/HASH/docid
- voi käyttää saman dokumentin sisälle samassa dokumenteissa olleita tehtävien tiedostoja
- ei toimi, jos esim. samaa tietokantaa halutaan jatkaa toisessa dokumentissa, eli esim. kukin demokerta on omana dokumenttinaan
- käyttäjälle luodaan TIMin
path: user/demot
- user perään voidaan antaa kiinteä nimi, ja nyt data tallentuu
/tmp/user/HASH/demot
hakemistoon (nimi voi toki olla jokin muukin kuin demot ja se voi mennä syvemmällekin) - voidaan käyttää samoja tiedostoja eri dokumenttien välillä. Sopii esim. tuohon, että demossa 1 tehdään tietokanta ja muissa demoissa käytetään sitä samaa.
- user perään voidaan antaa kiinteä nimi, ja nyt data tallentuu
- rootPath määritelty:
- rootPathin arvo laitetaan pathin eteen
- esimerkiksi
rootPath: user
japath: demot
yhdessä tarkoittavat, että path onuser/demot
Kohdissa 2, 3 ja 4 pitää muistaa, että /tmp
voidaan tuhota milloin tahansa, jolloin käyttäjälle pitää olla ohje, kuinka voi alustaa tilanteen takaisin. Käyttäjän vastaukset ovat TIMin tietokannassa ja niihin nuo hakemistot eivät vaikuta. Ainoastaan tehtävissä syntyviin "tilapäistiedostoihin".
Jos päätyy kohtiin 2, 3 tai 4, kirjoittamista helpottaa, jos pistää samana pysyvät attribuutit dokumentin alkuun settings-lohkoon tyyliin:
``` {settings=""}
global_plugin_attrs:
csPlugin:
path: user/demot
```
jolloin dokumentin jokainen plugin saa tuon saman attribuutin.
16.1 rootPath-attribuutti
Kun tämä on määritelty, otetaan docker kontin juuripoluksi tämä mukaan. Ohjelman ajo kuitenkin suoritetaan path-attribuutin mukaisessa polussa.
Esimerkki:
rootPath: user/cplusplus
path: Module1/exercise1
Näillä arvoilla dockeriin otetaan user/cplusplus (user sama kuin yllä pathissä) kansion alla olevat tiedostot mukaan docker konttiin ajoa varten. Työskentelykansio ohjelman ajolle on kuitenkin user/cplusplus/Module1/exercise1.
17. files, moreFiles ja deleteFiles -attribuutit
deleteFiles on lista tiedostoista ja kansioista, jotka poistetaan muiden tiedostojen tallentamisen jälkeen, mutta ennen kuin ohjelma ajetaan. Esimerkiksi:
deleteFiles:
- src
- test
poistaa src ja test -nimiset tiedostot tai kansiot.
files -attribuutilla annetaan lista tiedostoista, jotka sisällytetään vastaukseen ja tallennetaan tietokantaan. moreFiles toimii muuten samalla tavalla, mutta siinä listattuja tiedostoja ei sisällytetä tallenneta tietokantaan.
Jokaiselle tiedostolle määritellään source
, joka on oletuksena "editor" ja kertoo, mistä tiedosto saadaan. source
voi saada seuraavat arvot ([]-merkit tarkoittavat valinnaista osaa):
- "editor"
- Tiedoston sisältö kysytään editorin avulla käyttäjältä
- Ei voi käyttää
moreFiles
issä
- "upload"
- Tiedoston sisältö ladataan käyttäjän koneelta ja tallennetaan serverille.
- "uploadByCode"
- Tiedoston sisältö luetaan käyttäjän koneelta ja lähetetään serverille samoin tavoin kuin editorin sisältö
- Ei voi käyttää
moreFiles
issä
- "master:[root tai task, oletuksena task]:[r (regex) tai g (glob), oletuksena g]:<subPath>"
- Tiedosto kopioidaan
masterPath
in määräämästä kansiosta - Jos root: <masterPath>/<subPath>
- Jos task: <masterPath>/<taskPath>/<subPath>
- Kun rootPath on määritelty, taskPath on sama kuin path-attribuutti
- Kun rootPath ei ole määritelty, taskPath on tyhjä
- r tai g (regex tai glob) määrää, miten subPathiä käsitellään
- Tiedosto kopioidaan
- "git:<url>[;<subPath>[;<glob>[;<branch>]]]"
- url määrittelee repon
- subPath kertoo mistä kansiosta alkaen tiedostoja haetaan globin avulla. Oletuksena "" eli juurikansio.
- glob on glob tyylinen polku, joka kertoo mikä kansio tai mitkä tiedostot tallennetaan. Oletuksena "**/*" eli kaikki.
- branch kertoo, mistä git haarasta tiedostot haetaan. Oletuksena "master"
- tiedostot tallennetaan "path" (kts. alla) määreen mukaiseen paikkaan siten, että subPath vastaa pathia (kts. esimerkit alla)
Kaikille tiedostoille on myös määriteltävä "path", joka kertoo, mihin ja millä nimellä kyseinen tiedosto tallennetaan. "/"-merkkiin päättyvä path tarkoittaa, että path on kansio, jonka sisälle tiedosto tallennetaan. path on muotoa [root tai task, oletuksena task]:<polku>
. Kun määritellään "root", polku otetaan tarkoittavan suhteellista polkua rootPath
iin verrattuna. Kun määritellään "task", polku otetaan tarkoittavan suhteellista polkua path
attribuuttiin verrattuna.
Jokaiselle tiedostolle voi myös määritellä "maxSize"n, joka kertoo kuinka suuri tiedosto saa maksimissaan olla. Tällä hetkellä tämä tarkastetaan palvelimen puolella vain "files"issä määriteltyjen git tiedostojen kanssa. Lisäksi upload ja uploadByCode tiedostojen koko tarkastetaan käyttäjän selaimessa (älä siis luota siihen, että tiedosto ei voi olla suurempi, koska käyttäjä voi periaatteessa kiertää sen).
Esimerkkejä:
rootPath: user/example
path: first
files:
- source: editor # kysytään editorilla käyttäjältä
path: src/main.c # tallennetaan tiedostoon user/example/first/src/main.c
- source: git:git@gitlab.com:tim-jyu/tim.git;timApp/modules;cs/*
# haetaan gitlab.com:tim-jyu/tim.git reposta, kansiosta timApp/modules
# kaikki tiedostot, jotka sopivat "cs/*" -globiin
path: root:gitfiles/ # tiedostot tallennetaan user/example/gitfiles-kansioon
# esimerkiksi tiedosto cs.py git repon cs-kansiossa tallennettaisiin
# polkuun user/example/gitfiles/cs/cs.py
# (eli subPath "timApp/modules" jätettiin pois välistä)
maxSize: 100 # yksittäisen tiedoston maksimi koko 100 kB
maxTotalSize: 200 # tiedostojen koko yhteensä maksimissaan 200 kB
moreFiles:
- source: master:cplusplus/first/test/* # kaikki tiedostot polusta masters/cplusplus/first/test
path: test/ # tallennetaan user/example/first/test kansioon
- source: master:cplusplus/first/scripts/* # kaikki tiedostot polusta masters/cplusplus/first/scripts
path: root:scripts/ # tallennetaan user/example/scripts kansioon
Eri sourcejen kaikki attribuutit (oletusarvo pilkun jälkeen):
yhteiset:
"source" # lähdetyyppi (ja tarvittaessa polku)
"path" # tiedoston tallennuspolku
"maxSize" # tiedoston maksimikoko
"byCode" # tiedoston aloitus sisältö (ei taida toimia muiden kuin editorin kanssa)
editor:
"mode", kielen antama # ACE-editorin moodi
"placeholder" # editorin placeholder teksti
"canClose", false # voiko tiedoston sulkea selaimessa (buginen, ei suositeltavaa)
"canRename", false # voiko tiedoston nimetä uudelleen selaimessa (buginen, ei suositeltavaa)
upload:
"paths" # lista eri tiedostonimistä, jotka ohjataan tähän tiedostolähteeseen (kts. alla)
"extensions" # lista tiedostopäätteistä, jotka ohjataan tähän tiedostolähteeseen (kts. alla)
maxSizen oletusarvo maxSize-attribuutista
uploadByCode:
"show", false # näytetäänkö tiedosto editorissa. Voi olla true, false tai "loaded".
# Jos "loaded", näytetään lataamisen jälkeen
...samat kuin editorissa ja uploadissa
git:
"maxTotalSize" # tiedostojen maksimiyhteiskoko
Kun käyttäjä yrittää ladata useamman tiedoston kerralla, path ja extensions -kenttiä käytetään näiden tiedostojen jakamiseen oikeisille upload ja uploadByCode -lähteille, kun lähteitä on useampia. Esimerkiksi voidaan laittaa yhteen lähteeseen ".h" extension ja toiseen ".c", jolloin *.h tiedostot laitetaan ensimmäiseen ja *.c tiedostot toiseen lähteeseen, kun ladataan useampi tiedosto kerralla.
Esimerkki:
``` {plugin="csPlugin" #helloc}
type: cc
-pointsRule:
expectOutput: "Hello world!\n"
files:
- source: editor
path: main.c
byCode: |!!
#include "hello.h"
int main(void) {
// kutsu tässä hello-aliohjelmaa
}
!!
- source: editor
path: hello.h
byCode: |!!
#ifndef HELLO_H
#define HELLO_H
void hello();
#endif
!!
- source: editor
path: hello.c
byCode: |!!
#include <stdio.h>
void hello() {
printf("Hello world!\n");
}
!!
```
Joka näyttäisi tältä:
18. Review
Review-toimintoa (velpit) varten on mahdollisuus antaa attribuutti
review: true
tai kutsua parametrilla ?review=true
. Tällöin palautetaan pelkkä käyttäjän vastauksesta riippuva HTML-muoto, jossa on mahdollisesti myös input
ja args
-osiin annetut vastaukset. Vastaukset on ympäröity divillä, jossa on review
-tyyli, jolla voi määrittää vastausalueen ulkoasun:
<div class="review">
<pre>System.Console.WriteLine("Moi");</pre>
<p>Input:</p>
<pre>Mun syöte</pre>
<p>Args:</p>
<pre>Mun argsit</pre>
</div>
19. ExtCheck
Tarkoituksena on pystyä ajamaan ulkoinen arvosteluohjelma, joka antaa pisteet ja mukautetun tulosteen. Arvosteluohjelma voi olla esimerkiksi python skripti, joka kopioidaan master-lähteestä. Jos arvosteluohjelma ei ole itse kehitetty, on todennäköisesti tarpeellista tehdä välikäsiskripti, joka ajaa arvosteluohjelman, lukee sen tuloksen ja tulostaa sen oikeassa formaatissa TIMille.
Attribuutit:
command: yksittäinen ajettava komento. Tästä lisää alempana
commands: sanakirja eri komennoista. commandKey:llä valitaan tästä komento.
commandKey: komennon avain commands-sanakirjaan jos commandiä ei ole määritely, oletuksena 'run'
jsFiles: lista polkuja javascript tiedostoihin, jotka ladataan käyttäjälle.
Polut voi olla absoluuttisia (esim. /cs/masters/... tai https://...)
tai suhteellisia (ei ala '/' tai 'http'), jolloin se on suhteellinen masterPath-attribuuttiin.
cssFiles: sama kuin jsFiles, mutta css tiedostoille
Komennot voivat olla joko lista argumentteja tai yksittäinen merkkijono, kuten pythonin subprocess.run funktiolle annetaan. Kaikki 'points_rule'-merkkijonot komennoissa korvataan points_rule jsonilla.
Komennon tulee tulostaa standardi outputtiin json objekti seuraavilla kentillä:
points: annetut pisteet
max_points: maksimi pisteet. Annetut pisteet skaalataan tämän avulla
timissä määriteltyihin maksimipisteisiin.
penalties: sanakirja, jonka avaimet ovat points_rulessa määriteltyjä
penaltyjä ja jonka arvot on true, false tai merkkijono, joka kertoo mikä on väärin.
Merkkijono tarkoittaa true. Arvot on oletuksena false eli ei rankaisua.
output_boxes: lista objekteja {
hide: <boolean: piilotetaanko elementti oletuksena>,
title: {
classes: otsikko elementin css luokat,
content: otsikon sisältö,
isHTML: onko otsikko html,
isAngular: onko otsikko angularia
},
content: {
classes: sisältö elementin css luokat,
content: sisältö,
isHTML: onko sisältö html,
isAngular: onko sisältö angularia
}
}
Tästä olisi kiva nähdä kokonainen toimiva esimerkki.
—20. Git
20.1 git ja gitDefaults -attribuutit
git:
"onError" # mitä tehdään, kun sattuu virhe gitcheckissä
"library" # käytettävä git kirjasto
"fields" # kirjastolle annettavat tunnistetiedot (kts. GitReg)
"askFields" # käyttäjältä kysytyt kirjastolle annettavat tunnistetiedot (kts. GitReg)
"repo" # repon tiedot (kts. GitReg)
20.2 Kirjastot
Kirjastoja on tällä hetkellä kaksi: gitea ja gitea_aalto. Oletuksena courses-git.comnet.aalto.fi -osoitteelle käytetään gitea_aalto-kirjastoa.
TODO: lisää kirjastokohtaisia asioita
20.3 GitReg-kieli
GitReg luo käyttäjän ja/tai repon halutulle git palvelulle, kunhan sille löytyy sopiva kirjasto. Käyttäjän tiedot annetaan git-attribuutin fields ja askFields -kentillä. askFields on lista tiedoista, jotka kysytään käyttäjältä ja lähetetään eteenpäin kirjastolle. fields on sanakirja (dictionary), jonka avaimet ovat tietojen nimiä ja arvot muotoa
value: <arvo>
onError: raise, ask tai none. Oletuksena raise
valueen laitetaan arvo, joka annetaan kirjastolle, ja onError kertoo, mitä tehdään, jos kirjasto ei hyväksy kyseistä arvoa. onError vaihtoehdot:
raise: rekisteröinti keskeytetään ja käyttäjälle näytetään virheviesti
ask: annettu arvo heitätään pois ja kysytään uusi arvo käyttäjältä
none: arvoksi asetetaan None
Esimerkki:
git:
fields:
name:
value: %%realname%% # otetaan käyttäjän nimi TIMistä
email:
value: %%useremail%% # otetaan käyttäjän sähköposti TIMistä
onError: ask # jos sähköpostiosoite ei kelpaa, kysytään se käyttäjältä
askFields:
- username # kysytään käyttäjältä, minkä käyttäjänimen hän haluaa
repo-kenttä on muotoa
name: <repon nimi>
owner: <repon omistaja> # oletuksena kirjaston TIM itse
fork: <bool; onko repo fork> # oletuksena false
oldName: <kopioitavan repon nimi> # oletuksena sama kuin name
oldOwner: <kopioitavan repon omistaja> # oletuksena sama kuin owner
librarySpecific: <kirjasto kohtaiset tiedot>
20.4 GitCheck-modifier
GitCheck tarkastaa onko git-attribuutissa määritelty käyttäjä olemassa (fields-kentän arvojen perusteella, gitcheck ei kysy mitään käyttäjältä) ja toimii git-attribuutin onError-kentän mukaisesti.
onError vaihtoehdot:
raise: käyttäjälle näytetään virheviesti ja tehtävän ajaminen estetään
create: repo yritetään luoda, jos sitä ei ole olemassa. Jos ongelma on, että
käyttäjää ei ole olemassa, tehdään raise.
remove: fields-kentästä poistetaan lähteet, jotka ovat samasta reposta kuin
gitDefaultsissa mainittu repo.
removeAll: ields-kentästä poistetaan kaikki git-lähteet
21. Ehdotuksia
21.1 Vanhoja ehdotuksia TIMin käsiteltäviksi attribuuteiksi:
Näistä osa on jo toteutettukin. Jos on
-pointsRule:
divideBy: 6
niin tuo tarkoittaisi että se lukema, minkä plugin antaa, talletetaan 6:lla jaettuna.
Sitten ehkä jatkossa vielä jotakin, millä saa tuon RegExp-kokeen säännöt:
https://tim.jyu.fi/view/ohj2/materiaali/RegExp
Ehkä tyyliin (oletus että plugin palauttaa maksimisuorituksesta 10 p):
-pointsRule:
max: 10
min: 5
dec: 0.5
22. Moniriviset YAML-attribuutit
Seuraava yhteenveto on otettu:
> | " ' >- >+ |- |+
-------------------------|------|-----|-----|-----|------|------|------|------
Trailing spaces | Kept | Kept | | | | Kept | Kept | Kept | Kept
Single newline => | _ | \n | _ | _ | _ | _ | _ | \n | \n
Double newline => | \n | \n\n | \n | \n | \n | \n | \n | \n\n | \n\n
Final newline => | \n | \n | | | | | \n | | \n
Final dbl nl's => | | | | | | | Kept | | Kept
In-line newlines | No | No | No | \n | No | No | No | No | No
Spaceless newlines| No | No | No | \ | No | No | No | No | No
Single quote | ' | ' | ' | ' | '' | ' | ' | ' | '
Double quote | " | " | " | \" | " | " | " | " | "
Backslash | \ | \ | \ | \\ | \ | \ | \ | \ | \
" #", ": " | Ok | Ok | No | Ok | Ok | Ok | Ok | Ok | Ok
Can start on same | No | No | Yes | Yes | Yes | No | No | No | No
line as key |
Examples
Note the trailing spaces on the line before "spaces."
- >
very "long"
'string' with
paragraph gap, \n and
spaces.
- |
very "long"
'string' with
paragraph gap, \n and
spaces.
- very "long"
'string' with
paragraph gap, \n and
spaces.
- "very \"long\"
'string' with
paragraph gap, \n and
s\
p\
a\
c\
e\
s."
- 'very "long"
''string'' with
paragraph gap, \n and
spaces.'
- >-
very "long"
'string' with
paragraph gap, \n and
spaces.
[
"very \"long\" 'string' with\nparagraph gap, \\n and spaces.\n",
"very \"long\"\n'string' with\n\nparagraph gap, \\n and \nspaces.\n",
"very \"long\" 'string' with\nparagraph gap, \\n and spaces.",
"very \"long\" 'string' with\nparagraph gap, \n and spaces.",
"very \"long\" 'string' with\nparagraph gap, \\n and spaces.",
"very \"long\" 'string' with\nparagraph gap, \\n and spaces."
]
These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.