├── .babelrc ├── .editorconfig ├── .github └── workflows │ └── main.yml ├── .gitignore ├── .prettierrc ├── .vscode └── settings.json ├── Dockerfile ├── README.md ├── banner.svg ├── bin ├── check-code-style.sh └── update-material-template.sh ├── course-metadata.json ├── course-settings.js ├── data ├── all-exercises.md ├── error_messages.md ├── exam.md ├── exam_adv.md ├── exam_intro.md ├── faq.md ├── frontmatter-guide.md ├── grading-and-exams.md ├── img │ ├── diagrams │ │ ├── luokkakaavio-abstraktit.png │ │ ├── luokkakaavio-henkilo-getterit.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-getnimi.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene-ja-palautaika.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori.png │ │ ├── luokkakaavio-henkilo-ika-ja-nimi.png │ │ ├── luokkakaavio-henkilo-ja-syntymapaiva.png │ │ ├── luokkakaavio-henkilo.png │ │ ├── luokkakaavio-kirja-henkilo-kaksisuuntainen-monesta-moneen.png │ │ ├── luokkakaavio-kirja-henkilo-kaksisuuntainen.png │ │ ├── luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittaja.png │ │ ├── luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat-ja-metodit.png │ │ ├── luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat.png │ │ ├── luokkakaavio-kirja-nimi-ja-kustantaja.png │ │ ├── luokkakaavio-kirja-toteuttaa-luettavan.png │ │ ├── luokkakaavio-kirja.png │ │ ├── luokkakaavio-maatilasimulaattori.png │ │ ├── luokkakaavio-moottori-perii-osan.png │ │ ├── luokkakaavio-muistava-tuotevarasto.png │ │ ├── luokkakaavio-paita.png │ │ ├── luokkakaavio-rajapinta-luettava.png │ │ ├── luokkakaavio-soittolista.png │ │ ├── luokkakaavio-teht-huone.png │ │ ├── luokkakaavio-teht-koira.png │ │ ├── luokkakaavio-teht-luokka.png │ │ ├── luokkakaavio-teht-maksukortti.png │ │ └── luokkakaavio-teht-ruokalista.png │ ├── drawings │ │ ├── arraylist-add.png │ │ ├── arraylist.png │ │ ├── boolean-muuttuja.png │ │ ├── eka-1 (copy).png │ │ ├── eka-1.ora │ │ ├── eka-1.png │ │ ├── eka-2 (copy).png │ │ ├── eka-2.ora │ │ ├── eka-2.png │ │ ├── eka-3 (copy).png │ │ ├── eka-3.ora │ │ ├── eka-3.png │ │ ├── eka-4 (copy).png │ │ ├── eka-4.ora │ │ ├── eka-4.png │ │ ├── eka-5 (copy).png │ │ ├── eka-5.png │ │ ├── hashmap.png │ │ ├── henkilot-ja-juhana.ora │ │ ├── henkilot-ja-juhana.png │ │ ├── muhammad-ja-pascal.ora │ │ ├── muhammad-ja-pascal.png │ │ ├── muuttujan-arvon-vaihto-0.png │ │ ├── muuttujan-arvon-vaihto-1.png │ │ ├── muuttujan-arvon-vaihto-2.png │ │ ├── muuttujan-arvon-vaihto-3.png │ │ ├── muuttujan-arvon-vaihto-4.png │ │ ├── olio-joan-ja-ball-2.ora │ │ ├── olio-joan-ja-ball-2.png │ │ ├── olio-joan-ja-ball-3.ora │ │ ├── olio-joan-ja-ball-3.png │ │ ├── olio-joan-ja-ball-null.ora │ │ ├── olio-joan-ja-ball-null.png │ │ ├── olio-joan-ja-ball.ora │ │ ├── olio-joan-ja-ball.png │ │ ├── olio-joan.png │ │ ├── stream-pre-edit.png │ │ ├── stream.ora │ │ ├── stream.png │ │ └── while-true-break.png │ ├── ennustaja-1.png │ ├── ennustaja-2.png │ ├── ennustaja-3.gif │ ├── et_phone_home.wav │ ├── exercises │ │ ├── 01-10-jakolaskin.png │ │ ├── 01-22-maara.png │ │ ├── 01-30-jahtaus.png │ │ ├── 02-12-01.png │ │ ├── 02-12-02.png │ │ ├── 03-12-rivit.png │ │ ├── 06-14-piirturi-ok.png │ │ ├── 06-15-gameoflife.png │ │ ├── 06-19-matkavalokuvat-1.png │ │ ├── 06-19-matkavalokuvat-2.png │ │ ├── 06-19-matkavalokuvat-mediaani.png │ │ ├── 06-19-matkavalokuvat-tummin.png │ │ ├── 06-19-matkavalokuvat-vaalein.png │ │ ├── 10-08-asteroids.png │ │ ├── luokkakaavio-asiakas.png │ │ ├── luokkakaavio-iso-abstrakti.png │ │ ├── luokkakaavio-kirja-ja-lentokone.png │ │ ├── luokkakaavio-naytos-ja-lippu.png │ │ ├── luokkakaavio-opiskelija-ja-korkeakoulu.png │ │ ├── luokkakaavio-pelaaja-ja-tekoaly.png │ │ ├── luokkakaavio-tallennettava-henkilo.png │ │ ├── schelling-alku.png │ │ └── schelling-loppu.png │ ├── front-desk-bells-daniel_simon.wav │ ├── hiekkaranta-1.png │ ├── kollaasi-monalisa-kulma.png │ ├── kollaasi-monalisa-neg.png │ ├── kollaasi-monalisa-ruudut.png │ ├── kollaasi-monalisa.png │ ├── lohkoesimerkki-1.png │ ├── lohkoesimerkki-2.png │ ├── lohkoesimerkki.png │ ├── lyrics.png │ ├── macos-guide │ │ ├── add_tmcbeans.png │ │ ├── done.png │ │ ├── navigation.png │ │ ├── open-lock.png │ │ ├── search_system_preferences.png │ │ ├── system_preferences.png │ │ └── tmcbeans_added.png │ ├── material │ │ ├── alus-ampuu.gif │ │ ├── alus-kiihtyy-fiksummin.gif │ │ ├── ammus-poistaa-asteroidin.gif │ │ ├── ammus-poistuu.gif │ │ ├── asteroidi-huti.gif │ │ ├── asteroidit-liikkuu.gif │ │ ├── asteroids-ammuskelua.gif │ │ ├── asteroids-monta-asteroidia.png │ │ ├── asteroids-pisteet.png │ │ ├── asteroids-pysyy-ruudussa.gif │ │ ├── asteroids-ready.gif │ │ ├── asteroids-satunnaiset-monikulmiot.png │ │ ├── asteroids-tormays.gif │ │ ├── autocomplete-2.png │ │ ├── autocomplete-with-comment.png │ │ ├── autocomplete.png │ │ ├── gui-animaatio.gif │ │ ├── gui-borderpane.png │ │ ├── gui-gridpane-3x3.png │ │ ├── gui-hbox-spacing.png │ │ ├── gui-hbox.png │ │ ├── gui-helloworld.png │ │ ├── gui-hymio.png │ │ ├── gui-ilmoitin-1.png │ │ ├── gui-ilmoitin-2.png │ │ ├── gui-kopioija-2.png │ │ ├── gui-kopioija.png │ │ ├── gui-lisaa-henkilo.png │ │ ├── gui-nakyman-vaihto.gif │ │ ├── gui-nappi-ja-teksti-rivitetty.png │ │ ├── gui-nappi-ja-teksti.png │ │ ├── gui-nappi.png │ │ ├── gui-paint.png │ │ ├── gui-planeetat-painava-aurinko.gif │ │ ├── gui-planeetat-painavampi-aurinko.gif │ │ ├── gui-planeetat.gif │ │ ├── gui-ristinolla.png │ │ ├── gui-salasana.gif │ │ ├── gui-sanaharjoittelu.gif │ │ ├── gui-simulaatio-metalli-ja-hiekka.gif │ │ ├── gui-simulaatio-metalli.gif │ │ ├── gui-simulaatio.gif │ │ ├── gui-tekstielementti.png │ │ ├── gui-tervehtija.gif │ │ ├── gui-tilastoja.gif │ │ ├── gui-useampi.png │ │ ├── gui-vbox-spacing.png │ │ ├── humming-kaannetty.png │ │ ├── hurraa-nappi.png │ │ ├── image-ja-imageview.png │ │ ├── junit-laskimentestailua.png │ │ ├── junit-test-results.png │ │ ├── junit-test.png │ │ ├── kaavio-kannatus-rkp-ja-vihr.png │ │ ├── kaavio-pohjoismaiden-asukasluvut.png │ │ ├── kaavio-shanghai.png │ │ ├── kaavio-suhteellinen-kannatus.png │ │ ├── kaavio-suurten-lukujen-laki.png │ │ ├── kirjoitusharjoittelu.png │ │ ├── kuva-mysteeri.png │ │ ├── kuvaaja-liittyman-nopeus.png │ │ ├── luokka-luotuna.png │ │ ├── monalisa-kollaasi-alku.png │ │ ├── monalisa-kollaasi.png │ │ ├── monalisa-negatiivi.png │ │ ├── netbeans-output-venla.png │ │ ├── non-compiling-2.png │ │ ├── non-compiling-3.png │ │ ├── non-compiling-4.png │ │ ├── non-compiling.png │ │ ├── pane-alus-kiihtyy.gif │ │ ├── pane-alus-liikkuu.gif │ │ ├── pane-circle.png │ │ ├── pane-polygon-move-rotate-better.gif │ │ ├── pane-polygon-move-rotate.gif │ │ ├── pane-polygon-move.gif │ │ ├── pane-suunnikas-move-rotate.png │ │ ├── pane-suunnikas-siirretty.png │ │ ├── pane-suunnikas.png │ │ ├── perinta.gif │ │ ├── pisteet-kasvavat.gif │ │ ├── project-clean-and-build.png │ │ ├── project-properties.png │ │ ├── puolitushaku-ide-kommentit.png │ │ ├── string-api-perinta.png │ │ ├── tehtavienhallinta-luokat.png │ │ ├── tehtavienhallinta-testiluokka.png │ │ ├── vapaarobotti-kahdeksantoistakulmio.png │ │ ├── vapaarobotti-kolmio.png │ │ ├── vapaarobotti-kuusikulmio.png │ │ ├── vapaarobotti-nelio.png │ │ └── visualisointi-pyorat.png │ ├── matopeli.png │ ├── maven-1.png │ ├── metodivuokaavio.png │ ├── metodivuokaavio2.png │ ├── pong-screenshot.png │ ├── puuta │ │ ├── ikkuna-ja-viiva.png │ │ ├── komennot.png │ │ ├── puisevaa.png │ │ └── toisto.png │ ├── rintamamiestalo-rakennuspiirrustus.jpg │ ├── rintamamiestalo.jpg │ ├── saastolaskuri-1.png │ ├── saastolaskuri-2.png │ ├── saastolaskuri-3.png │ ├── saastolaskuri.png │ ├── satunnaiskavely.gif │ ├── shanghai.png │ ├── sout.gif │ ├── stackywindows-1.png │ ├── stackywindows-2.png │ ├── taikaneliot-siamese.gif │ ├── tykinkuula.png │ ├── vuokaavio1.png │ ├── vuokaavio2.png │ ├── vuokaavio3.png │ ├── vuokaavio4.png │ ├── vuokaaviojuupaseipas.png │ └── youtube.jpg ├── index.md ├── part-1 │ ├── 1-getting-started.md │ ├── 1_4_1.png │ ├── 1_5_1.png │ ├── 1_5_keyboard.png │ ├── 1_5_keyboard2.png │ ├── 2-information-from-the-user.md │ ├── 3-more-about-variables.md │ ├── 4-arithmetic-operations.md │ ├── 5-conditional-statements.md │ ├── index.md │ ├── margeret-action.jpg │ ├── sisennysvirhe.png │ └── testi.py ├── part-10 │ ├── 1-class-hierarchies.md │ ├── 2-access-modifiers.md │ ├── 3-oo-programming-techniques.md │ ├── 4-application-development.md │ └── index.md ├── part-11 │ ├── 1-list-comprehensions.md │ ├── 11_1_1.png │ ├── 11_1_2.png │ ├── 11_3_1.png │ ├── 11_4_1.png │ ├── 11_4_2.png │ ├── 11_4_3.png │ ├── 2-more-comprehensions.md │ ├── 3-recursion.md │ ├── 4-more-recursion-examples.md │ └── index.md ├── part-12 │ ├── 1-functions-as-arguments.md │ ├── 2-generators.md │ ├── 3-functional-programming.md │ ├── 4-regular-expressions.md │ └── index.md ├── part-13 │ ├── 1-pygame.md │ ├── 13-1-2.png │ ├── 13-1-3.png │ ├── 13-1-4.png │ ├── 13_1_1.png │ ├── 2-animation.md │ ├── 3-events.md │ ├── 4-more-pygame-techniques.md │ ├── index.md │ ├── pygame_animation.gif │ ├── pygame_animation2.gif │ ├── pygame_asteroids.gif │ ├── pygame_bounce.gif │ ├── pygame_circle.gif │ ├── pygame_clock.gif │ ├── pygame_cursor.gif │ ├── pygame_cursor2.gif │ ├── pygame_first.gif │ ├── pygame_four.gif │ ├── pygame_four_directions.gif │ ├── pygame_four_walls.gif │ ├── pygame_hundred.gif │ ├── pygame_invasion.gif │ ├── pygame_linux.png │ ├── pygame_move2.gif │ ├── pygame_move_robot.gif │ ├── pygame_perimeter.gif │ ├── pygame_pic.gif │ ├── pygame_pic2.gif │ ├── pygame_pic3.gif │ ├── pygame_robot_cursor.gif │ ├── pygame_robot_location.gif │ ├── pygame_rotation.gif │ ├── pygame_row.gif │ ├── pygame_shapes.gif │ ├── pygame_text.gif │ ├── pygame_thousand.gif │ ├── pygame_two_players.gif │ ├── pygame_vertical.gif │ └── robot.png ├── part-14 │ ├── 1-game-project.md │ ├── 2-robot-and-boxes.md │ ├── 3-finishing-the-game.md │ ├── 4-your-own-game.md │ ├── box.png │ ├── done.png │ ├── floor.png │ ├── game.png │ ├── index.md │ ├── robot.png │ ├── target.png │ ├── target_robot.png │ ├── tmc_paste_1.png │ ├── tmc_paste_2.png │ ├── tmc_paste_3.png │ └── wall.png ├── part-2 │ ├── 1-programming_terminology.md │ ├── 2-else-elif.md │ ├── 2_2_1.png │ ├── 2_2_2.png │ ├── 3-combining-conditions.md │ ├── 4-simple-loops.md │ └── index.md ├── part-3 │ ├── 1-loops-with-conditions.md │ ├── 2-working-with-strings.md │ ├── 3-more-loops.md │ ├── 3_1_1.png │ ├── 3_1_2.png │ ├── 3_1_3.png │ ├── 3_2_1.png │ ├── 3_2_2.png │ ├── 3_2_3.png │ ├── 3_2_4.png │ ├── 3_3_1.png │ ├── 3_4_1.png │ ├── 4-defining-functions.md │ └── index.md ├── part-4 │ ├── 1-vscode.md │ ├── 2-more-functions.md │ ├── 3-lists.md │ ├── 4-definite-iteration.md │ ├── 4_1_1.png │ ├── 4_1_2.png │ ├── 4_1_3.png │ ├── 4_1_4.png │ ├── 4_1_5.png │ ├── 4_1_6.png │ ├── 4_1_7.png │ ├── 4_1_8.png │ ├── 4_1_9.png │ ├── 4_2_1.png │ ├── 4_2_2.png │ ├── 4_3_1.png │ ├── 4_3_2.png │ ├── 4_4_1.png │ ├── 4_6_1.png │ ├── 4_6_2.png │ ├── 5-print-statement-formatting.md │ ├── 6-strings-and-lists.md │ └── index.md ├── part-5 │ ├── 1-more-lists.md │ ├── 2-references.md │ ├── 3-dictionary.md │ ├── 4-tuple.md │ ├── 5_1_1.png │ ├── 5_1_2.png │ ├── 5_1_3.png │ ├── 5_2_1.png │ ├── 5_2_10.png │ ├── 5_2_2.png │ ├── 5_2_3.png │ ├── 5_2_4.png │ ├── 5_2_5.png │ ├── 5_2_6.png │ ├── 5_2_7.png │ ├── 5_2_8.png │ ├── 5_2_9.png │ ├── 5_4_1.png │ └── index.md ├── part-6 │ ├── 1-reading-files.md │ ├── 2-writing-files.md │ ├── 3-errors.md │ ├── 4-scope-of-variables.md │ ├── 6_1_1.png │ ├── 6_1_2.png │ ├── 6_1_3.png │ ├── 6_1_4.png │ └── index.md ├── part-7 │ ├── 1-modules.md │ ├── 2-randomness.md │ ├── 3-times-and-dates.md │ ├── 4-data-processing.md │ ├── 5-creating-modules.md │ ├── 6-more-features.md │ ├── 7_1_1.png │ ├── 7_1_2.png │ ├── 7_1_3.png │ ├── 7_3_1.png │ ├── 7_3_2.png │ ├── 7_vihje.png │ └── index.md ├── part-8 │ ├── 1-objects-and-methods.md │ ├── 2-classes-and-objects.md │ ├── 3-defining-classes.md │ ├── 4-defining-methods.md │ ├── 5-more-examples-of-classes.md │ ├── 7_3_1.png │ ├── 7_3_2.png │ ├── 7_vihje.png │ ├── 8_1_1.png │ └── index.md ├── part-9 │ ├── 1-objects-and-references.md │ ├── 2-objects-as-attributes.md │ ├── 3-encapsulation.md │ ├── 4-scope-of-methods.md │ ├── 5-class-attributes.md │ ├── 6-more-examples-with-classes.md │ ├── 9_1_1.png │ ├── 9_1_2.png │ └── index.md ├── support-and-assistance.md ├── verkkotentti_lisa.md.old └── vocabulary.md ├── develop-loop.sh ├── docs ├── code-states-visualizer-guide.md ├── how-to-update-template.md ├── images │ ├── code-states-visualizer │ │ ├── markdown.png │ │ ├── network-monitor.png │ │ ├── pythontutor-editor.png │ │ └── pythontutor-frontpage.png │ ├── vocabulary-example-english.png │ └── vocabulary-example-finnish.png └── vocabulary-guide.md ├── gatsby-browser.js ├── gatsby-config.js ├── gatsby-node.js ├── gatsby-ssr.js ├── package-lock.json ├── package.json ├── plugins ├── gatsby-plugin-top-layout │ ├── TopLayout.js │ ├── gatsby-browser.js │ ├── gatsby-ssr.js │ └── package.json ├── gatsby-transformer-moocfi-exercises │ ├── gatsby-node.js │ └── package.json └── gatsby-transformer-vocabulary │ ├── gatsby-node.js │ └── package.json ├── src ├── components │ ├── Banner.js │ ├── Button.js │ ├── Container.js │ ├── ContentArea.js │ ├── CoursePageFooter.js │ ├── EndOfSubSection.js │ ├── Footer.js │ ├── Loading.js │ ├── LoginControls.js │ ├── Logo.js │ ├── MailinglistForm.js │ ├── Notification.js │ ├── PointsBalloon │ │ ├── CourseProgress.js │ │ ├── CustomTooltip.js │ │ ├── PartProgress.js │ │ ├── PointsBalloonBalloon.js │ │ ├── PointsBalloonContent.js │ │ └── index.js │ ├── Sidebar.js │ ├── StyledDivider.js │ ├── TopBar.js │ ├── TreeView │ │ ├── TreeViewItem.js │ │ └── index.js │ └── user │ │ ├── ConfirmEmail.js │ │ ├── CourseOptionsEditor.js │ │ ├── CreateAccountForm.js │ │ └── DropdownMenu.js ├── contexes │ ├── AbGroupContext.js │ ├── LoginStateContext.js │ └── PagesContext.js ├── html.js ├── i18n.js ├── images │ ├── banner.svg │ ├── email-example.png │ ├── logo.png │ ├── moocfi-logo-bw.png │ └── uh-logo.png ├── locales │ ├── common │ │ ├── en.json │ │ └── fi.json │ ├── pointsBalloon │ │ ├── en.json │ │ └── fi.json │ └── user │ │ ├── en.json │ │ └── fi.json ├── pages │ ├── 404.js │ ├── credits.js │ ├── edit-page.js │ ├── missing-info.js │ ├── profile.js │ ├── report-issue.js │ ├── sign-in.js │ └── sign-up.js ├── partials │ ├── AbStudy │ │ ├── OnlyForAbGroup.js │ │ └── index.js │ ├── CodeHighLight.js │ ├── CodeStatesVisualizer.js │ ├── Deadline.js │ ├── ExercisesInAllSections │ │ ├── ExerciseList.js │ │ └── index.js │ ├── ExercisesInThisSection │ │ ├── ExerciseList.js │ │ ├── ExerciseSummary.js │ │ └── index.js │ ├── FloatImageRight.js │ ├── GoogleFormLink.js │ ├── Headers │ │ ├── H1.js │ │ ├── H2.js │ │ ├── H3.js │ │ ├── H4.js │ │ ├── H5.js │ │ └── H6.js │ ├── Hr.js │ ├── InBrowserProgrammingExercise │ │ ├── MoocfiPythonEditorLoader.js │ │ └── index.js │ ├── MoodleExercise.js │ ├── Notice.js │ ├── OnlyForCourseVariant.js │ ├── OnlyForNotLoggedIn.js │ ├── PagesInThisSection.js │ ├── PdfSlideshow │ │ ├── PdfSlideshowLoader.js │ │ └── index.js │ ├── PleaseLogin.js │ ├── Points │ │ ├── OverallPoints.js │ │ ├── PartPoints.js │ │ ├── PointsImpl.js │ │ └── index.js │ ├── ProgrammingExercise │ │ ├── Coins.js │ │ ├── ExerciseDescription.js │ │ ├── ExtraDetails.js │ │ ├── ProgrammingExerciseCard.js │ │ └── index.js │ ├── Quiz.js │ ├── Quiznator.js │ ├── RegistrationLink.js │ ├── RegistrationLink2.js │ ├── SampleData.js │ ├── SampleOutput.js │ ├── SqlTrainerExercise.js │ ├── Summary.js │ ├── Table.js │ ├── TableOfContents.js │ ├── Test.js │ ├── Test2.js │ ├── TextBox.js │ ├── Vocabulary │ │ ├── VocabularyWord.js │ │ ├── Word.js │ │ └── index.js │ ├── WorkshopSchedule.js │ ├── Youtube.js │ └── index.js ├── services │ ├── abstudio.js │ ├── moocfi.js │ ├── progress.js │ ├── quiznator.js │ └── quizzes.js ├── templates │ ├── CourseContentTemplate.js │ ├── CourseInfoTemplate.js │ ├── CoursePartOverviewTemplate.js │ ├── InfoPageTemplate.js │ ├── Layout.js │ ├── VocabularyTemplate.js │ ├── reboot.css │ ├── remark.css │ └── theme.css ├── theme.js └── util │ ├── arrays.js │ ├── constants.js │ ├── dom.js │ ├── pheromones.js │ ├── strings.js │ ├── trackHeight.js │ └── withSimpleErrorBoundary.js ├── static └── pdf.worker.min.js ├── update.rb ├── updates ├── updates.2021 ├── updates.old ├── use-local-code-states-visualizer.sh └── use-local-quizzes.sh /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "babel-preset-gatsby", 5 | { 6 | "targets": { 7 | "browsers": [">0.25%", "not dead"] 8 | } 9 | } 10 | ] 11 | ], 12 | "plugins": [ 13 | "@babel/plugin-proposal-optional-chaining", 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | [*.js] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | jobs: 8 | build-and-deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 🛎️ 12 | uses: actions/checkout@v2.3.1 13 | - name: Setup node version 14 | uses: actions/setup-node@v3 15 | with: 16 | node-version: 16 17 | 18 | - name: Install and Build 19 | run: | 20 | npm ci --legacy-peer-deps 21 | npm run build 22 | - name: Deploy 🚀 23 | uses: JamesIves/github-pages-deploy-action@4.0.0 24 | with: 25 | branch: gh-pages # The branch the action should deploy to. 26 | folder: public # The folder the action should deploy. 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project dependencies 2 | .cache 3 | node_modules 4 | yarn-error.log 5 | 6 | # Build directory 7 | /public 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": false, 4 | "trailingComma": "all" 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.eol": "\n", 3 | "files.trimTrailingWhitespace": true, 4 | "files.insertFinalNewline": true 5 | } 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:11 2 | 3 | COPY . /app 4 | WORKDIR /app 5 | 6 | RUN npm ci 7 | 8 | RUN npm run build && mv /app/public /public 9 | -------------------------------------------------------------------------------- /bin/check-code-style.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED='\033[0;31m' 4 | BLUE='\033[0;34m' 5 | NC='\033[0m' # No Color 6 | 7 | echo "Checking code style..." 8 | npm run prettier-check 9 | 10 | rc=$?; 11 | if [[ $rc != 0 ]] 12 | then 13 | echo "" 14 | echo -e "${RED}Code style checking was not successful.${NC}" 15 | echo -e "Run '${BLUE}npm run format${NC}' and add the changes to git to fix the problem." 16 | fi 17 | exit $rc 18 | -------------------------------------------------------------------------------- /bin/update-material-template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Update material template for the directory that was provided as a parameter. 4 | 5 | if [ $# -lt 1 ]; then 6 | echo 1>&2 "$0: not enough arguments" 7 | exit 2 8 | elif [ $# -gt 1 ]; then 9 | echo 1>&2 "$0: too many arguments" 10 | exit 2 11 | fi 12 | 13 | updated_repository=${1%/} 14 | 15 | BASEDIR=$(dirname "$0") 16 | BASEDIR_WITHOUT_BIN=${BASEDIR%bin} 17 | 18 | if [ -z "$BASEDIR_WITHOUT_BIN" ]; then 19 | BASEDIR_WITHOUT_BIN="." 20 | fi 21 | 22 | rm -r $updated_repository/gatsby-* 23 | rm -r $updated_repository/package* 24 | rm -r $updated_repository/plugins 25 | rm -r $updated_repository/src 26 | rm -r $updated_repository/docs 27 | rm -r $updated_repository/bin 28 | 29 | cp -r $BASEDIR_WITHOUT_BIN/gatsby-* $updated_repository 30 | cp -r $BASEDIR_WITHOUT_BIN/package* $updated_repository 31 | cp -r $BASEDIR_WITHOUT_BIN/plugins $updated_repository/plugins 32 | cp -r $BASEDIR_WITHOUT_BIN/src $updated_repository/src 33 | cp -r $BASEDIR_WITHOUT_BIN/docs $updated_repository/docs 34 | cp -r $BASEDIR_WITHOUT_BIN/bin $updated_repository/bin 35 | -------------------------------------------------------------------------------- /course-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "@context": "http://schema.org", 3 | "@type": "Course", 4 | "name": "Programming MOOC 2022", 5 | "description": "", 6 | "provider": { 7 | "@type": "Organization", 8 | "name": "MOOC.fi", 9 | "sameAs": "https://mooc.fi" 10 | }, 11 | "publisher": { 12 | "@type": "Organization", 13 | "name": "University of Helsinki", 14 | "sameAs": "https://www.helsinki.fi/" 15 | }, 16 | "hasCourseInstance": [ 17 | { 18 | "@type": "CourseInstance", 19 | "name": "Programming MOOC 2022", 20 | "courseMode": ["MOOC", "online"], 21 | "location": { 22 | "@type": "Place", 23 | "name": "Exactum, Kumpulan kampus", 24 | "address": "Gustaf Hällströmin katu 2b 00560 Helsinki, Finland" 25 | }, 26 | "startDate": "2022-01-10", 27 | "audience": { 28 | "@type": "EducationalAudience", 29 | "educationalRole": "student", 30 | "audienceType": "everyone" 31 | }, 32 | "inLanguage": { 33 | "@type": "Language", 34 | "name": "English", 35 | "alternateName": "en" 36 | }, 37 | "isAccessibleForFree": true 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /course-settings.js: -------------------------------------------------------------------------------- 1 | const courseSettings = { 2 | language: "en", 3 | name: "Python Programming MOOC 2022", 4 | siteUrl: "https://programming-22.mooc.fi", 5 | githubUrl: "https://github.com/rage/programming-22", 6 | subtitle: "Python Programming MOOC", 7 | slug: "programming-22", 8 | organizationName: "MOOC", 9 | tmcCourse: "programming-22", 10 | quizzesId: "cc7ec951-c28b-4f16-86ff-0f9dc9196db4", 11 | tmcOrganization: "mooc", 12 | bannerPath: "banner.svg", 13 | showExerciseDescriptionWhenNotLoggedIn: true, 14 | courseVariants: [ 15 | { 16 | tmcOrganization: "laurea", 17 | tmcCourse: "python-laurea-english-2023", 18 | // quizzesId: "5c89b9b6-b8a6-4079-8c4f-a4bbc80b66a4", 19 | }, 20 | ], 21 | } 22 | 23 | module.exports = courseSettings 24 | -------------------------------------------------------------------------------- /data/all-exercises.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/all-exercises' 3 | title: 'All exercises' 4 | hidden: false 5 | hide_in_sidebar: false 6 | sidebar_priority: 5000 7 | course_info_page: true 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-abstraktit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-abstraktit.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-getterit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-getterit.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-getnimi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-getnimi.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene-ja-palautaika.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene-ja-palautaika.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta-ja-vanhene.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori-ja-tulosta.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi-ja-konstruktori.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ika-ja-nimi.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo-ja-syntymapaiva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo-ja-syntymapaiva.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-henkilo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-henkilo.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-henkilo-kaksisuuntainen-monesta-moneen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-henkilo-kaksisuuntainen-monesta-moneen.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-henkilo-kaksisuuntainen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-henkilo-kaksisuuntainen.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittaja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittaja.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat-ja-metodit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat-ja-metodit.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja-ja-kirjoittajat.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-nimi-ja-kustantaja.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja-toteuttaa-luettavan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja-toteuttaa-luettavan.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-kirja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-kirja.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-maatilasimulaattori.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-maatilasimulaattori.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-moottori-perii-osan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-moottori-perii-osan.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-muistava-tuotevarasto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-muistava-tuotevarasto.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-paita.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-paita.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-rajapinta-luettava.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-rajapinta-luettava.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-soittolista.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-soittolista.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-teht-huone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-teht-huone.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-teht-koira.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-teht-koira.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-teht-luokka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-teht-luokka.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-teht-maksukortti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-teht-maksukortti.png -------------------------------------------------------------------------------- /data/img/diagrams/luokkakaavio-teht-ruokalista.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/diagrams/luokkakaavio-teht-ruokalista.png -------------------------------------------------------------------------------- /data/img/drawings/arraylist-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/arraylist-add.png -------------------------------------------------------------------------------- /data/img/drawings/arraylist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/arraylist.png -------------------------------------------------------------------------------- /data/img/drawings/boolean-muuttuja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/boolean-muuttuja.png -------------------------------------------------------------------------------- /data/img/drawings/eka-1 (copy).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-1 (copy).png -------------------------------------------------------------------------------- /data/img/drawings/eka-1.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-1.ora -------------------------------------------------------------------------------- /data/img/drawings/eka-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-1.png -------------------------------------------------------------------------------- /data/img/drawings/eka-2 (copy).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-2 (copy).png -------------------------------------------------------------------------------- /data/img/drawings/eka-2.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-2.ora -------------------------------------------------------------------------------- /data/img/drawings/eka-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-2.png -------------------------------------------------------------------------------- /data/img/drawings/eka-3 (copy).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-3 (copy).png -------------------------------------------------------------------------------- /data/img/drawings/eka-3.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-3.ora -------------------------------------------------------------------------------- /data/img/drawings/eka-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-3.png -------------------------------------------------------------------------------- /data/img/drawings/eka-4 (copy).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-4 (copy).png -------------------------------------------------------------------------------- /data/img/drawings/eka-4.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-4.ora -------------------------------------------------------------------------------- /data/img/drawings/eka-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-4.png -------------------------------------------------------------------------------- /data/img/drawings/eka-5 (copy).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-5 (copy).png -------------------------------------------------------------------------------- /data/img/drawings/eka-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/eka-5.png -------------------------------------------------------------------------------- /data/img/drawings/hashmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/hashmap.png -------------------------------------------------------------------------------- /data/img/drawings/henkilot-ja-juhana.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/henkilot-ja-juhana.ora -------------------------------------------------------------------------------- /data/img/drawings/henkilot-ja-juhana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/henkilot-ja-juhana.png -------------------------------------------------------------------------------- /data/img/drawings/muhammad-ja-pascal.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muhammad-ja-pascal.ora -------------------------------------------------------------------------------- /data/img/drawings/muhammad-ja-pascal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muhammad-ja-pascal.png -------------------------------------------------------------------------------- /data/img/drawings/muuttujan-arvon-vaihto-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muuttujan-arvon-vaihto-0.png -------------------------------------------------------------------------------- /data/img/drawings/muuttujan-arvon-vaihto-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muuttujan-arvon-vaihto-1.png -------------------------------------------------------------------------------- /data/img/drawings/muuttujan-arvon-vaihto-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muuttujan-arvon-vaihto-2.png -------------------------------------------------------------------------------- /data/img/drawings/muuttujan-arvon-vaihto-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muuttujan-arvon-vaihto-3.png -------------------------------------------------------------------------------- /data/img/drawings/muuttujan-arvon-vaihto-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/muuttujan-arvon-vaihto-4.png -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-2.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-2.ora -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-2.png -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-3.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-3.ora -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-3.png -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-null.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-null.ora -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball-null.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball-null.png -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball.ora -------------------------------------------------------------------------------- /data/img/drawings/olio-joan-ja-ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan-ja-ball.png -------------------------------------------------------------------------------- /data/img/drawings/olio-joan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/olio-joan.png -------------------------------------------------------------------------------- /data/img/drawings/stream-pre-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/stream-pre-edit.png -------------------------------------------------------------------------------- /data/img/drawings/stream.ora: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/stream.ora -------------------------------------------------------------------------------- /data/img/drawings/stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/stream.png -------------------------------------------------------------------------------- /data/img/drawings/while-true-break.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/drawings/while-true-break.png -------------------------------------------------------------------------------- /data/img/ennustaja-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/ennustaja-1.png -------------------------------------------------------------------------------- /data/img/ennustaja-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/ennustaja-2.png -------------------------------------------------------------------------------- /data/img/ennustaja-3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/ennustaja-3.gif -------------------------------------------------------------------------------- /data/img/et_phone_home.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/et_phone_home.wav -------------------------------------------------------------------------------- /data/img/exercises/01-10-jakolaskin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/01-10-jakolaskin.png -------------------------------------------------------------------------------- /data/img/exercises/01-22-maara.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/01-22-maara.png -------------------------------------------------------------------------------- /data/img/exercises/01-30-jahtaus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/01-30-jahtaus.png -------------------------------------------------------------------------------- /data/img/exercises/02-12-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/02-12-01.png -------------------------------------------------------------------------------- /data/img/exercises/02-12-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/02-12-02.png -------------------------------------------------------------------------------- /data/img/exercises/03-12-rivit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/03-12-rivit.png -------------------------------------------------------------------------------- /data/img/exercises/06-14-piirturi-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-14-piirturi-ok.png -------------------------------------------------------------------------------- /data/img/exercises/06-15-gameoflife.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-15-gameoflife.png -------------------------------------------------------------------------------- /data/img/exercises/06-19-matkavalokuvat-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-19-matkavalokuvat-1.png -------------------------------------------------------------------------------- /data/img/exercises/06-19-matkavalokuvat-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-19-matkavalokuvat-2.png -------------------------------------------------------------------------------- /data/img/exercises/06-19-matkavalokuvat-mediaani.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-19-matkavalokuvat-mediaani.png -------------------------------------------------------------------------------- /data/img/exercises/06-19-matkavalokuvat-tummin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-19-matkavalokuvat-tummin.png -------------------------------------------------------------------------------- /data/img/exercises/06-19-matkavalokuvat-vaalein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/06-19-matkavalokuvat-vaalein.png -------------------------------------------------------------------------------- /data/img/exercises/10-08-asteroids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/10-08-asteroids.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-asiakas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-asiakas.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-iso-abstrakti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-iso-abstrakti.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-kirja-ja-lentokone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-kirja-ja-lentokone.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-naytos-ja-lippu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-naytos-ja-lippu.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-opiskelija-ja-korkeakoulu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-opiskelija-ja-korkeakoulu.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-pelaaja-ja-tekoaly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-pelaaja-ja-tekoaly.png -------------------------------------------------------------------------------- /data/img/exercises/luokkakaavio-tallennettava-henkilo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/luokkakaavio-tallennettava-henkilo.png -------------------------------------------------------------------------------- /data/img/exercises/schelling-alku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/schelling-alku.png -------------------------------------------------------------------------------- /data/img/exercises/schelling-loppu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/exercises/schelling-loppu.png -------------------------------------------------------------------------------- /data/img/front-desk-bells-daniel_simon.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/front-desk-bells-daniel_simon.wav -------------------------------------------------------------------------------- /data/img/hiekkaranta-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/hiekkaranta-1.png -------------------------------------------------------------------------------- /data/img/kollaasi-monalisa-kulma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/kollaasi-monalisa-kulma.png -------------------------------------------------------------------------------- /data/img/kollaasi-monalisa-neg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/kollaasi-monalisa-neg.png -------------------------------------------------------------------------------- /data/img/kollaasi-monalisa-ruudut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/kollaasi-monalisa-ruudut.png -------------------------------------------------------------------------------- /data/img/kollaasi-monalisa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/kollaasi-monalisa.png -------------------------------------------------------------------------------- /data/img/lohkoesimerkki-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/lohkoesimerkki-1.png -------------------------------------------------------------------------------- /data/img/lohkoesimerkki-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/lohkoesimerkki-2.png -------------------------------------------------------------------------------- /data/img/lohkoesimerkki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/lohkoesimerkki.png -------------------------------------------------------------------------------- /data/img/lyrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/lyrics.png -------------------------------------------------------------------------------- /data/img/macos-guide/add_tmcbeans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/add_tmcbeans.png -------------------------------------------------------------------------------- /data/img/macos-guide/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/done.png -------------------------------------------------------------------------------- /data/img/macos-guide/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/navigation.png -------------------------------------------------------------------------------- /data/img/macos-guide/open-lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/open-lock.png -------------------------------------------------------------------------------- /data/img/macos-guide/search_system_preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/search_system_preferences.png -------------------------------------------------------------------------------- /data/img/macos-guide/system_preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/system_preferences.png -------------------------------------------------------------------------------- /data/img/macos-guide/tmcbeans_added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/macos-guide/tmcbeans_added.png -------------------------------------------------------------------------------- /data/img/material/alus-ampuu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/alus-ampuu.gif -------------------------------------------------------------------------------- /data/img/material/alus-kiihtyy-fiksummin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/alus-kiihtyy-fiksummin.gif -------------------------------------------------------------------------------- /data/img/material/ammus-poistaa-asteroidin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/ammus-poistaa-asteroidin.gif -------------------------------------------------------------------------------- /data/img/material/ammus-poistuu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/ammus-poistuu.gif -------------------------------------------------------------------------------- /data/img/material/asteroidi-huti.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroidi-huti.gif -------------------------------------------------------------------------------- /data/img/material/asteroidit-liikkuu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroidit-liikkuu.gif -------------------------------------------------------------------------------- /data/img/material/asteroids-ammuskelua.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-ammuskelua.gif -------------------------------------------------------------------------------- /data/img/material/asteroids-monta-asteroidia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-monta-asteroidia.png -------------------------------------------------------------------------------- /data/img/material/asteroids-pisteet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-pisteet.png -------------------------------------------------------------------------------- /data/img/material/asteroids-pysyy-ruudussa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-pysyy-ruudussa.gif -------------------------------------------------------------------------------- /data/img/material/asteroids-ready.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-ready.gif -------------------------------------------------------------------------------- /data/img/material/asteroids-satunnaiset-monikulmiot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-satunnaiset-monikulmiot.png -------------------------------------------------------------------------------- /data/img/material/asteroids-tormays.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/asteroids-tormays.gif -------------------------------------------------------------------------------- /data/img/material/autocomplete-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/autocomplete-2.png -------------------------------------------------------------------------------- /data/img/material/autocomplete-with-comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/autocomplete-with-comment.png -------------------------------------------------------------------------------- /data/img/material/autocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/autocomplete.png -------------------------------------------------------------------------------- /data/img/material/gui-animaatio.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-animaatio.gif -------------------------------------------------------------------------------- /data/img/material/gui-borderpane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-borderpane.png -------------------------------------------------------------------------------- /data/img/material/gui-gridpane-3x3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-gridpane-3x3.png -------------------------------------------------------------------------------- /data/img/material/gui-hbox-spacing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-hbox-spacing.png -------------------------------------------------------------------------------- /data/img/material/gui-hbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-hbox.png -------------------------------------------------------------------------------- /data/img/material/gui-helloworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-helloworld.png -------------------------------------------------------------------------------- /data/img/material/gui-hymio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-hymio.png -------------------------------------------------------------------------------- /data/img/material/gui-ilmoitin-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-ilmoitin-1.png -------------------------------------------------------------------------------- /data/img/material/gui-ilmoitin-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-ilmoitin-2.png -------------------------------------------------------------------------------- /data/img/material/gui-kopioija-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-kopioija-2.png -------------------------------------------------------------------------------- /data/img/material/gui-kopioija.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-kopioija.png -------------------------------------------------------------------------------- /data/img/material/gui-lisaa-henkilo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-lisaa-henkilo.png -------------------------------------------------------------------------------- /data/img/material/gui-nakyman-vaihto.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-nakyman-vaihto.gif -------------------------------------------------------------------------------- /data/img/material/gui-nappi-ja-teksti-rivitetty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-nappi-ja-teksti-rivitetty.png -------------------------------------------------------------------------------- /data/img/material/gui-nappi-ja-teksti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-nappi-ja-teksti.png -------------------------------------------------------------------------------- /data/img/material/gui-nappi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-nappi.png -------------------------------------------------------------------------------- /data/img/material/gui-paint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-paint.png -------------------------------------------------------------------------------- /data/img/material/gui-planeetat-painava-aurinko.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-planeetat-painava-aurinko.gif -------------------------------------------------------------------------------- /data/img/material/gui-planeetat-painavampi-aurinko.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-planeetat-painavampi-aurinko.gif -------------------------------------------------------------------------------- /data/img/material/gui-planeetat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-planeetat.gif -------------------------------------------------------------------------------- /data/img/material/gui-ristinolla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-ristinolla.png -------------------------------------------------------------------------------- /data/img/material/gui-salasana.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-salasana.gif -------------------------------------------------------------------------------- /data/img/material/gui-sanaharjoittelu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-sanaharjoittelu.gif -------------------------------------------------------------------------------- /data/img/material/gui-simulaatio-metalli-ja-hiekka.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-simulaatio-metalli-ja-hiekka.gif -------------------------------------------------------------------------------- /data/img/material/gui-simulaatio-metalli.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-simulaatio-metalli.gif -------------------------------------------------------------------------------- /data/img/material/gui-simulaatio.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-simulaatio.gif -------------------------------------------------------------------------------- /data/img/material/gui-tekstielementti.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-tekstielementti.png -------------------------------------------------------------------------------- /data/img/material/gui-tervehtija.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-tervehtija.gif -------------------------------------------------------------------------------- /data/img/material/gui-tilastoja.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-tilastoja.gif -------------------------------------------------------------------------------- /data/img/material/gui-useampi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-useampi.png -------------------------------------------------------------------------------- /data/img/material/gui-vbox-spacing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/gui-vbox-spacing.png -------------------------------------------------------------------------------- /data/img/material/humming-kaannetty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/humming-kaannetty.png -------------------------------------------------------------------------------- /data/img/material/hurraa-nappi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/hurraa-nappi.png -------------------------------------------------------------------------------- /data/img/material/image-ja-imageview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/image-ja-imageview.png -------------------------------------------------------------------------------- /data/img/material/junit-laskimentestailua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/junit-laskimentestailua.png -------------------------------------------------------------------------------- /data/img/material/junit-test-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/junit-test-results.png -------------------------------------------------------------------------------- /data/img/material/junit-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/junit-test.png -------------------------------------------------------------------------------- /data/img/material/kaavio-kannatus-rkp-ja-vihr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kaavio-kannatus-rkp-ja-vihr.png -------------------------------------------------------------------------------- /data/img/material/kaavio-pohjoismaiden-asukasluvut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kaavio-pohjoismaiden-asukasluvut.png -------------------------------------------------------------------------------- /data/img/material/kaavio-shanghai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kaavio-shanghai.png -------------------------------------------------------------------------------- /data/img/material/kaavio-suhteellinen-kannatus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kaavio-suhteellinen-kannatus.png -------------------------------------------------------------------------------- /data/img/material/kaavio-suurten-lukujen-laki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kaavio-suurten-lukujen-laki.png -------------------------------------------------------------------------------- /data/img/material/kirjoitusharjoittelu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kirjoitusharjoittelu.png -------------------------------------------------------------------------------- /data/img/material/kuva-mysteeri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kuva-mysteeri.png -------------------------------------------------------------------------------- /data/img/material/kuvaaja-liittyman-nopeus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/kuvaaja-liittyman-nopeus.png -------------------------------------------------------------------------------- /data/img/material/luokka-luotuna.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/luokka-luotuna.png -------------------------------------------------------------------------------- /data/img/material/monalisa-kollaasi-alku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/monalisa-kollaasi-alku.png -------------------------------------------------------------------------------- /data/img/material/monalisa-kollaasi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/monalisa-kollaasi.png -------------------------------------------------------------------------------- /data/img/material/monalisa-negatiivi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/monalisa-negatiivi.png -------------------------------------------------------------------------------- /data/img/material/netbeans-output-venla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/netbeans-output-venla.png -------------------------------------------------------------------------------- /data/img/material/non-compiling-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/non-compiling-2.png -------------------------------------------------------------------------------- /data/img/material/non-compiling-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/non-compiling-3.png -------------------------------------------------------------------------------- /data/img/material/non-compiling-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/non-compiling-4.png -------------------------------------------------------------------------------- /data/img/material/non-compiling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/non-compiling.png -------------------------------------------------------------------------------- /data/img/material/pane-alus-kiihtyy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-alus-kiihtyy.gif -------------------------------------------------------------------------------- /data/img/material/pane-alus-liikkuu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-alus-liikkuu.gif -------------------------------------------------------------------------------- /data/img/material/pane-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-circle.png -------------------------------------------------------------------------------- /data/img/material/pane-polygon-move-rotate-better.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-polygon-move-rotate-better.gif -------------------------------------------------------------------------------- /data/img/material/pane-polygon-move-rotate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-polygon-move-rotate.gif -------------------------------------------------------------------------------- /data/img/material/pane-polygon-move.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-polygon-move.gif -------------------------------------------------------------------------------- /data/img/material/pane-suunnikas-move-rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-suunnikas-move-rotate.png -------------------------------------------------------------------------------- /data/img/material/pane-suunnikas-siirretty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-suunnikas-siirretty.png -------------------------------------------------------------------------------- /data/img/material/pane-suunnikas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pane-suunnikas.png -------------------------------------------------------------------------------- /data/img/material/perinta.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/perinta.gif -------------------------------------------------------------------------------- /data/img/material/pisteet-kasvavat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/pisteet-kasvavat.gif -------------------------------------------------------------------------------- /data/img/material/project-clean-and-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/project-clean-and-build.png -------------------------------------------------------------------------------- /data/img/material/project-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/project-properties.png -------------------------------------------------------------------------------- /data/img/material/puolitushaku-ide-kommentit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/puolitushaku-ide-kommentit.png -------------------------------------------------------------------------------- /data/img/material/string-api-perinta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/string-api-perinta.png -------------------------------------------------------------------------------- /data/img/material/tehtavienhallinta-luokat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/tehtavienhallinta-luokat.png -------------------------------------------------------------------------------- /data/img/material/tehtavienhallinta-testiluokka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/tehtavienhallinta-testiluokka.png -------------------------------------------------------------------------------- /data/img/material/vapaarobotti-kahdeksantoistakulmio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/vapaarobotti-kahdeksantoistakulmio.png -------------------------------------------------------------------------------- /data/img/material/vapaarobotti-kolmio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/vapaarobotti-kolmio.png -------------------------------------------------------------------------------- /data/img/material/vapaarobotti-kuusikulmio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/vapaarobotti-kuusikulmio.png -------------------------------------------------------------------------------- /data/img/material/vapaarobotti-nelio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/vapaarobotti-nelio.png -------------------------------------------------------------------------------- /data/img/material/visualisointi-pyorat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/material/visualisointi-pyorat.png -------------------------------------------------------------------------------- /data/img/matopeli.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/matopeli.png -------------------------------------------------------------------------------- /data/img/maven-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/maven-1.png -------------------------------------------------------------------------------- /data/img/metodivuokaavio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/metodivuokaavio.png -------------------------------------------------------------------------------- /data/img/metodivuokaavio2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/metodivuokaavio2.png -------------------------------------------------------------------------------- /data/img/pong-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/pong-screenshot.png -------------------------------------------------------------------------------- /data/img/puuta/ikkuna-ja-viiva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/puuta/ikkuna-ja-viiva.png -------------------------------------------------------------------------------- /data/img/puuta/komennot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/puuta/komennot.png -------------------------------------------------------------------------------- /data/img/puuta/puisevaa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/puuta/puisevaa.png -------------------------------------------------------------------------------- /data/img/puuta/toisto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/puuta/toisto.png -------------------------------------------------------------------------------- /data/img/rintamamiestalo-rakennuspiirrustus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/rintamamiestalo-rakennuspiirrustus.jpg -------------------------------------------------------------------------------- /data/img/rintamamiestalo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/rintamamiestalo.jpg -------------------------------------------------------------------------------- /data/img/saastolaskuri-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/saastolaskuri-1.png -------------------------------------------------------------------------------- /data/img/saastolaskuri-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/saastolaskuri-2.png -------------------------------------------------------------------------------- /data/img/saastolaskuri-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/saastolaskuri-3.png -------------------------------------------------------------------------------- /data/img/saastolaskuri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/saastolaskuri.png -------------------------------------------------------------------------------- /data/img/satunnaiskavely.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/satunnaiskavely.gif -------------------------------------------------------------------------------- /data/img/shanghai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/shanghai.png -------------------------------------------------------------------------------- /data/img/sout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/sout.gif -------------------------------------------------------------------------------- /data/img/stackywindows-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/stackywindows-1.png -------------------------------------------------------------------------------- /data/img/stackywindows-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/stackywindows-2.png -------------------------------------------------------------------------------- /data/img/taikaneliot-siamese.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/taikaneliot-siamese.gif -------------------------------------------------------------------------------- /data/img/tykinkuula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/tykinkuula.png -------------------------------------------------------------------------------- /data/img/vuokaavio1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/vuokaavio1.png -------------------------------------------------------------------------------- /data/img/vuokaavio2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/vuokaavio2.png -------------------------------------------------------------------------------- /data/img/vuokaavio3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/vuokaavio3.png -------------------------------------------------------------------------------- /data/img/vuokaavio4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/vuokaavio4.png -------------------------------------------------------------------------------- /data/img/vuokaaviojuupaseipas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/vuokaaviojuupaseipas.png -------------------------------------------------------------------------------- /data/img/youtube.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/img/youtube.jpg -------------------------------------------------------------------------------- /data/part-1/1_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/1_4_1.png -------------------------------------------------------------------------------- /data/part-1/1_5_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/1_5_1.png -------------------------------------------------------------------------------- /data/part-1/1_5_keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/1_5_keyboard.png -------------------------------------------------------------------------------- /data/part-1/1_5_keyboard2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/1_5_keyboard2.png -------------------------------------------------------------------------------- /data/part-1/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-1' 3 | title: 'Part 1' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-1/margeret-action.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/margeret-action.jpg -------------------------------------------------------------------------------- /data/part-1/sisennysvirhe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-1/sisennysvirhe.png -------------------------------------------------------------------------------- /data/part-1/testi.py: -------------------------------------------------------------------------------- 1 | lämpö = 10 2 | lämpö2 = 20 3 | print(lämpö + lämpö2) -------------------------------------------------------------------------------- /data/part-10/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-10' 3 | title: 'Part 10' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-11/11_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_1_1.png -------------------------------------------------------------------------------- /data/part-11/11_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_1_2.png -------------------------------------------------------------------------------- /data/part-11/11_3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_3_1.png -------------------------------------------------------------------------------- /data/part-11/11_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_4_1.png -------------------------------------------------------------------------------- /data/part-11/11_4_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_4_2.png -------------------------------------------------------------------------------- /data/part-11/11_4_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-11/11_4_3.png -------------------------------------------------------------------------------- /data/part-11/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-11' 3 | title: 'Part 11' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-12/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-12' 3 | title: 'Part 12' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-13/13-1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/13-1-2.png -------------------------------------------------------------------------------- /data/part-13/13-1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/13-1-3.png -------------------------------------------------------------------------------- /data/part-13/13-1-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/13-1-4.png -------------------------------------------------------------------------------- /data/part-13/13_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/13_1_1.png -------------------------------------------------------------------------------- /data/part-13/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-13' 3 | title: 'Part 13' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-13/pygame_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_animation.gif -------------------------------------------------------------------------------- /data/part-13/pygame_animation2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_animation2.gif -------------------------------------------------------------------------------- /data/part-13/pygame_asteroids.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_asteroids.gif -------------------------------------------------------------------------------- /data/part-13/pygame_bounce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_bounce.gif -------------------------------------------------------------------------------- /data/part-13/pygame_circle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_circle.gif -------------------------------------------------------------------------------- /data/part-13/pygame_clock.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_clock.gif -------------------------------------------------------------------------------- /data/part-13/pygame_cursor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_cursor.gif -------------------------------------------------------------------------------- /data/part-13/pygame_cursor2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_cursor2.gif -------------------------------------------------------------------------------- /data/part-13/pygame_first.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_first.gif -------------------------------------------------------------------------------- /data/part-13/pygame_four.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_four.gif -------------------------------------------------------------------------------- /data/part-13/pygame_four_directions.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_four_directions.gif -------------------------------------------------------------------------------- /data/part-13/pygame_four_walls.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_four_walls.gif -------------------------------------------------------------------------------- /data/part-13/pygame_hundred.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_hundred.gif -------------------------------------------------------------------------------- /data/part-13/pygame_invasion.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_invasion.gif -------------------------------------------------------------------------------- /data/part-13/pygame_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_linux.png -------------------------------------------------------------------------------- /data/part-13/pygame_move2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_move2.gif -------------------------------------------------------------------------------- /data/part-13/pygame_move_robot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_move_robot.gif -------------------------------------------------------------------------------- /data/part-13/pygame_perimeter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_perimeter.gif -------------------------------------------------------------------------------- /data/part-13/pygame_pic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_pic.gif -------------------------------------------------------------------------------- /data/part-13/pygame_pic2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_pic2.gif -------------------------------------------------------------------------------- /data/part-13/pygame_pic3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_pic3.gif -------------------------------------------------------------------------------- /data/part-13/pygame_robot_cursor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_robot_cursor.gif -------------------------------------------------------------------------------- /data/part-13/pygame_robot_location.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_robot_location.gif -------------------------------------------------------------------------------- /data/part-13/pygame_rotation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_rotation.gif -------------------------------------------------------------------------------- /data/part-13/pygame_row.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_row.gif -------------------------------------------------------------------------------- /data/part-13/pygame_shapes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_shapes.gif -------------------------------------------------------------------------------- /data/part-13/pygame_text.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_text.gif -------------------------------------------------------------------------------- /data/part-13/pygame_thousand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_thousand.gif -------------------------------------------------------------------------------- /data/part-13/pygame_two_players.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_two_players.gif -------------------------------------------------------------------------------- /data/part-13/pygame_vertical.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/pygame_vertical.gif -------------------------------------------------------------------------------- /data/part-13/robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-13/robot.png -------------------------------------------------------------------------------- /data/part-14/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/box.png -------------------------------------------------------------------------------- /data/part-14/done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/done.png -------------------------------------------------------------------------------- /data/part-14/floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/floor.png -------------------------------------------------------------------------------- /data/part-14/game.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/game.png -------------------------------------------------------------------------------- /data/part-14/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-14' 3 | title: 'Part 14' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-14/robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/robot.png -------------------------------------------------------------------------------- /data/part-14/target.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/target.png -------------------------------------------------------------------------------- /data/part-14/target_robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/target_robot.png -------------------------------------------------------------------------------- /data/part-14/tmc_paste_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/tmc_paste_1.png -------------------------------------------------------------------------------- /data/part-14/tmc_paste_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/tmc_paste_2.png -------------------------------------------------------------------------------- /data/part-14/tmc_paste_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/tmc_paste_3.png -------------------------------------------------------------------------------- /data/part-14/wall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-14/wall.png -------------------------------------------------------------------------------- /data/part-2/2_2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-2/2_2_1.png -------------------------------------------------------------------------------- /data/part-2/2_2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-2/2_2_2.png -------------------------------------------------------------------------------- /data/part-2/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-2' 3 | title: 'Part 2' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-3/3_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_1_1.png -------------------------------------------------------------------------------- /data/part-3/3_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_1_2.png -------------------------------------------------------------------------------- /data/part-3/3_1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_1_3.png -------------------------------------------------------------------------------- /data/part-3/3_2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_2_1.png -------------------------------------------------------------------------------- /data/part-3/3_2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_2_2.png -------------------------------------------------------------------------------- /data/part-3/3_2_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_2_3.png -------------------------------------------------------------------------------- /data/part-3/3_2_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_2_4.png -------------------------------------------------------------------------------- /data/part-3/3_3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_3_1.png -------------------------------------------------------------------------------- /data/part-3/3_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-3/3_4_1.png -------------------------------------------------------------------------------- /data/part-3/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-3' 3 | title: 'Part 3' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-4/4_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_1.png -------------------------------------------------------------------------------- /data/part-4/4_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_2.png -------------------------------------------------------------------------------- /data/part-4/4_1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_3.png -------------------------------------------------------------------------------- /data/part-4/4_1_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_4.png -------------------------------------------------------------------------------- /data/part-4/4_1_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_5.png -------------------------------------------------------------------------------- /data/part-4/4_1_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_6.png -------------------------------------------------------------------------------- /data/part-4/4_1_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_7.png -------------------------------------------------------------------------------- /data/part-4/4_1_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_8.png -------------------------------------------------------------------------------- /data/part-4/4_1_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_1_9.png -------------------------------------------------------------------------------- /data/part-4/4_2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_2_1.png -------------------------------------------------------------------------------- /data/part-4/4_2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_2_2.png -------------------------------------------------------------------------------- /data/part-4/4_3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_3_1.png -------------------------------------------------------------------------------- /data/part-4/4_3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_3_2.png -------------------------------------------------------------------------------- /data/part-4/4_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_4_1.png -------------------------------------------------------------------------------- /data/part-4/4_6_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_6_1.png -------------------------------------------------------------------------------- /data/part-4/4_6_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-4/4_6_2.png -------------------------------------------------------------------------------- /data/part-4/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-4' 3 | title: 'Part 4' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-5/5_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_1_1.png -------------------------------------------------------------------------------- /data/part-5/5_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_1_2.png -------------------------------------------------------------------------------- /data/part-5/5_1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_1_3.png -------------------------------------------------------------------------------- /data/part-5/5_2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_1.png -------------------------------------------------------------------------------- /data/part-5/5_2_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_10.png -------------------------------------------------------------------------------- /data/part-5/5_2_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_2.png -------------------------------------------------------------------------------- /data/part-5/5_2_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_3.png -------------------------------------------------------------------------------- /data/part-5/5_2_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_4.png -------------------------------------------------------------------------------- /data/part-5/5_2_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_5.png -------------------------------------------------------------------------------- /data/part-5/5_2_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_6.png -------------------------------------------------------------------------------- /data/part-5/5_2_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_7.png -------------------------------------------------------------------------------- /data/part-5/5_2_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_8.png -------------------------------------------------------------------------------- /data/part-5/5_2_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_2_9.png -------------------------------------------------------------------------------- /data/part-5/5_4_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-5/5_4_1.png -------------------------------------------------------------------------------- /data/part-5/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-5' 3 | title: 'Part 5' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-6/6_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-6/6_1_1.png -------------------------------------------------------------------------------- /data/part-6/6_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-6/6_1_2.png -------------------------------------------------------------------------------- /data/part-6/6_1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-6/6_1_3.png -------------------------------------------------------------------------------- /data/part-6/6_1_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-6/6_1_4.png -------------------------------------------------------------------------------- /data/part-6/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-6' 3 | title: 'Part 6' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-7/7_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_1_1.png -------------------------------------------------------------------------------- /data/part-7/7_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_1_2.png -------------------------------------------------------------------------------- /data/part-7/7_1_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_1_3.png -------------------------------------------------------------------------------- /data/part-7/7_3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_3_1.png -------------------------------------------------------------------------------- /data/part-7/7_3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_3_2.png -------------------------------------------------------------------------------- /data/part-7/7_vihje.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-7/7_vihje.png -------------------------------------------------------------------------------- /data/part-7/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-7' 3 | title: 'Part 7' 4 | overview: true 5 | hidden: false 6 | separator_after: "Advanced Course in Programming" 7 | --- 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /data/part-8/7_3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-8/7_3_1.png -------------------------------------------------------------------------------- /data/part-8/7_3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-8/7_3_2.png -------------------------------------------------------------------------------- /data/part-8/7_vihje.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-8/7_vihje.png -------------------------------------------------------------------------------- /data/part-8/8_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-8/8_1_1.png -------------------------------------------------------------------------------- /data/part-8/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-8' 3 | title: 'Part 8' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/part-9/9_1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-9/9_1_1.png -------------------------------------------------------------------------------- /data/part-9/9_1_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/data/part-9/9_1_2.png -------------------------------------------------------------------------------- /data/part-9/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/part-9' 3 | title: 'Part 9' 4 | overview: true 5 | hidden: false 6 | --- 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/support-and-assistance.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: "/support-and-assistance" 3 | title: "Support and assistance" 4 | hidden: false 5 | information_page: true 6 | sidebar_priority: 4000 7 | --- 8 | 9 | ### Guidance during the autumn 10 | 11 | In the autumn of 2022 the course will have guidance in both Kumpula campus and on Discord. The sessions on campus are held in Exactum BK107. The guidance sessions are the following 12 | 13 | Note! Guidance will be held until December 16th. 14 | 15 | | Time / Date | MON | TUE | WED | THU | FRI | 16 | |-----|----|----|----|----|----| 17 | | 10-11 | Discord | - | Campus | - | - | 18 | | 11-12 | Discord | - | Campus | - | - | 19 | | 12-13 | Campus | - | - | Discord | Campus | 20 | | 13-14 | Campus | - | - | Discord | Campus | 21 | | 14-15 | - | Campus | Campus | - | - | 22 | | 15-16 | - | Campus | Campus | - | - | 23 | | 16-17 | - | Campus | - | - | - | 24 | | 17-18 | - | Campus | - | - | - | 25 | 26 | In the table **Campus** means that the guidance session will be on campus, **Discord** means its remotely on Discord. During the on-campus sessions there might be help available also on Discord if the assistants have time to follow the course Discord. 27 | 28 | *The schedule is subject to change.* 29 | 30 | #### Discord 31 | 32 | Discord is a communication platform which allows both text-based and voice/video chats. You can find out more about the platform [on the Discord website](https://discord.com/). 33 | 34 | The course channels are available through [this link](https://study.cs.helsinki.fi/discord/join/ohjelmoinnin_mooc). See especially the `ohjelmoinnin_mooc_english` and the `ohjelmoinnin_mooc_voice` channels for support in English. 35 | 36 | Instructor will be on standby on the course channels in Discord at guidance time. Instructor will also reply to questions sent via private messages. Discord also has a discussion about the course outside of the guidance hours, so it’s worth joining! 37 | -------------------------------------------------------------------------------- /data/vocabulary.md: -------------------------------------------------------------------------------- 1 | --- 2 | path: "/glossary" 3 | title: "Glossary" 4 | hidden: true 5 | information_page: true 6 | banner: false 7 | vocabulary_page: true 8 | hide_in_sidebar: true 9 | sidebar_priority: 1000 10 | --- 11 | 12 | This page will be filled in as the course progresses. 13 | 14 | 15 | -------------------------------------------------------------------------------- /develop-loop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | while : 3 | do 4 | echo "Spam [CTRL+C] to stop.." 5 | npm run develop || true 6 | sleep 1 7 | done 8 | -------------------------------------------------------------------------------- /docs/how-to-update-template.md: -------------------------------------------------------------------------------- 1 | ## How to update the template 2 | 3 | To update a course using this repository as a template, simply execute the script `update-material-template.sh` found in this repository's bin-directory. 4 | 5 | The script takes a single parameter, the path to the directory of the course that's updated. 6 | 7 | The script updates the following parts in the target directory: 8 | 9 | - src-directory 10 | - plugins-directory 11 | - docs-directory 12 | - all files beginning with `gatsby-` 13 | - all files beginning with `package` 14 | 15 | Note, that you might have to manually update some files (such as course-settings.js), if needed. 16 | -------------------------------------------------------------------------------- /docs/images/code-states-visualizer/markdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/code-states-visualizer/markdown.png -------------------------------------------------------------------------------- /docs/images/code-states-visualizer/network-monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/code-states-visualizer/network-monitor.png -------------------------------------------------------------------------------- /docs/images/code-states-visualizer/pythontutor-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/code-states-visualizer/pythontutor-editor.png -------------------------------------------------------------------------------- /docs/images/code-states-visualizer/pythontutor-frontpage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/code-states-visualizer/pythontutor-frontpage.png -------------------------------------------------------------------------------- /docs/images/vocabulary-example-english.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/vocabulary-example-english.png -------------------------------------------------------------------------------- /docs/images/vocabulary-example-finnish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/docs/images/vocabulary-example-finnish.png -------------------------------------------------------------------------------- /gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Browser APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/browser-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | require("prismjs/themes/prism.css") 9 | -------------------------------------------------------------------------------- /gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/TopLayout.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Helmet } from 'react-helmet'; 3 | import CssBaseline from '@material-ui/core/CssBaseline'; 4 | import { ThemeProvider } from '@material-ui/styles'; 5 | import theme from '../../src/theme'; 6 | 7 | export default function TopLayout(props) { 8 | return ( 9 | 10 | 11 | 15 | 16 | 17 | 18 | {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} 19 | 20 | {props.children} 21 | 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export, react/prop-types */ 2 | 3 | import React from 'react'; 4 | import TopLayout from './TopLayout'; 5 | 6 | export const wrapRootElement = ({ element }) => { 7 | return {element}; 8 | }; 9 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export, react/prop-types */ 2 | 3 | import React from 'react'; 4 | import TopLayout from './TopLayout'; 5 | 6 | export const wrapRootElement = ({ element }) => { 7 | return {element}; 8 | }; 9 | -------------------------------------------------------------------------------- /plugins/gatsby-plugin-top-layout/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-plugin-top-layout" 3 | } 4 | -------------------------------------------------------------------------------- /plugins/gatsby-transformer-moocfi-exercises/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-transformer-moocfi-exercises", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "Henrik Nygren ", 11 | "license": "Apache-2.0" 12 | } 13 | -------------------------------------------------------------------------------- /plugins/gatsby-transformer-vocabulary/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-transformer-vocabulary", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "Antti Leinonen ", 11 | "license": "Apache-2.0" 12 | } 13 | -------------------------------------------------------------------------------- /src/components/Banner.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import CourseSettings from "../../course-settings" 4 | 5 | import BannerImage from "../../banner.svg" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | 8 | const BannerWrapper = styled.header` 9 | height: 30rem; 10 | max-height: 50vh; 11 | display: flex; 12 | flex-direction: column; 13 | justify-content: center; 14 | align-items: center; 15 | margin-bottom: 2rem; 16 | background-color: #c0392b; 17 | background-image: url(${BannerImage}); 18 | text-align: center; 19 | h1 { 20 | } 21 | h2 { 22 | } 23 | ` 24 | 25 | const Heading = styled.div` 26 | font-family: "Roboto Slab", -apple-system, BlinkMacSystemFont, "Segoe UI", 27 | Roboto, "Helvetica Neue", Arial, Noto Sans, sans-serif, "Apple Color Emoji", 28 | "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 29 | font-weight: 500; 30 | font-size: 2rem; 31 | color: #c0392b; 32 | background: white; 33 | padding: 0.5rem; 34 | margin: 1rem; 35 | text-align: center; 36 | @media only screen and (min-width: 720px) { 37 | font-size: 3rem; 38 | } 39 | ` 40 | 41 | const SubHeading = styled.div` 42 | font-family: 'Roboto Slab', -apple-system, BlinkMacSystemFont, 'Segoe UI', 43 | Roboto, 'Helvetica Neue', Arial, Noto Sans, sans-serif, 'Apple Color Emoji', 44 | 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; 45 | font-weight: 500; 46 | color: #c0392b; 47 | background: white; 48 | padding .5rem; 49 | font-size: 1.4rem; 50 | margin: 0 1rem; 51 | ` 52 | 53 | const Banner = () => ( 54 | 55 | {CourseSettings.name} 56 | {CourseSettings.subtitle} 57 | 58 | ) 59 | 60 | export default withSimpleErrorBoundary(Banner) 61 | -------------------------------------------------------------------------------- /src/components/Button.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Link } from "gatsby" 3 | import styled from "styled-components" 4 | import { Button as MaterialButton } from "@material-ui/core" 5 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 6 | 7 | const StyledLink = styled(Link)` 8 | margin: 1rem 0.5rem; 9 | ` 10 | 11 | const Button = ({ children, to, onClick, disabled, variant = "outlined" }) => ( 12 | 17 | {children} 18 | 19 | ) 20 | 21 | export default withSimpleErrorBoundary(Button) 22 | -------------------------------------------------------------------------------- /src/components/Container.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | 4 | const Container = styled.div` 5 | width: 90%; 6 | max-width: 800px; 7 | margin: 0 auto; 8 | ` 9 | 10 | export default withSimpleErrorBoundary(Container) 11 | -------------------------------------------------------------------------------- /src/components/ContentArea.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | 5 | const ContentAreaContainer = styled.main` 6 | padding: 0 0.5rem; 7 | background-color: #fcfcfc; 8 | margin-bottom: 5rem; 9 | min-height: 80vh; 10 | font-size: 1rem; 11 | ${(props) => 12 | props.mobileMenuOpen && 13 | ` 14 | display: none; 15 | `} 16 | ` 17 | 18 | class ContentArea extends React.Component { 19 | render() { 20 | return ( 21 | 25 | {this.props.children} 26 | 27 | ) 28 | } 29 | } 30 | 31 | export default withSimpleErrorBoundary(ContentArea) 32 | -------------------------------------------------------------------------------- /src/components/CoursePageFooter.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import PagesInThisSection from "../partials/PagesInThisSection" 4 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 5 | 6 | const CoursePageFooterWrapper = styled.footer` 7 | background-color: white; 8 | color: black; 9 | padding: 3rem; 10 | ` 11 | 12 | const CoursePageFooterContent = styled.div` 13 | display: flex; 14 | justify-content: center; 15 | max-width: 960px; 16 | margin: 0 auto; 17 | ` 18 | 19 | class CoursePageFooter extends React.Component { 20 | render() { 21 | return ( 22 | 23 | 24 | 27 | 28 | 29 | ) 30 | } 31 | } 32 | 33 | export default withSimpleErrorBoundary(CoursePageFooter) 34 | -------------------------------------------------------------------------------- /src/components/Loading.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react" 2 | import styled from "styled-components" 3 | 4 | import { CircularProgress } from "@material-ui/core" 5 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 6 | 7 | const LoadingWrapper = styled.div` 8 | padding: 5rem; 9 | display: flex; 10 | align-items: center; 11 | flex-direction: column; 12 | width: 100%; 13 | ${(props) => 14 | props.heightHint && 15 | ` 16 | height: ${props.heightHint}; 17 | `} 18 | ` 19 | 20 | const Loading = ({ children, loading = true, heightHint = "500px" }) => { 21 | if (loading) { 22 | return ( 23 | 24 | 25 | 26 | ) 27 | } 28 | 29 | return {children} 30 | } 31 | 32 | export default withSimpleErrorBoundary(Loading) 33 | -------------------------------------------------------------------------------- /src/components/LoginControls.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react" 2 | import Button from "./Button" 3 | import { signOut, getCachedUserDetails } from "../services/moocfi" 4 | import LoginStateContext, { 5 | withLoginStateContext, 6 | } from "../contexes/LoginStateContext" 7 | import { withTranslation } from "react-i18next" 8 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 9 | import { faUser as profileIcon } from "@fortawesome/free-solid-svg-icons" 10 | import styled from "styled-components" 11 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 12 | 13 | const StyledIcon = styled(FontAwesomeIcon)` 14 | margin-right: 0.5rem; 15 | ` 16 | 17 | class LoginControls extends React.Component { 18 | static contextType = LoginStateContext 19 | 20 | doSignOut = (e) => { 21 | e.preventDefault() 22 | signOut() 23 | } 24 | 25 | async componentDidMount() { 26 | if (!this.context.loggedIn) { 27 | return 28 | } 29 | const details = await getCachedUserDetails() 30 | let name = `${details?.user_field?.first_name || ""} ${ 31 | details?.user_field?.last_name || "" 32 | }`.trim() 33 | if (name === "") { 34 | name = details.email 35 | } 36 | this.setState({ 37 | name, 38 | }) 39 | } 40 | 41 | state = { 42 | name: "Loading...", 43 | } 44 | 45 | render() { 46 | return this.context.loggedIn ? ( 47 | 48 | 52 | 55 | 56 | ) : ( 57 | 58 | 59 | 60 | 61 | ) 62 | } 63 | } 64 | 65 | export default withTranslation("common")( 66 | withSimpleErrorBoundary(withLoginStateContext(LoginControls)), 67 | ) 68 | -------------------------------------------------------------------------------- /src/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import logo from "../images/logo.png" 3 | import styled from "styled-components" 4 | import "typeface-open-sans-condensed" 5 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 6 | 7 | const LogoImg = styled.img` 8 | width: 3.4em; 9 | height: 3.4em; 10 | margin-right: 0.5em; 11 | margin-bottom: 0; 12 | ` 13 | 14 | const LogoTypography = styled.div` 15 | flex: 1; 16 | font-family: "Open Sans Condensed", sans-serif !important; 17 | font-size: 1.75em !important; 18 | ` 19 | 20 | const StyledLink = styled.a` 21 | text-decoration: none; 22 | color: black; 23 | display: flex; 24 | align-items: center; 25 | padding: 1em; 26 | padding-right: 1.7em; 27 | height: 64px; 28 | background-color: white; 29 | 30 | :hover { 31 | text-decoration: none; 32 | color: black; 33 | } 34 | ` 35 | 36 | const Logo = () => ( 37 | 38 | 39 | 40 | MOOC.fi 41 | 42 | 43 | ) 44 | 45 | export default withSimpleErrorBoundary(Logo) 46 | -------------------------------------------------------------------------------- /src/components/MailinglistForm.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import { withTranslation } from "react-i18next" 4 | import { TextField, Button } from "@material-ui/core" 5 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 6 | 7 | const Container = styled.div` 8 | padding: 3rem; 9 | ` 10 | 11 | const FieldContainer = styled.div` 12 | width: 100%; 13 | display: flex; 14 | height: 2.5rem; 15 | 16 | button { 17 | background-color: #22a7f0; 18 | color: white; 19 | border: 0; 20 | padding: 0 1rem; 21 | font-weight: bold; 22 | transition: all 0.2s; 23 | height: 3.5rem !important; 24 | margin-left: 0.5rem; 25 | &:hover { 26 | cursor: pointer; 27 | background-color: #4183d7; 28 | } 29 | } 30 | ` 31 | 32 | class MailingListForm extends React.Component { 33 | constructor(props) { 34 | super(props) 35 | this.form = React.createRef() 36 | } 37 | render() { 38 | return ( 39 | 40 |

{props.t("mailingListTitle")}

41 |
50 | 51 | 58 | 65 | 66 |
67 |
68 | ) 69 | } 70 | } 71 | 72 | export default withTranslation("common")( 73 | withSimpleErrorBoundary(MailingListForm), 74 | ) 75 | -------------------------------------------------------------------------------- /src/components/PointsBalloon/CourseProgress.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PartProgress from "./PartProgress" 3 | 4 | const splitCourses = false 5 | const CourseProgress = ({ 6 | data, 7 | appliesForStudyRight, 8 | currentCourseVariant, 9 | }) => { 10 | return ( 11 | data && 12 | (currentCourseVariant === "ohja-dl" || 13 | currentCourseVariant === "ohja-nodl" ? ( 14 |
15 |

Ohjelmoinnin jatkokurssi

16 | {Object.entries(data).map(([name, data]) => { 17 | return ( 18 | 23 | ) 24 | })} 25 |
26 | ) : ( 27 |
28 | {splitCourses &&

Ohjelmoinnin perusteet

} 29 | {Object.entries(data).map(([name, data]) => { 30 | if (name === "osa08" && splitCourses) { 31 | return ( 32 |
33 |

Ohjelmoinnin jatkokurssi

34 | 39 |
40 | ) 41 | } else { 42 | return ( 43 | 48 | ) 49 | } 50 | })} 51 |
52 | )) 53 | ) 54 | } 55 | 56 | export default CourseProgress 57 | -------------------------------------------------------------------------------- /src/components/PointsBalloon/CustomTooltip.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | import styled from "styled-components" 4 | import { SMALL_MEDIUM_BREAKPOINT } from "../../util/constants" 5 | import { withTranslation } from "react-i18next" 6 | 7 | const StyledTooltip = styled.div` 8 | background: white; 9 | border-radius: 0.25rem; 10 | padding: 0.5rem; 11 | p { 12 | margin-bottom: 0 !important; 13 | font-size: 0.9rem; 14 | } 15 | @media only screen and (max-width: ${SMALL_MEDIUM_BREAKPOINT}) { 16 | p { 17 | font-size: 0.75rem; 18 | } 19 | } 20 | ` 21 | 22 | const CustomTooltip = (props) => { 23 | if (!props.active) { 24 | return null 25 | } 26 | 27 | return ( 28 | 29 |

30 | {props.t("gotPoints")}: {props.payload?.[0].payload.n_points} 31 |

32 |

33 | {props.t("maxPoints")}: {props.payload?.[0].payload.max_points} 34 |

35 |
36 | ) 37 | } 38 | 39 | export default withTranslation("points-balloon")( 40 | withSimpleErrorBoundary(CustomTooltip), 41 | ) 42 | -------------------------------------------------------------------------------- /src/components/PointsBalloon/PointsBalloonBalloon.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | import Fab from "@material-ui/core/Fab" 4 | import styled from "styled-components" 5 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 6 | import { faChartLine as icon } from "@fortawesome/free-solid-svg-icons" 7 | 8 | const StyledIcon = styled(FontAwesomeIcon)` 9 | color: white; 10 | font-size: 1.5em !important; 11 | ` 12 | 13 | const StyledFab = styled(Fab)` 14 | background-color: #00a5ff !important; 15 | ` 16 | 17 | const PointsBalloonBalloon = ({ onClick }) => ( 18 | 19 | 20 | 21 | ) 22 | 23 | export default withSimpleErrorBoundary(PointsBalloonBalloon) 24 | -------------------------------------------------------------------------------- /src/components/PointsBalloon/index.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment } from "react" 2 | import LoginStateContext from "../../contexes/LoginStateContext" 3 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 4 | import styled from "styled-components" 5 | 6 | import PointsBalloonBalloon from "./PointsBalloonBalloon" 7 | import PointsBalloonContent from "./PointsBalloonContent" 8 | 9 | const PointsBalloonContainer = styled.div` 10 | position: fixed; 11 | right: 1.5rem; 12 | bottom: 1.5rem; 13 | z-index: 50; 14 | ` 15 | 16 | class PointsBalloon extends React.Component { 17 | static contextType = LoginStateContext 18 | 19 | state = { 20 | render: false, 21 | open: false, 22 | } 23 | 24 | componentDidMount() { 25 | this.setState({ render: true }) 26 | } 27 | 28 | onClick = () => { 29 | this.setState({ open: true }) 30 | } 31 | 32 | onClose = () => { 33 | this.setState({ open: false }) 34 | } 35 | 36 | render() { 37 | if (!this.state.render || !this.context.loggedIn) { 38 | return 39 | } 40 | return ( 41 | 42 | {!this.state.open && } 43 | {this.state.open && ( 44 | 48 | )} 49 | 50 | ) 51 | } 52 | } 53 | 54 | export default withSimpleErrorBoundary(PointsBalloon) 55 | -------------------------------------------------------------------------------- /src/components/StyledDivider.js: -------------------------------------------------------------------------------- 1 | import styled from "styled-components" 2 | import { Divider } from "@material-ui/core" 3 | 4 | const StyledDivider = styled(Divider)` 5 | margin: 1rem 16px !important; 6 | ` 7 | 8 | export default StyledDivider 9 | -------------------------------------------------------------------------------- /src/components/TopBar.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import LoginControls from "./LoginControls" 4 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 5 | import LoginStateContext, { 6 | withLoginStateContext, 7 | } from "../contexes/LoginStateContext" 8 | import Button from "./Button" 9 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 10 | import { faChartLine as pointsIcon } from "@fortawesome/free-solid-svg-icons" 11 | import CourseSettings from "../../course-settings" 12 | 13 | const TopBarContainer = styled.div` 14 | height: 4rem; 15 | width: 100%; 16 | display: flex; 17 | justify-content: flex-end; 18 | @media only screen and (max-width: 1200px) { 19 | justify-content: center; 20 | } 21 | ` 22 | 23 | const StyledIcon = styled(FontAwesomeIcon)` 24 | margin-right: 0.5rem; 25 | ` 26 | 27 | class TopBar extends React.Component { 28 | static contextType = LoginStateContext 29 | 30 | render() { 31 | return ( 32 | 33 | {CourseSettings.useNewPointsVisualization && this.context.loggedIn && ( 34 | 38 | )} 39 | 40 | 41 | ) 42 | } 43 | } 44 | 45 | export default withSimpleErrorBoundary(withLoginStateContext(TopBar)) 46 | -------------------------------------------------------------------------------- /src/components/TreeView/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import TreeViewItem from "./TreeViewItem" 3 | import styled from "styled-components" 4 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 5 | 6 | const StyledUl = styled.ul` 7 | margin-left: 0; 8 | margin-top: 0.5em; 9 | padding-left: 0; 10 | ` 11 | 12 | class TreeView extends React.Component { 13 | render() { 14 | return ( 15 | 16 | {this.props.data.map((top) => ( 17 | 18 | ))} 19 | 20 | ) 21 | } 22 | } 23 | 24 | export default withSimpleErrorBoundary(TreeView) 25 | -------------------------------------------------------------------------------- /src/components/user/ConfirmEmail.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Link } from "gatsby" 3 | import { withTranslation } from "react-i18next" 4 | import EmailExample from "../../images/email-example.png" 5 | 6 | import styled from "styled-components" 7 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 8 | 9 | const InfoBox = styled.div` 10 | margin-bottom: 2rem; 11 | ` 12 | 13 | const FormContainer = styled.div` 14 | height: 100%; 15 | margin-top: 2rem; 16 | ` 17 | 18 | const StyledImage = styled.img` 19 | width: 100%; 20 | padding: 1rem 0; 21 | ` 22 | 23 | class ConfirmEmail extends React.Component { 24 | onClick = async (e) => { 25 | e.preventDefault() 26 | } 27 | 28 | state = { 29 | email: undefined, 30 | password: undefined, 31 | submitting: false, 32 | error: false, 33 | } 34 | 35 | render() { 36 | return ( 37 | 38 |

{this.props.t("welcomeToCourse")}

39 | 40 |

{this.props.t("emailSent")}

41 | 42 |

{this.props.t("emailExample")}

43 | 44 | 48 |
49 |

50 | {this.props.t("nowContinue")}{" "} 51 | {this.props.t("toMaterial")}. 52 |

53 |
54 | ) 55 | } 56 | } 57 | 58 | export default withTranslation("user")(withSimpleErrorBoundary(ConfirmEmail)) 59 | -------------------------------------------------------------------------------- /src/contexes/AbGroupContext.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | export default React.createContext() 4 | -------------------------------------------------------------------------------- /src/contexes/LoginStateContext.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { loggedIn, onLoginStateChanged } from "../services/moocfi" 3 | 4 | const LoginStateContext = React.createContext() 5 | 6 | export class LoginStateContextProvider extends React.Component { 7 | constructor(props) { 8 | super(props) 9 | this.state = { 10 | loggedIn: loggedIn(), 11 | } 12 | } 13 | 14 | componentDidMount() { 15 | onLoginStateChanged((loggedIn) => { 16 | this.setState({ loggedIn }) 17 | }) 18 | setTimeout(() => { 19 | this.setState({ 20 | loggedIn: loggedIn(), 21 | }) 22 | }, 5000) 23 | } 24 | 25 | render() { 26 | return ( 27 | 28 | {this.props.children} 29 | 30 | ) 31 | } 32 | } 33 | 34 | export function withLoginStateContext(Component) { 35 | return (props) => ( 36 | 37 | 38 | 39 | ) 40 | } 41 | 42 | export default LoginStateContext 43 | -------------------------------------------------------------------------------- /src/contexes/PagesContext.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | export default React.createContext() 4 | -------------------------------------------------------------------------------- /src/html.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PropTypes from "prop-types" 3 | 4 | export default class HTML extends React.Component { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | 11 | 15 | {this.props.headComponents} 16 | 17 | 18 | {this.props.preBodyComponents} 19 |
24 | {this.props.postBodyComponents} 25 | 26 | 27 | ) 28 | } 29 | } 30 | 31 | HTML.propTypes = { 32 | htmlAttributes: PropTypes.object, 33 | headComponents: PropTypes.array, 34 | bodyAttributes: PropTypes.object, 35 | preBodyComponents: PropTypes.array, 36 | body: PropTypes.string, 37 | postBodyComponents: PropTypes.array, 38 | } 39 | -------------------------------------------------------------------------------- /src/i18n.js: -------------------------------------------------------------------------------- 1 | import i18n from "i18next" 2 | import { initReactI18next } from "react-i18next" 3 | import CourseSettings from "../course-settings" 4 | import commonEN from "./locales/common/en" 5 | import pointsBalloonEN from "./locales/pointsBalloon/en" 6 | import userEN from "./locales/user/en" 7 | import commonFI from "./locales/common/fi" 8 | import pointsBalloonFI from "./locales/pointsBalloon/fi" 9 | import userFI from "./locales/user/fi" 10 | 11 | const resources = { 12 | en: { 13 | common: commonEN, 14 | "points-balloon": pointsBalloonEN, 15 | user: userEN, 16 | }, 17 | fi: { 18 | common: commonFI, 19 | "points-balloon": pointsBalloonFI, 20 | user: userFI, 21 | }, 22 | } 23 | 24 | i18n.use(initReactI18next).init({ 25 | resources, 26 | ns: ["common", "user", "points-balloon"], 27 | defaultNS: "common", 28 | react: { 29 | wait: true, 30 | }, 31 | lng: CourseSettings.language, 32 | }) 33 | 34 | export default i18n 35 | -------------------------------------------------------------------------------- /src/images/email-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/src/images/email-example.png -------------------------------------------------------------------------------- /src/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/src/images/logo.png -------------------------------------------------------------------------------- /src/images/moocfi-logo-bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/src/images/moocfi-logo-bw.png -------------------------------------------------------------------------------- /src/images/uh-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rage/programming-22/dffe6da3749231671f1cfa41185228cd1dcce6cf/src/images/uh-logo.png -------------------------------------------------------------------------------- /src/locales/pointsBalloon/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "gotPoints": "Awarded points: ", 3 | "maxPoints": "Maximum points: ", 4 | "programmingService": "Programming exercises", 5 | "quizService": "Quizzes", 6 | "totalPoints": "Total points", 7 | "noTimeLimit": "You are doing the course without deadlines, and cannot apply for a study place.", 8 | "canApplyForStudyRight": "To be applicable for a study place, 90% of the points from programming exercises of the time limited course are required. Your progress so far: ", 9 | "progress":"Progress (beta)", 10 | "close": "close ", 11 | "error":"Fetching progress data failed with the following error: " 12 | } 13 | -------------------------------------------------------------------------------- /src/locales/pointsBalloon/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "gotPoints": "Saadut pisteet: ", 3 | "maxPoints": "Maksimipisteet: ", 4 | "programmingService": "Ohjelmointitehtävät", 5 | "quizService": "Kyselyt", 6 | "totalPoints": "Tehtäväpisteet yhteensä", 7 | "progressTotal": "Osasta saadut kurssipisteet: ", 8 | "noTimeLimit": "Olet aikatauluttomalla kurssilla, josta ei voi hakea opinto-oikeutta.", 9 | "canApplyForStudyRight": "Opinto-oikeuteen vaaditaan 90% aikataulutetun kurssin ohjelmointitehtävien pisteistä. Edistymisesi tällä hetkellä:", 10 | "progress":"Edistyminen (beta)", 11 | "close": "sulje", 12 | "error":"Edistymisen hakeminen kaatui seuraavaan virheeseen:" 13 | } 14 | -------------------------------------------------------------------------------- /src/locales/user/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcomeToCourse": "Welcome to the course!", 3 | "emailSent":"We have sent a confirmation link to your e-mail address. Please check your email and confirm your address.", 4 | "emailExample":"The email should look as follows:", 5 | "emailExampleAria":"Example e-mail", 6 | "nowContinue":"After this you can continue ", 7 | "toMaterial":"to the material", 8 | "withDeadlines": "Scheduled programming MOOC", 9 | "noDeadlines": "Unscheduled programming MOOC", 10 | "beginPart8withDeadlines":"I will start the scheduled course from part 8", 11 | "beginPart8withoutDeadlines":"I will start the unscheduled course from part 8", 12 | "summerMooc":"Summer: Scheduled programming MOOC.", 13 | "summerMoocDL":"Summer: I start the scheduled course from part 8", 14 | "whichCourse":"Which courses points, deadlines and coins do you want to see?", 15 | "emailInUse":"The email is already in use. Have you done mooc.fi courses before?", 16 | "problemCreatingAccount":"Problem creating an account. The error was: ", 17 | "noAt":"The email did not contain @", 18 | "passwordsNoMatch":"Passwords did not match", 19 | "createAccount":"Create new account", 20 | "courseUses":"This course uses", 21 | "courseUses2":"accounts. If you have previously done mooc.fi -courses, you can log in with your existing account. On this page you can create a new account, which works on majority of mooc.fi courses and services.", 22 | "email":"E-mail address", 23 | "emailUsername":"e-mail or username", 24 | "password":"password", 25 | "passwordAgain":"Repeat password", 26 | "create":"Create an account", 27 | "alreadyHaveAccount":" Already have an account? Log in", 28 | "error":"Error: ", 29 | "forgottenPW":"Forgot your password?", 30 | "wrongDetails":"Something is wrong with the login details, please check them for any typos!" 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/locales/user/fi.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcomeToCourse": "Tervetuloa kurssille!", 3 | "emailSent":"Olemme lähettäneet sähköpostiisi sähköpostiosoitteen varmistuslinkin. Käy nyt sähköpostissasi ja varmista osoitteesi.", 4 | "emailExample":"Sähköpostin pitäisi näyttää tälläiseltä:", 5 | "emailExampleAria":"Esimerkki sähköpostista", 6 | "nowContinue":"Tämän jälkeen voit jatkaa", 7 | "toMaterial":"materiaaliin", 8 | "withDeadlines": "Aikataulutettu Ohjelmoinnin MOOC", 9 | "noDeadlines": "Aikatauluton Ohjelmoinnin MOOC", 10 | "beginPart8withDeadlines":"Aloitan kurssin aikataulutettuna osasta 8 (Ohjelmoinnin jatkokurssi)", 11 | "beginPart8withoutDeadlines":"Aloitan kurssin aikatauluttomana osasta 8 (Ohjelmoinnin jatkokurssi)", 12 | "summerMooc":"Kesä: Aikataulutettu Ohjelmoinnin MOOC", 13 | "summerMoocDL":"Kesä: Aloitan kurssin aikataulutettuna osasta 8 (Ohjelmoinninjatkokurssi)", 14 | "whichCourse":"Minkä kurssin version pisteet, deadlinet ja kolikot haluat nähdä?", 15 | "emailInUse":"Sähköpostiosoitteesi on jo käytössä. Oletko tehnyt aikaisemmin mooc.fi:n kursseja?", 16 | "problemCreatingAccount":"Ongelma tunnuksen luonnissa. Virhe oli:", 17 | "noAt":"Sähköpostiosoitessa ei ole '@'-merkkiä.", 18 | "passwordsNoMatch":"Salasana ja salasana uudestaan eivät olleet samoja.", 19 | "createAccount":"Luo käyttäjätunnus", 20 | "courseUses":"Tämä kurssi käyttää", 21 | "courseUses2":"käyttäjätunnuksia. Jos olet aikaisemmin tehnyt mooc.fi -kursseja, voit käyttää sisäänkirjautumissivulla olemassaolevia tunnuksiasi. Tällä sivulla voit luoda uuden tunnuksen, joka toimii suurimmassa osassa mooc.fi:n kursseissa ja palveluissa.", 22 | "email":"Sähköpostiosoite", 23 | "emailUsername":"Sähköpostiosoite tai käyttäjänimi", 24 | "password":"Salasana", 25 | "passwordAgain":"Salasana uudestaan", 26 | "create":"Luo käyttäjätunnus", 27 | "alreadyHaveAccount":"Onko sinulla jo käyttäjätunnus? Kirjaudu sisään", 28 | "error":"Virhe: ", 29 | "forgottenPW":"Unohditko salasanasi?", 30 | "wrongDetails":"Virheelliset käyttäjätunnukset. Tarkista kirjoitusasu!" 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Layout from "../templates/Layout" 3 | import Container from "../components/Container" 4 | import { withLoginStateContext } from "../contexes/LoginStateContext" 5 | import Helmet from "react-helmet" 6 | 7 | const NotFoundPage = () => ( 8 | 9 | 10 | 11 |

Ei löytynyt

12 |

Olet päätynyt osoitteeseen, jota ei ole olemassa.

13 |
14 |
15 | ) 16 | 17 | export default withLoginStateContext(NotFoundPage) 18 | -------------------------------------------------------------------------------- /src/pages/missing-info.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import Layout from "../templates/Layout" 4 | import CourseOptionsEditor from "../components/user/CourseOptionsEditor" 5 | import { navigate } from "gatsby" 6 | import LoginStateContext, { 7 | withLoginStateContext, 8 | } from "../contexes/LoginStateContext" 9 | import Container from "../components/Container" 10 | 11 | class MissingInfo extends React.Component { 12 | static contextType = LoginStateContext 13 | 14 | onStepComplete = () => { 15 | if (typeof window !== "undefined") { 16 | window.history.back() 17 | return 18 | } 19 | navigate("/") 20 | } 21 | 22 | render() { 23 | if (!this.context.loggedIn) { 24 | if (typeof window !== "undefined") { 25 | navigate("/sign-in") 26 | } 27 | return
Redirecting...
28 | } 29 | return ( 30 | 31 | 32 | 36 | 37 | 38 | ) 39 | } 40 | } 41 | 42 | export default withLoginStateContext(MissingInfo) 43 | -------------------------------------------------------------------------------- /src/pages/sign-up.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Helmet from "react-helmet" 3 | 4 | import Layout from "../templates/Layout" 5 | import CreateAccountForm from "../components/user/CreateAccountForm" 6 | import CourseOptionsEditor from "../components/user/CourseOptionsEditor" 7 | import ConfirmEmail from "../components/user/ConfirmEmail" 8 | import LoginStateContext, { 9 | withLoginStateContext, 10 | } from "../contexes/LoginStateContext" 11 | import Container from "../components/Container" 12 | 13 | class SignInPage extends React.Component { 14 | static contextType = LoginStateContext 15 | 16 | state = { 17 | step: 1, 18 | } 19 | 20 | onStepComplete = () => { 21 | this.setState((prevState) => ({ 22 | step: prevState.step + 1, 23 | })) 24 | if (typeof window !== "undefined") { 25 | window.scrollTo(0, 0) 26 | } 27 | } 28 | 29 | render() { 30 | let stepComponent 31 | if (this.state.step === 1) { 32 | stepComponent = 33 | } else if (this.state.step === 2) { 34 | stepComponent = ( 35 | 39 | ) 40 | } else { 41 | stepComponent = 42 | } 43 | 44 | return ( 45 | 46 | 47 | {stepComponent} 48 | 49 | ) 50 | } 51 | } 52 | 53 | export default withLoginStateContext(SignInPage) 54 | -------------------------------------------------------------------------------- /src/partials/AbStudy/OnlyForAbGroup.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | import AbGroupContext from "../../contexes/AbGroupContext" 4 | 5 | class OnlyForAbGroup extends Component { 6 | static contextType = AbGroupContext 7 | 8 | state = { 9 | render: false, 10 | } 11 | 12 | componentDidMount() { 13 | this.setState({ render: true }) 14 | } 15 | 16 | render() { 17 | if (!this.state.render) { 18 | return
Loading...
19 | } 20 | if (!this.context) { 21 | return ( 22 |
23 | Error:. Please use only-for-ab-group only inside of ab-study 24 | components. 25 |
26 | ) 27 | } 28 | if (!this.props.group) { 29 | return
Error: please provide a group.
30 | } 31 | if (this.props.group === this.context.toString()) { 32 | return this.props.children 33 | } 34 | return
35 | } 36 | } 37 | 38 | export default withSimpleErrorBoundary(OnlyForAbGroup) 39 | -------------------------------------------------------------------------------- /src/partials/CodeHighLight.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | 4 | const CodeHighLight = () =>
Test
5 | 6 | export default withSimpleErrorBoundary(CodeHighLight) 7 | -------------------------------------------------------------------------------- /src/partials/CodeStatesVisualizer.js: -------------------------------------------------------------------------------- 1 | import React, { lazy, Suspense } from "react" 2 | 3 | import "code-states-visualizer/dist/app.css" 4 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 5 | const CodeStatesVisualizer = lazy(() => import("code-states-visualizer")) 6 | 7 | class CodeStatesVisualizerWrapper extends React.Component { 8 | state = { 9 | render: false, 10 | } 11 | 12 | componentDidMount() { 13 | this.setState({ render: true }) 14 | } 15 | 16 | render() { 17 | if (!this.state.render) { 18 | return
Loading...
19 | } 20 | const { input } = this.props 21 | return ( 22 | Loading...
}> 23 | 24 | 25 | ) 26 | } 27 | } 28 | 29 | export default withSimpleErrorBoundary(CodeStatesVisualizerWrapper) 30 | -------------------------------------------------------------------------------- /src/partials/Deadline.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 4 | import { faClock as icon } from "@fortawesome/free-solid-svg-icons" 5 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 6 | 7 | const DeadlineWrapper = styled.div` 8 | margin-bottom: 1rem; 9 | color: #6c757d; 10 | font-size: 0.9rem; 11 | font-weight: bold; 12 | ` 13 | 14 | const StyledIcon = styled(FontAwesomeIcon)` 15 | //vertical-align: middle; 16 | margin-right: 0.25em; 17 | font-size: 1em; 18 | ` 19 | 20 | const Deadline = ({ children }) => { 21 | return ( 22 | 23 | 24 | Deadline: {children} 25 | 26 | ) 27 | } 28 | 29 | export default withSimpleErrorBoundary(Deadline) 30 | -------------------------------------------------------------------------------- /src/partials/ExercisesInAllSections/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { withTranslation } from "react-i18next" 3 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 4 | import ExerciseList from "./ExerciseList" 5 | 6 | class ExercisesInAllSections extends React.Component { 7 | state = { 8 | render: false, 9 | } 10 | 11 | componentDidMount() { 12 | this.setState({ render: true }) 13 | } 14 | 15 | render() { 16 | if (!this.state.render) { 17 | return
Loading...
18 | } 19 | return 20 | } 21 | } 22 | 23 | export default withTranslation("common")( 24 | withSimpleErrorBoundary(ExercisesInAllSections), 25 | ) 26 | -------------------------------------------------------------------------------- /src/partials/ExercisesInThisSection/ExerciseSummary.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | import styled from "styled-components" 4 | import { normalizeExerciseId } from "../../util/strings" 5 | import { Link } from "gatsby" 6 | import { withTranslation } from "react-i18next" 7 | const ExerciseSummaryWrapper = styled(Link)` 8 | padding-left: 1rem; 9 | margin-bottom: 0.5rem; 10 | display: block; 11 | ` 12 | 13 | const ExerciseSummary = ({ exercise, index, quizIdToTitle, t }) => { 14 | let description = t("unknownType") 15 | if (exercise.type === "quiz") { 16 | const name = quizIdToTitle[exercise.id] 17 | if (name) { 18 | description = `${t("quiz")}: ${name}` 19 | } else { 20 | description = t("quiz") 21 | } 22 | } 23 | if (exercise.type === "programming-exercise") { 24 | description = `${t("programmingExercise")} ${exercise.id}` 25 | } 26 | if (exercise.type === "crowdsorcerer") { 27 | description = "Crowdsorcerer" 28 | } 29 | if (exercise.type === "moodle-exercise") { 30 | description = `${t("moodleExercise")} ${exercise.id}` 31 | } 32 | if (exercise.type === "sqltrainer-exercise") { 33 | description = `${t("sqlTrainerExercise")} ${exercise.id}` 34 | } 35 | if (exercise.type === "in-browser-programming-exercise") { 36 | description = `${t("programmingExercise")} ${exercise.id}` 37 | } 38 | let anchorLinkDigest = normalizeExerciseId(`${exercise.type}-${exercise.id}`) 39 | return ( 40 | 43 | {index + 1}. {description} 44 | 45 | ) 46 | } 47 | 48 | export default withTranslation("common")( 49 | withSimpleErrorBoundary(ExerciseSummary), 50 | ) 51 | -------------------------------------------------------------------------------- /src/partials/ExercisesInThisSection/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Accordion from "@material-ui/core/Accordion" 3 | import AccordionSummary from "@material-ui/core/AccordionSummary" 4 | import AccordionDetails from "@material-ui/core/AccordionDetails" 5 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 6 | import { faAngleDown as icon } from "@fortawesome/free-solid-svg-icons" 7 | import { withTranslation } from "react-i18next" 8 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 9 | import ExerciseList from "./ExerciseList" 10 | 11 | class ExercisesInThisSection extends React.Component { 12 | state = { 13 | render: false, 14 | } 15 | 16 | componentDidMount() { 17 | this.setState({ render: true }) 18 | } 19 | 20 | render() { 21 | if (!this.state.render) { 22 | return
Loading...
23 | } 24 | return ( 25 | 26 | }> 27 | {this.props.t("exerciseList")} 28 | 29 | 30 | 31 | 32 | 33 | ) 34 | } 35 | } 36 | 37 | export default withTranslation("common")( 38 | withSimpleErrorBoundary(ExercisesInThisSection), 39 | ) 40 | -------------------------------------------------------------------------------- /src/partials/FloatImageRight.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | 5 | const FloatImageRightContainer = styled.div`` 6 | 7 | const FloatImageRight = ({ children }) => { 8 | return {children} 9 | } 10 | 11 | export default withSimpleErrorBoundary(FloatImageRight) 12 | -------------------------------------------------------------------------------- /src/partials/GoogleFormLink.js: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react" 2 | import LoginStateContext from "../contexes/LoginStateContext" 3 | import styled from "styled-components" 4 | import { Card } from "@material-ui/core" 5 | import { withTranslation } from "react-i18next" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | import { useAsync } from "react-use" 8 | import { getCachedUserDetails } from "../services/moocfi" 9 | 10 | const Wrapper = styled(Card)` 11 | margin-bottom: 2rem; 12 | padding: 1rem; 13 | ` 14 | 15 | const MessageWrapper = styled.div` 16 | display: flex; 17 | align-items: center; 18 | ` 19 | 20 | const P = styled.p` 21 | margin-bottom: 1rem !important; 22 | ` 23 | 24 | const GoogleFormLink = ({ children, href, t, emailfieldname }) => { 25 | const { loggedIn } = useContext(LoginStateContext) 26 | const userDetails = useAsync(getCachedUserDetails) 27 | 28 | if (!loggedIn) { 29 | return ( 30 | 31 | 32 |
33 |

