diff --git a/db/seeds/turtle/default.pylintrc b/db/seeds/turtle/default.pylintrc new file mode 100644 index 000000000..308be6969 --- /dev/null +++ b/db/seeds/turtle/default.pylintrc @@ -0,0 +1,7 @@ +[MASTER] + +[MESSAGES CONTROL] + +[REPORTS] + +[BASIC] diff --git a/db/seeds/turtle/main.py b/db/seeds/turtle/main.py new file mode 100644 index 000000000..e77c3c2c9 --- /dev/null +++ b/db/seeds/turtle/main.py @@ -0,0 +1,75 @@ +# This example is based on content from the 2020 openHPI course +# "Programmieren lernen mit Python" ("Learning to Program with Python") +# Authors: Kira Grammel, Nina Ihde, Selina Reinhard, and Sebastian Serth +# Published by: openHPI, Hasso-Plattner-Institut für Digital Engineering gGmbH +# License: CC BY-NC-SA 4.0, https://creativecommons.org/licenses/by-nc-sa/4.0 +# +# The course is freely available at: https://open.hpi.de/courses/pythonjunior2020 + +from turtle import * + +def erstelle_turtle(x, y, rotationsWinkel = 0, shape = "triangle", color = "green"): + steuerung = Turtle() + steuerung.speed(0) # schnellste Animationsgeschwindigkeit, um sichtbare Bewegung zu vermeiden + steuerung.shape(shape) + steuerung.color(color) + steuerung.right(rotationsWinkel) + steuerung.penup() + steuerung.goto(x, y) + steuerung.direction = "stop" # nur für Kopf relevant + return steuerung + +rechts = erstelle_turtle(180, -160) +unten = erstelle_turtle(160, -180, 90) +links = erstelle_turtle(140, -160, 180) +oben = erstelle_turtle(160, -140, 270) +kopf = erstelle_turtle(0, 0, 0, "square", "black") + +def setze_richtung(dahin, dahinNicht): + # Vermeiden, dass Schlangenkopf zurück in sich selbst laufen kann + if kopf.direction != dahinNicht: + kopf.direction = dahin + kopf_bewegen() + +def kopf_bewegen(): + if kopf.direction == "down": + y = kopf.ycor() + kopf.sety(y - 20) + + elif kopf.direction == "right": + x = kopf.xcor() + kopf.setx(x + 20) + + elif kopf.direction == "up": + y = kopf.ycor() + kopf.sety(y + 20) + + elif kopf.direction == "left": + x = kopf.xcor() + kopf.setx(x - 20) + + +def checke_kollision_mit_fensterrand(): + if kopf.xcor() > 190 or kopf.xcor() < -190 or kopf.ycor() > 190 or kopf.ycor() < -190: + spiel_neustarten() + + +def interpretiere_eingabe(x, y): + if (x >= 170 and x <= 190 and y >= -170 and y <= -150): + setze_richtung("right", "left") + elif (x >= 150 and x <= 170 and y >= -190 and y <= -170): + setze_richtung("down", "up") + elif (x >= 130 and x <= 150 and y >= -170 and y <= -150): + setze_richtung("left", "right") + elif (x >= 150 and x <= 170 and y >= -150 and y <= -130): + setze_richtung("up", "down") + else: + return None + checke_kollision_mit_fensterrand() + +def spiel_neustarten(): + kopf.goto(0, 0) + kopf.direction = "stop" + +onclick(interpretiere_eingabe) +mainloop() diff --git a/db/seeds/turtle/test_style.py b/db/seeds/turtle/test_style.py new file mode 100644 index 000000000..35507c159 --- /dev/null +++ b/db/seeds/turtle/test_style.py @@ -0,0 +1,7 @@ +from pylint import epylint as lint +import glob + +pylint_opts = ['--rcfile=default.pylintrc'] +exercise = glob.glob('main.py')[0] +lint.lint(exercise, options=pylint_opts) +exit() diff --git a/spec/factories/execution_environment.rb b/spec/factories/execution_environment.rb index 7724397b9..18d07b0de 100644 --- a/spec/factories/execution_environment.rb +++ b/spec/factories/execution_environment.rb @@ -73,18 +73,18 @@ created_by_teacher default_memory_limit default_cpu_limit - docker_image { 'openhpi/co_execenv_python:3.4' } + docker_image { 'openhpi/co_execenv_python:3.8' } file_type { association :dot_py, user: } help - name { 'Python 3.4' } + name { 'Python 3.8' } network_enabled { false } privileged_execution { false } permitted_execution_time { 10.seconds } pool_size { 0 } - run_command { 'python3 %{filename}' } + run_command { 'python3 -B /usr/lib/python3.8/webpython.py -f %{filename}' } singleton_execution_environment test_command { 'python3 -m unittest --verbose %{module_name}' } - testing_framework { 'PyUnitAdapter' } + testing_framework { 'PyUnitAndPyLintAdapter' } end factory :ruby, class: 'ExecutionEnvironment' do diff --git a/spec/factories/exercise.rb b/spec/factories/exercise.rb index f04daff68..fe23031fb 100644 --- a/spec/factories/exercise.rb +++ b/spec/factories/exercise.rb @@ -75,6 +75,20 @@ def create_seed_file(exercise, path, file_attributes = {}) end end + factory :turtle, class: 'Exercise' do + created_by_teacher + description { 'Interactive Turtle test exercise.' } + execution_environment { association :python, user: } + instructions + title { 'Interactive Turtle' } + + after(:create) do |exercise| + create_seed_file(exercise, 'turtle/main.py', role: 'main_file') + create_seed_file(exercise, 'turtle/test_style.py', feedback_message: 'Your solution is not correctly formated.', hidden: true, role: 'teacher_defined_linter') + create_seed_file(exercise, 'turtle/default.pylintrc', hidden: true, role: 'regular_file') + end + end + factory :fibonacci, class: 'Exercise' do created_by_teacher description { 'Implement a recursive function that calculates a requested Fibonacci number.' } diff --git a/spec/factories/file_type.rb b/spec/factories/file_type.rb index 7001bcac9..c1bd59e1a 100644 --- a/spec/factories/file_type.rb +++ b/spec/factories/file_type.rb @@ -124,6 +124,15 @@ singleton_file_type end + factory :dot_pylintrc, class: 'FileType' do + created_by_admin + editor_mode { 'ace/mode/ini' } + file_extension { '.pylintrc' } + indent_size { 4 } + name { 'Pylintrc' } + singleton_file_type + end + factory :dot_rb, class: 'FileType' do created_by_admin editor_mode { 'ace/mode/ruby' } diff --git a/spec/services/proforma_service/convert_task_to_exercise_spec.rb b/spec/services/proforma_service/convert_task_to_exercise_spec.rb index f60cea59b..89bca4099 100644 --- a/spec/services/proforma_service/convert_task_to_exercise_spec.rb +++ b/spec/services/proforma_service/convert_task_to_exercise_spec.rb @@ -32,7 +32,7 @@ ProformaXML::Task.new( title: 'title', description:, - proglang: {name: 'python', version: '3.4'}, + proglang: {name: 'python', version: '3.8'}, uuid: 'uuid', parent_uuid: 'parent_uuid', language: 'language', @@ -146,7 +146,7 @@ before { create(:python) } it 'sets the execution_environment based on proglang name and value' do - expect(convert_to_exercise_service).to have_attributes(execution_environment: have_attributes(name: 'Python 3.4')) + expect(convert_to_exercise_service).to have_attributes(execution_environment: have_attributes(name: 'Python 3.8')) end end