{t("loginToSee")}

34 |
35 |
36 |
37 | ) 38 | } 39 | 40 | if (userDetails.loading) { 41 | return
Loading...
42 | } 43 | 44 | if (userDetails.error) { 45 | return
Error while loading user information.
46 | } 47 | 48 | const email = userDetails.value.email 49 | 50 | let link = href 51 | if (emailfieldname) { 52 | link = `${link}&${encodeURIComponent(emailfieldname)}=${encodeURIComponent( 53 | email, 54 | )}` 55 | } 56 | return ( 57 | 58 | {children} 59 | 60 | ) 61 | } 62 | 63 | export default withTranslation("common")( 64 | withSimpleErrorBoundary(GoogleFormLink), 65 | ) 66 | -------------------------------------------------------------------------------- /src/partials/Headers/H1.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H1 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | 10 | const id = `${normalizeExerciseId(text)}` 11 | return ( 12 |

13 | {children} 14 |

15 | ) 16 | } 17 | 18 | export default H1 19 | -------------------------------------------------------------------------------- /src/partials/Headers/H2.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H2 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | const id = `${normalizeExerciseId(text)}` 10 | return ( 11 |

12 | {children} 13 |

14 | ) 15 | } 16 | 17 | export default H2 18 | -------------------------------------------------------------------------------- /src/partials/Headers/H3.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H3 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | const id = `${normalizeExerciseId(text)}` 10 | return ( 11 |

12 | {children} 13 |

14 | ) 15 | } 16 | 17 | export default H3 18 | -------------------------------------------------------------------------------- /src/partials/Headers/H4.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H4 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | const id = `${normalizeExerciseId(text)}` 10 | return ( 11 |

12 | {children} 13 |

14 | ) 15 | } 16 | 17 | export default H4 18 | -------------------------------------------------------------------------------- /src/partials/Headers/H5.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H5 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | const id = `${normalizeExerciseId(text)}` 10 | return ( 11 |
12 | {children} 13 |
14 | ) 15 | } 16 | 17 | export default H5 18 | -------------------------------------------------------------------------------- /src/partials/Headers/H6.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { normalizeExerciseId } from "../../util/strings" 3 | 4 | const H6 = ({ children }) => { 5 | let text = "unknown heading" 6 | try { 7 | text = children.find((o) => typeof o === "string") || "unknown heading" 8 | } catch (e) {} 9 | const id = `${normalizeExerciseId(text)}` 10 | return ( 11 |
12 | {children} 13 |
14 | ) 15 | } 16 | 17 | export default H6 18 | -------------------------------------------------------------------------------- /src/partials/Hr.js: -------------------------------------------------------------------------------- 1 | import { Divider } from "@material-ui/core" 2 | import styled from "styled-components" 3 | 4 | const StyledDivider = styled(Divider)` 5 | margin: 1em 16px !important; 6 | ` 7 | 8 | export default StyledDivider 9 | -------------------------------------------------------------------------------- /src/partials/InBrowserProgrammingExercise/index.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment, lazy, Suspense } from "react" 2 | import { Paper } from "@material-ui/core" 3 | import styled from "styled-components" 4 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 5 | import Loading from "../../components/Loading" 6 | const MoocFiPythonEditor = lazy(() => import("./MoocfiPythonEditorLoader")) 7 | 8 | const StyledPaper = styled(Paper)` 9 | @media only screen and (max-width: 800px) { 10 | overflow-y: scroll; 11 | } 12 | ` 13 | 14 | class MoocFiPythonEditorWrapper extends React.Component { 15 | state = { 16 | render: false, 17 | } 18 | 19 | constructor(props) { 20 | super(props) 21 | this.linkContainer = React.createRef() 22 | } 23 | 24 | componentDidMount() { 25 | this.setState({ render: true }) 26 | } 27 | 28 | render() { 29 | if (!this.state.render) { 30 | return ( 31 | 32 | 33 | 34 | ) 35 | } 36 | return ( 37 | Loading...
}> 38 | 39 | 40 | 41 | 42 | ) 43 | } 44 | } 45 | 46 | export default withSimpleErrorBoundary(MoocFiPythonEditorWrapper) 47 | -------------------------------------------------------------------------------- /src/partials/MoodleExercise.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 5 | import { faUniversity as icon } from "@fortawesome/free-solid-svg-icons" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | import { normalizeExerciseId } from "../util/strings" 8 | 9 | const Wrapper = styled.aside` 10 | padding 1rem; 11 | margin-bottom: 2rem; 12 | border-left: 0.2rem solid var(--color); 13 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 14 | border-radius: 4px; 15 | ` 16 | 17 | const StyledIcon = styled(FontAwesomeIcon)` 18 | vertical-align: middle; 19 | margin-right: 1rem; 20 | margin-left: 0.5rem; 21 | color: var(--color); 22 | ` 23 | 24 | const Header = styled.h3` 25 | font-size: 1.3rem; 26 | font-weight: normal; 27 | padding-bottom: 1rem; 28 | border-bottom: 1px solid #f7f7f9; 29 | ` 30 | 31 | const Body = styled.div` 32 | padding-bottom: 0.5rem; 33 | ` 34 | 35 | const MoodleExercise = (props) => { 36 | return ( 37 | 41 |
42 | 43 | Moodle-tehtävä: {props.name} 44 |
45 | {props.children} 46 |
47 | ) 48 | } 49 | 50 | export default withSimpleErrorBoundary(MoodleExercise) 51 | -------------------------------------------------------------------------------- /src/partials/Notice.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import Typography from "@material-ui/core/Typography" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | 5 | const Notice = (props) => { 6 | return ( 7 | 8 | {props.children} 9 | 10 | ) 11 | } 12 | 13 | export default withSimpleErrorBoundary(Notice) 14 | -------------------------------------------------------------------------------- /src/partials/OnlyForCourseVariant.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | import { getCourseVariant } from "../services/moocfi" 4 | import LoginStateContext from "../contexes/LoginStateContext" 5 | 6 | class OnlyForCourseVariant extends Component { 7 | static contextType = LoginStateContext 8 | state = { 9 | render: false, 10 | organization: "", 11 | course: "", 12 | } 13 | 14 | async componentDidMount() { 15 | this.setState({ 16 | render: true, 17 | }) 18 | 19 | const { tmcOrganization, tmcCourse } = await getCourseVariant() 20 | this.setState({ organization: tmcOrganization, course: tmcCourse }) 21 | } 22 | 23 | render() { 24 | if (!this.state.render && !this.state.organization && !this.state.course) { 25 | return
Loading...
26 | } 27 | if (!this.context.loggedIn) { 28 | return
29 | } 30 | if ( 31 | this.props.organization === this.state.organization && 32 | this.props.course === this.state.course 33 | ) { 34 | return this.props.children 35 | } 36 | return
37 | } 38 | } 39 | 40 | export default withSimpleErrorBoundary(OnlyForCourseVariant) 41 | -------------------------------------------------------------------------------- /src/partials/OnlyForNotLoggedIn.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | import LoginStateContext from "../contexes/LoginStateContext" 4 | 5 | class OnlyForNotLoggedIn extends Component { 6 | static contextType = LoginStateContext 7 | 8 | state = { 9 | render: false, 10 | } 11 | 12 | componentDidMount() { 13 | this.setState({ 14 | render: true, 15 | }) 16 | } 17 | 18 | render() { 19 | if (!this.state.render) { 20 | return
Loading...
21 | } 22 | if (!this.context.loggedIn) { 23 | return
{this.props.children}
24 | } 25 | return
26 | } 27 | } 28 | 29 | export default withSimpleErrorBoundary(OnlyForNotLoggedIn) 30 | -------------------------------------------------------------------------------- /src/partials/PdfSlideshow/PdfSlideshowLoader.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PdfSlideshow, { setPdfJsWorkerPath } from "pdf-slideshow" 3 | import { withPrefix } from "gatsby" 4 | import ReduxActionAnalytics from "redux-action-analytics" 5 | import { canDoResearch } from "../../services/moocfi" 6 | import * as storejs from "store" 7 | 8 | setPdfJsWorkerPath(withPrefix("/pdf.worker.min.js")) 9 | 10 | const PdfSlideshowLoader = (props) => { 11 | const middleware = [] 12 | const analytics = new ReduxActionAnalytics( 13 | "https://usage.testmycode.io/api/v0/data", 14 | "pdf-slideshow", 15 | props.pdfLocation, 16 | 10000, 17 | () => { 18 | const user = storejs.get("tmc.user") 19 | if (user === undefined) { 20 | return {} 21 | } 22 | return { 23 | username: user.username, 24 | } 25 | }, 26 | ) 27 | if (canDoResearch()) { 28 | middleware.push(analytics.getMiddleware()) 29 | } 30 | return 31 | } 32 | 33 | export default PdfSlideshowLoader 34 | -------------------------------------------------------------------------------- /src/partials/PdfSlideshow/index.js: -------------------------------------------------------------------------------- 1 | import React, { Fragment, lazy, Suspense } from "react" 2 | import { Paper } from "@material-ui/core" 3 | import styled from "styled-components" 4 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 5 | import Loading from "../../components/Loading" 6 | const PdfSlideshow = lazy(() => import("./PdfSlideshowLoader")) 7 | 8 | const HiddenLinkWrapper = styled.div` 9 | display: none; 10 | ` 11 | 12 | const StyledPaper = styled(Paper)` 13 | @media only screen and (max-width: 800px) { 14 | overflow-y: scroll; 15 | } 16 | ` 17 | 18 | class PdfSlideshowWrapper extends React.Component { 19 | state = { 20 | render: false, 21 | path: undefined, 22 | } 23 | 24 | constructor(props) { 25 | super(props) 26 | this.linkContainer = React.createRef() 27 | } 28 | 29 | componentDidMount() { 30 | const links = this.linkContainer.current 31 | const path = links.querySelector("a").href 32 | this.setState({ render: true, path }) 33 | } 34 | 35 | render() { 36 | if (!this.state.render) { 37 | return ( 38 | 39 | 40 | 41 | {this.props.children} 42 | 43 | 44 | ) 45 | } 46 | return ( 47 | Loading...
}> 48 | 49 | 50 | 51 | 52 | ) 53 | } 54 | } 55 | 56 | export default withSimpleErrorBoundary(PdfSlideshowWrapper) 57 | -------------------------------------------------------------------------------- /src/partials/PleaseLogin.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Card, CardContent } from "@material-ui/core" 3 | import styled from "styled-components" 4 | import LoginControls from "../components/LoginControls" 5 | import LoginStateContext from "../contexes/LoginStateContext" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | import { withTranslation } from "react-i18next" 8 | const PleaseLoginWrapper = styled(Card)` 9 | margin-bottom: 2rem; 10 | ` 11 | 12 | const Wrapper = styled.div` 13 | margin-bottom: 1rem; 14 | ` 15 | class PleaseLogin extends React.Component { 16 | static contextType = LoginStateContext 17 | 18 | render() { 19 | if (this.context.loggedIn) { 20 | return
21 | } 22 | return ( 23 | 24 | 25 | {this.props.t("pleaseLogin")} 26 |
27 | 28 |
29 |
30 |
31 | ) 32 | } 33 | } 34 | 35 | export default withTranslation("common")(withSimpleErrorBoundary(PleaseLogin)) 36 | -------------------------------------------------------------------------------- /src/partials/Points/OverallPoints.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Card, CardContent, Typography, Button } from "@material-ui/core" 3 | import { LinearProgress } from "@material-ui/core" 4 | import styled from "styled-components" 5 | 6 | const ProgressLineContainer = styled.div` 7 | display: flex; 8 | align-items: center; 9 | margin: 1rem 0; 10 | div { 11 | height: 20px; 12 | } 13 | ` 14 | 15 | const StyledLinearProgress = styled(LinearProgress)` 16 | flex: 1; 17 | margin-left: 10px; 18 | ` 19 | 20 | const OverallPoints = ({ courseName, progress, refetch }) => { 21 | const data = progress.user_course_progress.progress.sort((a, b) => 22 | a.group.localeCompare(b.group, undefined, { 23 | numeric: true, 24 | sensitivity: "base", 25 | }), 26 | ) 27 | return ( 28 | 29 | 30 | 31 | {courseName} 32 | 33 | 34 | {data.map((group) => { 35 | return ( 36 | <> 37 | 38 | {group.group} 39 | 43 | 44 | 45 | ) 46 | })} 47 | 54 | 55 | 56 | ) 57 | } 58 | 59 | export default OverallPoints 60 | -------------------------------------------------------------------------------- /src/partials/Points/PartPoints.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { Card, CardContent, Typography } from "@material-ui/core" 3 | 4 | export default ({ points }) => ( 5 | 6 | 7 | 8 | Pisteet: {points.group} 9 | 10 | 11 | 12 | ) 13 | -------------------------------------------------------------------------------- /src/partials/Points/PointsImpl.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | 4 | import { useQuery } from "@apollo/react-hooks" 5 | import { gql } from "apollo-boost" 6 | import { Button } from "@material-ui/core" 7 | import OverallPoints from "./OverallPoints" 8 | 9 | const PROGRESS = gql` 10 | { 11 | currentUser { 12 | email 13 | progress(course_id: "59314cb4-a9ca-43c9-b9a7-58c19325b44c") { 14 | course { 15 | id 16 | name 17 | } 18 | user_course_progress { 19 | id 20 | progress 21 | } 22 | user_course_service_progresses { 23 | id 24 | progress 25 | service { 26 | id 27 | name 28 | } 29 | } 30 | } 31 | } 32 | } 33 | ` 34 | 35 | const Points = (props) => { 36 | // const course = props.course || CourseSettings.slug 37 | const { data, loading, error, refetch } = useQuery(PROGRESS) 38 | 39 | if (loading) { 40 | return <>Loading... 41 | } 42 | 43 | if (error) { 44 | return <>Error while fetching progress: {error} 45 | } 46 | 47 | if (!data || !data.currentUser) { 48 | return ( 49 | <> 50 | 57 |

Please log in to see your points.

58 | 59 | ) 60 | } 61 | 62 | // const points = data.currentUser.progress.user_course_progress.progress[0] 63 | const courseName = data.currentUser.progress.course.name 64 | return ( 65 | <> 66 | 71 | 72 | ) 73 | } 74 | 75 | export default withSimpleErrorBoundary(Points) 76 | -------------------------------------------------------------------------------- /src/partials/Points/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PointsImpl from "./PointsImpl" 3 | import ApolloClient from "apollo-boost" 4 | import { ApolloProvider } from "@apollo/react-hooks" 5 | import { accessToken } from "../../services/moocfi" 6 | 7 | export default class Points extends React.Component { 8 | state = { 9 | render: false, 10 | } 11 | componentDidMount() { 12 | this.setState({ render: true }) 13 | } 14 | render() { 15 | if (!this.state.render) { 16 | return
Loading...
17 | } 18 | const apolloClient = new ApolloClient({ 19 | uri: "https://www.mooc.fi/api", 20 | request: async (operation) => { 21 | const token = accessToken() 22 | if (!token) { 23 | return 24 | } 25 | operation.setContext({ 26 | headers: { 27 | Authorization: `Bearer ${token}`, 28 | }, 29 | }) 30 | }, 31 | }) 32 | return ( 33 | 34 | {" "} 35 | 36 | ) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/partials/ProgrammingExercise/ExerciseDescription.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | 4 | const ExerciseDescriptionWrapper = styled.div` 5 | counter-reset: headingCounter; 6 | 7 | h1::before, 8 | h2::before, 9 | h3::before, 10 | h4::before, 11 | h5::before { 12 | content: "Part " counter(headingCounter) ": "; 13 | counter-increment: headingCounter; 14 | } 15 | ` 16 | 17 | const ExerciseDescription = ({ children }) => ( 18 | 19 |
20 | {children} 21 | 22 | ) 23 | 24 | export default ExerciseDescription 25 | -------------------------------------------------------------------------------- /src/partials/Quiznator.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | import { normalizeExerciseId } from "../util/strings" 5 | 6 | const quizWrapper = styled.div` 7 | code { 8 | color: black !important; 9 | } 10 | ` 11 | 12 | class Quiznator extends React.Component { 13 | componentDidMount() { 14 | const { id } = this.props 15 | if (!id || typeof window === "undefined") { 16 | return 17 | } 18 | if (!window.loadQuiz) { 19 | return 20 | } 21 | window.loadQuiz(document.getElementById(`unloaded-quiz-${id}`)) 22 | } 23 | 24 | render() { 25 | const { id } = this.props 26 | if (!id) { 27 | return
There should be quiz here but no quiz id is specified.
28 | } 29 | return ( 30 | 31 |
36 | 37 | ) 38 | } 39 | } 40 | 41 | export default withSimpleErrorBoundary(Quiznator) 42 | -------------------------------------------------------------------------------- /src/partials/RegistrationLink.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import moment from "moment" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | 5 | const start = moment("01/01/2018", "DD/MM/YYYY") 6 | const summerStart = moment("18/03/2019", "DD/MM/YYYY") 7 | const autumnStart = moment("06/05/2019", "DD/MM/YYYY") 8 | 9 | const springLink = 10 | "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404110" 11 | const summerLink = 12 | "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404483" 13 | // const autumnLink = 14 | // "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404483" 15 | 16 | function getLink() { 17 | const currentDate = moment() 18 | if (currentDate.isBetween(start, summerStart)) { 19 | return springLink 20 | } 21 | if (currentDate.isBetween(start, autumnStart)) { 22 | return summerLink 23 | } 24 | return springLink 25 | } 26 | 27 | const RegistrationLink = () => { 28 | return {getLink()} 29 | } 30 | 31 | export default withSimpleErrorBoundary(RegistrationLink) 32 | -------------------------------------------------------------------------------- /src/partials/RegistrationLink2.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import moment from "moment" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | 5 | const start = moment("01/01/2018", "DD/MM/YYYY") 6 | const summerStart = moment("20/05/2019", "DD/MM/YYYY") 7 | const autumnStart = moment("05/07/2019", "DD/MM/YYYY") 8 | 9 | const springLink = 10 | "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404483" 11 | const summerLink = 12 | "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404483" 13 | // const autumnLink = 14 | // "https://www.avoin.helsinki.fi/palvelut/esittely.aspx?o=127404483" 15 | 16 | function getLink() { 17 | const currentDate = moment() 18 | if (currentDate.isBetween(start, summerStart)) { 19 | return springLink 20 | } 21 | if (currentDate.isBetween(start, autumnStart)) { 22 | return summerLink 23 | } 24 | return springLink 25 | } 26 | 27 | const RegistrationLink2 = () => { 28 | return {getLink()} 29 | } 30 | 31 | export default withSimpleErrorBoundary(RegistrationLink2) 32 | -------------------------------------------------------------------------------- /src/partials/SampleData.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | import { withTranslation } from "react-i18next" 5 | 6 | const accentColor = "#CCC" 7 | 8 | const Wrapper = styled.div` 9 | padding 1rem; 10 | padding-top: 0.2rem; 11 | margin-bottom: 2rem; 12 | border-left: 0.2rem solid ${accentColor}; 13 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 14 | border-radius: 4px; 15 | ` 16 | 17 | const Body = styled.div` 18 | padding-bottom: 0.5rem; 19 | font-family: monospace; 20 | white-space: pre-wrap; 21 | 22 | p:last-of-type { 23 | margin-bottom: 0; 24 | } 25 | 26 | em, 27 | strong { 28 | color: red; 29 | font-weight: normal; 30 | } 31 | ` 32 | 33 | const Note = styled.div` 34 | width: 100%; 35 | text-align: right; 36 | font-size: 0.75rem; 37 | ` 38 | 39 | const SampleData = (props) => { 40 | return ( 41 | 42 | {props.t("sampleData")} 43 | {props.children} 44 | 45 | ) 46 | } 47 | 48 | export default withTranslation("common")(withSimpleErrorBoundary(SampleData)) 49 | -------------------------------------------------------------------------------- /src/partials/SampleOutput.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | import { withTranslation } from "react-i18next" 5 | 6 | const accentColor = "#CCC" 7 | 8 | const Wrapper = styled.div` 9 | padding 1rem; 10 | padding-top: 0.2rem; 11 | margin-bottom: 2rem; 12 | border-left: 0.2rem solid ${accentColor}; 13 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 14 | border-radius: 4px; 15 | ` 16 | 17 | const Body = styled.div` 18 | padding-bottom: 0.5rem; 19 | font-family: monospace; 20 | white-space: pre-wrap; 21 | 22 | p:last-of-type { 23 | margin-bottom: 0; 24 | } 25 | 26 | em, 27 | strong { 28 | color: red; 29 | font-weight: normal; 30 | } 31 | ` 32 | 33 | const Note = styled.div` 34 | width: 100%; 35 | text-align: right; 36 | font-size: 0.75rem; 37 | ` 38 | 39 | const SampleOutput = (props) => { 40 | return ( 41 | 42 | {props.t("sampleOutput")} 43 | {props.children} 44 | 45 | ) 46 | } 47 | 48 | export default withTranslation("common")(withSimpleErrorBoundary(SampleOutput)) 49 | -------------------------------------------------------------------------------- /src/partials/SqlTrainerExercise.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 5 | import { faDatabase as icon } from "@fortawesome/free-solid-svg-icons" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | import { normalizeExerciseId } from "../util/strings" 8 | 9 | const Wrapper = styled.aside` 10 | padding 1rem; 11 | margin-bottom: 2rem; 12 | border-left: 0.2rem solid var(--color); 13 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 14 | border-radius: 4px; 15 | ` 16 | 17 | const StyledIcon = styled(FontAwesomeIcon)` 18 | vertical-align: middle; 19 | margin-right: 1rem; 20 | margin-left: 0.5rem; 21 | color: var(--color); 22 | ` 23 | 24 | const Header = styled.h3` 25 | font-size: 1.3rem; 26 | font-weight: normal; 27 | padding-bottom: 1rem; 28 | border-bottom: 1px solid #f7f7f9; 29 | ` 30 | 31 | const Body = styled.div` 32 | padding-bottom: 0.5rem; 33 | ` 34 | 35 | const SqltrainerExercise = (props) => { 36 | return ( 37 | 41 |
42 | 43 | SQL Trainer -tehtävä: {props.name} 44 |
45 | 46 | {props.children} 47 | Löydät harjoittelujärjestelmän osoitteesta{" "} 48 | 53 | https://sql-t.herokuapp.com/ 54 | 55 | 56 |
57 | ) 58 | } 59 | 60 | export default withSimpleErrorBoundary(SqltrainerExercise) 61 | -------------------------------------------------------------------------------- /src/partials/Summary.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 4 | import { withTranslation } from "react-i18next" 5 | 6 | const Wrapper = styled.aside` 7 | border-left: 0.2rem solid var(--color); 8 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 9 | 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 10 | border-radius: 4px; 11 | ` 12 | 13 | const Header = styled.h3` 14 | font-size: 1.3rem; 15 | font-weight: normal; 16 | padding: 0.5rem; 17 | margin: 0.5rem 1rem; 18 | ` 19 | 20 | const Body = styled.div` 21 | margin: 0.5rem 1rem; 22 | ` 23 | 24 | const Split = styled.div` 25 | border-bottom: 1px solid #bdc3c7; 26 | ` 27 | 28 | const Summary = (props) => { 29 | const updatedPropsChildren = props.children.map((child, index) => { 30 | return child.type.displayName === "Hr__StyledDivider" ? ( 31 | 32 | ) : ( 33 | {child} 34 | ) 35 | }) 36 | return ( 37 | 38 |
Tässä osiossa käsiteltiin seuraavat asiat:
39 | 40 | {updatedPropsChildren} 41 |
42 | ) 43 | } 44 | 45 | export default withTranslation("common")(withSimpleErrorBoundary(Summary)) 46 | -------------------------------------------------------------------------------- /src/partials/Table.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | import Paper from "@material-ui/core/Paper" 4 | 5 | import MaterialTable from "@material-ui/core/Table" 6 | import MaterialTableBody from "@material-ui/core/TableBody" 7 | import MaterialTableCell from "@material-ui/core/TableCell" 8 | import MaterialTableHead from "@material-ui/core/TableHead" 9 | import MaterialTableRow from "@material-ui/core/TableRow" 10 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 11 | 12 | const StyledTableCell = styled(MaterialTableCell)` 13 | padding: 1rem !important; 14 | ` 15 | 16 | export const Table = withSimpleErrorBoundary((props) => ( 17 | 18 | 19 | 20 | )) 21 | 22 | export const TableBody = withSimpleErrorBoundary((props) => ( 23 | 24 | )) 25 | 26 | export const TableCell = withSimpleErrorBoundary((props) => ( 27 | 28 | )) 29 | 30 | export const TableTh = withSimpleErrorBoundary((props) => ( 31 | 32 | )) 33 | 34 | export const TableHead = withSimpleErrorBoundary((props) => ( 35 | 36 | )) 37 | 38 | export const TableRow = withSimpleErrorBoundary((props) => ( 39 | 40 | )) 41 | -------------------------------------------------------------------------------- /src/partials/TableOfContents.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react" 2 | import Loading from "../components/Loading" 3 | import styled from "styled-components" 4 | import { Paper } from "@material-ui/core" 5 | import { normalizeExerciseId } from "../util/strings" 6 | import { withTranslation } from "react-i18next" 7 | 8 | const TableOfContentsWrapper = styled(Paper)` 9 | padding: 1rem; 10 | margin: 2rem 0; 11 | ` 12 | 13 | class TableOfContents extends Component { 14 | state = { data: null } 15 | 16 | componentDidMount() { 17 | const data = Array.from( 18 | document.querySelectorAll( 19 | "h1.material-header,h2.material-header,h3.material-header", 20 | ), 21 | ).map((o) => { 22 | return o.textContent || o.innerText 23 | }) 24 | this.setState({ data }) 25 | } 26 | 27 | render() { 28 | return ( 29 | 30 |

{this.props.t("tableOfContents")}

31 |
32 | {this.state.data ? ( 33 |
    34 | {this.state.data.map((o) => { 35 | return ( 36 |
  1. 37 | {o} 38 |
  2. 39 | ) 40 | })} 41 |
42 | ) : ( 43 | 44 | )} 45 |
46 |
47 | ) 48 | } 49 | } 50 | 51 | export default withTranslation("common")(TableOfContents) 52 | -------------------------------------------------------------------------------- /src/partials/Test.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | 4 | const Test = (props) => { 5 | return
{JSON.stringify(props, null, 2)}
6 | } 7 | 8 | export default withSimpleErrorBoundary(Test) 9 | -------------------------------------------------------------------------------- /src/partials/Test2.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | 4 | const Test = (props) => { 5 | return
{props.children}
6 | } 7 | 8 | export default withSimpleErrorBoundary(Test) 9 | -------------------------------------------------------------------------------- /src/partials/TextBox.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import styled from "styled-components" 3 | 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" 5 | import { faInfoCircle, faUserGraduate } from "@fortawesome/free-solid-svg-icons" 6 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 7 | 8 | const Wrapper = styled.aside` 9 | padding 1rem; 10 | margin-bottom: 2rem; 11 | border-left: 0.2rem solid var(--color); 12 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 13 | border-radius: 4px; 14 | ` 15 | 16 | const StyledIcon = styled(FontAwesomeIcon)` 17 | vertical-align: middle; 18 | margin-right: 1rem; 19 | margin-left: 0.5rem; 20 | color: var(--color); 21 | ` 22 | 23 | const Header = styled.h3` 24 | font-size: 1.3rem; 25 | font-weight: normal; 26 | padding-bottom: 1rem; 27 | border-bottom: 1px solid #f7f7f9; 28 | ` 29 | 30 | const Body = styled.div` 31 | padding-bottom: 0.5rem; 32 | ` 33 | 34 | const variantToColor = { 35 | hint: "#528afc", 36 | learningObjectives: "#57b181", 37 | } 38 | 39 | const variantToIcon = { 40 | hint: faInfoCircle, 41 | learningObjectives: faUserGraduate, 42 | } 43 | 44 | const TextBox = (props) => { 45 | return ( 46 | 47 |
48 | 49 | {props.name} 50 |
51 | {props.children} 52 |
53 | ) 54 | } 55 | 56 | export default withSimpleErrorBoundary(TextBox) 57 | -------------------------------------------------------------------------------- /src/partials/Vocabulary/VocabularyWord.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | 4 | const VocabularyWord = ({ name, description }) => { 5 | const anchor = name.toLowerCase().replace(" ", "-") 6 | console.log(anchor) 7 | return
8 | } 9 | 10 | export default withSimpleErrorBoundary(VocabularyWord) 11 | -------------------------------------------------------------------------------- /src/partials/Vocabulary/Word.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../../util/withSimpleErrorBoundary" 3 | import { withTranslation } from "react-i18next" 4 | import { AnchorLink } from "gatsby-plugin-anchor-links" 5 | import styled from "styled-components" 6 | 7 | const StyledWord = styled.div` 8 | margin-bottom: 0.5em; 9 | ` 10 | 11 | const StyledLink = styled(AnchorLink)` 12 | margin-left: 0.5em; 13 | ` 14 | 15 | const transformParentPagePath = (parentPagePath) => { 16 | const sectionNumber = parentPagePath.split("-")[1].replace("/", ".") 17 | return sectionNumber 18 | } 19 | 20 | const transformNameToAnchor = (name) => { 21 | return name.toLowerCase().replace(" ", "-") 22 | } 23 | 24 | const Word = ({ word }) => { 25 | return ( 26 | 27 | {word.name}, 28 | {Array.isArray(word.parentPagePath) ? ( 29 | word.parentPagePath.map((path, i) => ( 30 | 34 | {transformParentPagePath(path)} 35 | 36 | )) 37 | ) : ( 38 | 41 | {transformParentPagePath(word.parentPagePath)} 42 | 43 | )} 44 | {word.description && 45 | (Array.isArray(word.description) ? ( 46 | word.description.map((d, i) =>
- {d}
) 47 | ) : ( 48 |
- {word.description}
49 | ))} 50 |
51 | ) 52 | } 53 | 54 | export default withTranslation("common")(withSimpleErrorBoundary(Word)) 55 | -------------------------------------------------------------------------------- /src/partials/WorkshopSchedule.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import withSimpleErrorBoundary from "../util/withSimpleErrorBoundary" 3 | import CourseSettings from "../../course-settings" 4 | 5 | const WorkShopSchedule = ({ slug }) => { 6 | const language = CourseSettings.language 7 | return ( 8 | 17 | ) 18 | } 19 | 20 | export default withSimpleErrorBoundary(WorkShopSchedule) 21 | -------------------------------------------------------------------------------- /src/services/abstudio.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | import { accessToken } from "./moocfi" 3 | 4 | const BASE_URL = "https://ab-studio.testmycode.io" 5 | 6 | export async function fetchAbGroup(studyId) { 7 | const res = await axios.get( 8 | `${BASE_URL}/api/v0/ab_studies/${studyId}/group?oauth_token=${accessToken()}`, 9 | ) 10 | return res.data 11 | } 12 | -------------------------------------------------------------------------------- /src/services/progress.js: -------------------------------------------------------------------------------- 1 | import { fetchProgrammingProgress } from "./moocfi" 2 | import { zip } from "../util/arrays" 3 | import { fetchQuizzesProgress } from "./quizzes" 4 | 5 | //eslint-disable-next-line no-unused-vars 6 | const introductionCourseGroups = [ 7 | "osa01", 8 | "osa02", 9 | "osa03", 10 | "osa04", 11 | "osa05", 12 | "osa06", 13 | "osa07", 14 | ] 15 | 16 | export async function fetchProgress(t) { 17 | // await fetchQuizzesProgress() 18 | const serviceIdentifiers = [t("programmingService"), t("quizService")] 19 | const progressesCollection = await Promise.all([ 20 | fetchProgrammingProgress(), 21 | fetchQuizzesProgress(), 22 | ]) 23 | // const userDetails = await getCachedUserDetails() 24 | // const currentCourseVariant = userDetails?.extra_fields?.course_variant 25 | const progressByGroup = {} 26 | 27 | zip(serviceIdentifiers, progressesCollection).forEach( 28 | ([identifier, progresses]) => { 29 | console.log(JSON.stringify(progresses)) 30 | progresses.forEach((progressEntry) => { 31 | if (!progressByGroup[progressEntry.group]) { 32 | progressByGroup[progressEntry.group] = {} 33 | } 34 | progressByGroup[progressEntry.group][identifier] = progressEntry 35 | }) 36 | }, 37 | ) 38 | const toBeDeleted = [] 39 | Object.entries(progressByGroup).forEach(([group, serviceEntries]) => { 40 | if ( 41 | !Object.keys(serviceEntries).find((o) => o === t("programmingService")) 42 | ) { 43 | toBeDeleted.push(group) 44 | } 45 | }) 46 | // TODO: this is not a good way to do this 47 | toBeDeleted.forEach((o) => { 48 | delete progressByGroup[o] 49 | }) 50 | return progressByGroup 51 | } 52 | -------------------------------------------------------------------------------- /src/services/quizzes.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | import { accessToken, getCourseVariant } from "./moocfi" 3 | import CourseSettings from "../../course-settings" 4 | 5 | // const id = CourseSettings.quizzesId 6 | const language = CourseSettings.language 7 | 8 | // const quizzesLanguage = language === "en" ? "en_US" : "fi_FI" 9 | 10 | export async function fetchQuizzesProgress() { 11 | const { quizzesId } = await getCourseVariant() 12 | const response = await axios.get( 13 | `https://quizzes.mooc.fi/api/v2/general/course/${quizzesId}/progress`, 14 | { headers: { Authorization: `Bearer ${accessToken()}` } }, 15 | ) 16 | return response.data 17 | } 18 | 19 | export async function fetchQuizNames() { 20 | const { quizzesId } = await getCourseVariant() 21 | const response = await axios.get( 22 | `https://quizzes.mooc.fi/api/v2/general/course/${quizzesId}/quiz-titles`, 23 | ) 24 | return response.data 25 | } 26 | -------------------------------------------------------------------------------- /src/templates/remark.css: -------------------------------------------------------------------------------- 1 | code { 2 | font-family: 'Roboto Mono', monospace; 3 | } 4 | 5 | .gatsby-highlight { 6 | margin-bottom: 2rem; 7 | } 8 | 9 | .gatsby-highlight pre { 10 | border-radius: 10px; 11 | box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 2px 1px -1px rgba(0, 0, 0, 0.12); 12 | } 13 | 14 | .gatsby-highlight code.language-text { 15 | padding: 0.2rem !important; 16 | margin-right: 0.4rem; 17 | padding-left: 0.4rem !important; 18 | } 19 | 20 | .gatsby-highlight code, .gatsby-highlight pre { 21 | background-color: white !important; 22 | } 23 | 24 | :not(pre) > code[class*='language-'] { 25 | background-color: rgb(243, 243, 243) !important; 26 | color: rgb(20, 20, 20) !important; 27 | white-space: pre-wrap; 28 | } 29 | 30 | 31 | @media only screen and (min-width: 550px) { 32 | .singleline-code > code { 33 | white-space: nowrap !important; 34 | } 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | import { red, blue } from "@material-ui/core/colors" 2 | import { createMuiTheme } from "@material-ui/core/styles" 3 | 4 | // A custom theme for this app 5 | const theme = createMuiTheme({ 6 | palette: { 7 | primary: { 8 | light: blue[300], 9 | main: blue[500], 10 | dark: blue[700], 11 | }, 12 | secondary: { 13 | light: red[300], 14 | main: red[500], 15 | dark: red[700], 16 | }, 17 | }, 18 | typography: { 19 | useNextVariants: true, 20 | }, 21 | overrides: { 22 | MuiButton: { 23 | label: { 24 | textTransform: "none", 25 | }, 26 | root: { 27 | textTransform: "none", 28 | }, 29 | }, 30 | MuiTypography: { 31 | body2: { 32 | fontSize: "16px", 33 | }, 34 | subheading: { 35 | fontSize: "18px", 36 | }, 37 | }, 38 | }, 39 | }) 40 | 41 | export default theme 42 | -------------------------------------------------------------------------------- /src/util/arrays.js: -------------------------------------------------------------------------------- 1 | export function flatten(arr) { 2 | return arr.reduce(function (flat, toFlatten) { 3 | return flat.concat( 4 | Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten, 5 | ) 6 | }, []) 7 | } 8 | 9 | export function zip(arr, ...arrs) { 10 | return arr.map((val, i) => arrs.reduce((a, arr) => [...a, arr[i]], [val])) 11 | } 12 | 13 | export function getCommonElements(array1, array2) { 14 | return array1.filter((value) => -1 !== array2.indexOf(value)) 15 | } 16 | -------------------------------------------------------------------------------- /src/util/constants.js: -------------------------------------------------------------------------------- 1 | export const SMALL_MEDIUM_BREAKPOINT = "900px" 2 | export const MEDIUM_LARGE_BREAKPOINT = "1200px" 3 | export const MEDIUM_SIDEBAR_WIDTH = "245px" 4 | export const LARGE_SIDEBAR_WIDTH = "324px" 5 | -------------------------------------------------------------------------------- /src/util/dom.js: -------------------------------------------------------------------------------- 1 | export function tryToScrollToSelector(selector) { 2 | if (typeof window === "undefined") { 3 | return 4 | } 5 | try { 6 | const element = document.querySelector(selector) 7 | if (!element) { 8 | console.warn("Could not find the element to scroll to.") 9 | return 10 | } 11 | element.scrollIntoView() 12 | } catch (e) { 13 | console.warn("Could not scroll element into view", e) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/util/strings.js: -------------------------------------------------------------------------------- 1 | export function nthIndex(str, pat, n) { 2 | var L = str.length, 3 | i = -1 4 | while (n-- && i++ < L) { 5 | i = str.indexOf(pat, i) 6 | if (i < 0) break 7 | } 8 | return i 9 | } 10 | 11 | export function extractPartNumberFromPath(string) { 12 | // Assumes path is formatted /part-[num] or /part-[num]/... 13 | const subpartSeperator = nthIndex(string, "/", 2) 14 | if (subpartSeperator !== -1) { 15 | string = string.substring(0, subpartSeperator) 16 | } 17 | return parseInt(string.substring(string.indexOf("-") + 1)) 18 | } 19 | 20 | export function extractSubpartNumberFromPath(string) { 21 | // Assumes path is formatted /part-[num]/[num]-... 22 | return parseInt( 23 | string.substring(nthIndex(string, "/", 2) + 1, nthIndex(string, "-", 2)), 24 | ) 25 | } 26 | 27 | export function capitalizeFirstLetter(string) { 28 | return string.charAt(0).toUpperCase() + string.slice(1) 29 | } 30 | 31 | export function removeLeadingZeros(string) { 32 | return string.replace(/^0+/, "") 33 | } 34 | 35 | export function splitGroupNameToWordAndNumber(string) { 36 | return string.split(/(\d+)/) 37 | } 38 | 39 | export function improveGroupName(string) { 40 | var stringParts = splitGroupNameToWordAndNumber(string) 41 | return ( 42 | capitalizeFirstLetter(stringParts[0]) + 43 | " " + 44 | removeLeadingZeros(stringParts[1]) 45 | ) 46 | } 47 | 48 | export function normalizeExerciseId(string) { 49 | return encodeURIComponent( 50 | string 51 | .toLowerCase() 52 | .replace(/ö/g, "o") 53 | .replace(/Ö/g, "O") 54 | .replace(/ä/g, "a") 55 | .replace(/Ä/g, "A") 56 | .replace(/\s+/g, "-") 57 | .replace(/[^A-Za-z0-9_-]/g, "") 58 | .replace(/-+/g, "-"), 59 | ) 60 | } 61 | -------------------------------------------------------------------------------- /src/util/trackHeight.js: -------------------------------------------------------------------------------- 1 | // Used for animations 2 | import { createGlobalStyle } from "styled-components" 3 | 4 | createGlobalStyle` 5 | .render-element-off-screen-for-measurement { 6 | position: absolute !important; 7 | top: -100000px !important; 8 | height: auto !important; 9 | } 10 | ` 11 | 12 | const saveHeight = (element, height) => { 13 | element.style.setProperty("--calculated-height", height) 14 | } 15 | 16 | const calculateElementHeightOffScreen = (element) => { 17 | return new Promise((resolve) => { 18 | element.classList.add("render-element-off-screen-for-measurement") 19 | setTimeout(() => { 20 | const height = element.getBoundingClientRect().height 21 | element.classList.remove("render-element-off-screen-for-measurement") 22 | resolve(height) 23 | }, 100) 24 | }) 25 | } 26 | 27 | const calculateElementHeight = async (element) => { 28 | let { height } = element.getBoundingClientRect() 29 | if (height === 0) { 30 | height = await calculateElementHeightOffScreen(element) 31 | } 32 | saveHeight(element, height) 33 | } 34 | 35 | export const trackElementHeight = (element) => { 36 | if (element === null) { 37 | return 38 | } 39 | element.classList.add("track-element-height-changes-for-animations") 40 | calculateElementHeight(element) 41 | } 42 | 43 | const trackHeight = () => { 44 | window.addEventListener("resize", () => { 45 | document 46 | .querySelectorAll(".track-element-height-changes-for-animations") 47 | .forEach((e) => { 48 | calculateElementHeight(e) 49 | }) 50 | }) 51 | } 52 | 53 | export default trackHeight 54 | -------------------------------------------------------------------------------- /src/util/withSimpleErrorBoundary.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | export default function withSimpleErrorBoundary(Component) { 4 | class SimpleErrorBoundary extends React.Component { 5 | state = { 6 | error: null, 7 | } 8 | 9 | static getDerivedStateFromError(error) { 10 | return { error: error.toString() } 11 | } 12 | 13 | componentDidCatch(error, info) { 14 | console.error(error, info) 15 | } 16 | 17 | render() { 18 | if (this.state.error) { 19 | return ( 20 |
21 | Ohjelman osa kaatui: 22 |
{this.state.error}
23 |
24 | ) 25 | } 26 | 27 | return 28 | } 29 | } 30 | return SimpleErrorBoundary 31 | } 32 | -------------------------------------------------------------------------------- /update.rb: -------------------------------------------------------------------------------- 1 | updates = File.read("updates") 2 | 3 | paths = `find data -name '*.md'`.split("\n") 4 | 5 | paths.each do |path| 6 | input = File.read(path) 7 | 8 | updates.split("\n").each do |line| 9 | split = line.split(" ") 10 | old_id = split[0] 11 | new_id = split[1] 12 | input = input.gsub(old_id, new_id) 13 | end 14 | 15 | File.write(path, input) 16 | end 17 | -------------------------------------------------------------------------------- /use-local-code-states-visualizer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATH_TO_PACKAGE=${1:-"../code-states-visualizer"}; 4 | 5 | 6 | if [ ! -d "$PATH_TO_PACKAGE" ]; then 7 | echo "Given argument '$PATH_TO_PACKAGE' is not a directory" 8 | exit 1 9 | fi 10 | 11 | rm -r ./node_modules/code-states-visualizer; 12 | mkdir ./node_modules/code-states-visualizer; 13 | 14 | if [ ! -d "$PATH_TO_PACKAGE/dist" ]; then 15 | PATH_TO_THIS=$PWD 16 | cd "$PATH_TO_PACKAGE" || exit 1 17 | yarn install 18 | cd "$PATH_TO_THIS" || exit 1 19 | fi 20 | 21 | cp -r "$PATH_TO_PACKAGE/dist" node_modules/code-states-visualizer/dist; 22 | cp "$PATH_TO_PACKAGE/package.json" node_modules/code-states-visualizer/package.json; 23 | cd node_modules/code-states-visualizer || exit 1; 24 | # npm install --prod; 25 | cd ../..; 26 | -------------------------------------------------------------------------------- /use-local-quizzes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PATH_TO_PACKAGE=${1:-"../quizzes/packages/moocfi-quizzes"}; 4 | 5 | 6 | if [ ! -d "$PATH_TO_PACKAGE" ]; then 7 | echo "Given argument '$PATH_TO_PACKAGE' is not a directory" 8 | exit -1 9 | fi 10 | 11 | rm -r ./node_modules/moocfi-quizzes; 12 | mkdir ./node_modules/moocfi-quizzes; 13 | 14 | if [ ! -d "$PATH_TO_PACKAGE/dist" ]; then 15 | PATH_TO_THIS=$PWD 16 | cd $PATH_TO_PACKAGE 17 | yarn install 18 | cd $PATH_TO_THIS 19 | fi 20 | 21 | cp -r $PATH_TO_PACKAGE/dist node_modules/moocfi-quizzes/dist; 22 | cp $PATH_TO_PACKAGE/package.json node_modules/moocfi-quizzes/package.json; 23 | cd node_modules/moocfi-quizzes; 24 | npm install --prod; 25 | cd ../..; 26 | --------------------------------------------------------------------------------