Skip to content

Commit

Permalink
add TP6Ex2 + delete __pycache__ file in TP4EX8Supp
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreFiset001 committed Jul 5, 2019
1 parent 55219b0 commit 791542c
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 0 deletions.
Binary file removed TP4Ex8Supp/src/__pycache__/CorrQ.cpython-36.pyc
Binary file not shown.
190 changes: 190 additions & 0 deletions TP6Ex2/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#! /usr/bin/python3
# -*- coding: utf-8 -*-

import subprocess
import gettext
import shlex
import sys
import os
import re

from inginious import feedback
from inginious import rst
from inginious import input


# This runner suits for typical exercises of LSINF1101/FSAB1401
# Should be adapted if used in another occasion
# Structure used:
# -One folder : src with a proposer answer, the tests and a subdirectory containing the templates
# -A run file
# -A task file
# Note that beside this structure we use the global folder common (c) and common/student (cs) containing:
# -The compiler script (c)
# -The tests runner script (c)
# -The translations folder (cs)

def init_translations():
"""
Move the translations files to student directory
Initialize gettext and translate to the proper language
"""
lang = input.get_lang()
try:
trad = gettext.GNUTranslations(open("../course/common/student/$i18n/" + lang + ".mo", "rb"))
except FileNotFoundError:
trad = gettext.NullTranslations()
trad.install()
return lang


def compute_code():
"""
Fills the template file with the student answer
Returns the task's number of questions
"""
for file in os.listdir('./src/Templates'):
input.parse_template('./src/Templates/' + file, './student/' + file + '.py')
data = input.load_input()
return len([k for k in data['input'].keys() if '@' not in k])


def compile_code():
"""
Compiles both the student code and the exercise code
Provides feedback if there is any compilation error
"""
pyc_cmd = "python3 ../course/common/compiler.py "

with open('log.out', 'w+', encoding="utf-8") as f:
subprocess.call(shlex.split(pyc_cmd + './student/'), universal_newlines=True, stderr=f)
f.seek(0)
out_student = f.read()

if out_student != "":
rawhtml = rst.get_codeblock("", out_student)
feedback.set_global_result('failed')
feedback.set_global_feedback(_("Your program does not compile: \n ") + rawhtml + "\n")
sys.exit(0)

with open('logTests.out', 'w+', encoding="utf-8") as f:
subprocess.call(shlex.split(pyc_cmd + './src/'), universal_newlines=True, stderr=f)
f.seek(0)
out_tests = f.read()

if out_tests != "":
rawhtml = rst.get_codeblock("", out_tests)
feedback.set_global_result('failed')
feedback.set_global_feedback(_("The program does not compile for external reasons,"
"please contact an administrator asap: \n ") + rawhtml + "\n")
sys.exit(0)

with open('logRunner.out', 'w+', encoding="utf-8") as f:
subprocess.call(shlex.split(pyc_cmd + '../course/common/'), universal_newlines=True, stderr=f)
f.seek(0)
out_runner = f.read()

if out_runner != "":
rawhtml = rst.get_codeblock("", out_runner)
feedback.set_global_result('failed')
feedback.set_global_feedback(_("The program does not compile for external reasons,"
"please contact an administrator asap: \n ") + rawhtml + "\n")
sys.exit(0)


def cleanup_output(error_content):
"""
Provides a cleaner output from the error trace
:param error_content: string returned by the unittest failures
"""
cleaned_lines = []
indexes = [match.start() for match in re.finditer('AssertionError: ', error_content)]
for i in indexes:
cleaned_lines.append(_('Failed test:\n'))
cleaned_lines.append(error_content[i + len("AssertionError: "): error_content.find("=" * 70, i)])
return ''.join(cleaned_lines) if len(indexes) > 0 else error_content


def run_code(n_exercises, lang):
"""
Runs the student code with the tests
Provides feedback if it contains errors
:param n_exercises: the task's number of exercices
:param lang: the language used by the user
"""
with open('err.txt', 'w+', encoding="utf-8") as f:
os.chdir('./student')
py_cmd = "run_student python3 Runner.pyc " + lang
try:
resproc = subprocess.Popen(shlex.split(py_cmd), universal_newlines=True, stderr=f, stdout=subprocess.PIPE)
resproc.communicate()
result = resproc.returncode
except (IOError, BrokenPipeError):
result = 252
f.flush()
f.seek(0)
errors = f.read()
print(errors)
outerr = rst.get_codeblock("python", cleanup_output(errors))

# expected error code: 252=outofmemory, 253=timedout
# 127 = code returned by our runner
grade=0
if result == 127:
feedback.set_global_result('success')
elif result == 252:
feedback.set_global_result('overflow')
elif result == 253:
feedback.set_global_result('timeout')
else: # Tests failed
if n_exercises == 1:
feedback.set_global_result('failed')
feedback.set_global_feedback(_("It seems that you have made mistakes in your code…\n\n") + outerr + "\n")
else:
sub_found = False
for i in range(1, n_exercises + 1):
regex = '@' + str(i) + '@: ((.+)(\n|\r){1})+'
regex_question = re.search(regex, errors)
if regex_question:
sub_found = True
break
if not sub_found:
feedback.set_global_result('failed')
feedback.set_global_feedback(_("custom…\n\n") + outerr + "\n")
return
sub_found = False
for i in range(0, n_exercises + 1):
regex = '@' + str(i) + '@: ((.+)(\n|\r){1})+'
regex_question = re.search(regex, errors)
if regex_question:
outerr_question = re.sub('"', '', regex_question.group(0)[5:])
sub_found = True
else:
outerr_question = False

if i == 0:
feedback.set_global_result('failed')
if outerr_question:
feed = _("You have made mistakes: \n\n") + rst.get_codeblock("python", outerr_question) + "\n"
feedback.set_global_feedback(feed)
else:
if outerr_question:
feed = _("You have made mistakes: \n\n") + rst.get_codeblock("python", outerr_question) + "\n"
feedback.set_problem_feedback(feed, "q" + str(i))
else:
feedback.set_problem_feedback(_("You answered well this question"), "q" + str(i))
feedback.set_problem_result('success', "q" + str(i))
grade+=1
if not sub_found:
feedback.set_global_result('failed')
feedback.set_global_feedback(_("It seems that you have made mistakes in your code…\n\n") + outerr + "\n")
else:
feedback.set_grade(grade*100/n_exercises)

if __name__ == '__main__':
language = init_translations()
num_exercises = compute_code()
compile_code()
run_code(num_exercises, language)
6 changes: 6 additions & 0 deletions TP6Ex2/src/CorrQ.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-


def tempete(M):
return [sum([1 if (M[i][0] > 90 and M[i][1] > 10 ) else 0 for i in range(24)])] + [round(sum([M[i][0]/24 for i in range(24)]),2)] + [round(sum([M[i][1]/24 for i in range(24)]),2)]
3 changes: 3 additions & 0 deletions TP6Ex2/src/Templates/q
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
@@q1@@
25 changes: 25 additions & 0 deletions TP6Ex2/src/TestQ.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-


import unittest
import q
import CorrQ as corr
import random

#Creation of the random matrix M
M = [[random.randint(80,101),random.randint(0,21)] for i in range(24)]


class TestPageRank(unittest.TestCase):

def test_exist_inverse(self):
self.assertTrue(hasattr(q, 'tempete'), _("You did not name the method as expected."))

def test_inverse(self):
stud_ans = q.tempete(M)
corr_ans = corr.tempete(M)
self.assertEqual(stud_ans,corr_ans,_("You did not return the rigth result for the matrix \n M = {} \n Your result : \n ans = {} \n The expected result : \n ans = {} ").format(M,stud_ans,corr_ans))

if __name__ == '__main__':
unittest.main()
52 changes: 52 additions & 0 deletions TP6Ex2/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
accessible: true
author: Alexandre Fiset
context: |-
L’institut météo a enregistré la vitesse moyenne du vent et le niveau de précipitations au cours de la journée dans un tableau de nombres réels à deux dimensions, ``M``. Il s’agit donc d’une matrice 24 x 2. L’indice de ligne correspond à l’heure de la journée (de 0 à 23), la première colonne contient la vitesse du vent (en km/h) et la seconde colonne contient le niveau de précipitations (en cm de pluie par mètre carré et par heure) durant cette heure.
L’institut considère qu’il y a tempête lorsque, à la fois, la vitesse du vent excède 90 km/h et que le niveau de précipitations excède 10 cm. A partir de ces données, nous vous demandons d’écrire une méthode qui, à partir du tableau M, calcule:
1. Le nombre d’heures de tempête durant la journée de 24 heures.
2. La vitesse moyenne du vent durant ces heures de tempête ( arrondi à deux décimales ).
3. Le niveau moyen de précipitations durant ces heures de tempête (arrondi à deux décimales ).
Ces trois informations seront mémorisées dans un tableau de nombres réels de longueur 3 qui sera renvoyé par la méthode
Par exemple pour la matrice :
.. code-block:: python
M = [[91, 5], [94, 1], [100, 14], [92, 1], [86, 20], [86, 9], [94, 16], [85, 16], [80, 6], [92, 14], [93, 18], [99, 5], [82, 17], [83, 3], [101, 12], [96, 14], [80, 4], [90, 3], [80, 6], [81, 12], [94, 21], [84, 19], [99, 0], [80, 16]]
Votre code doit retourner :
.. code-block:: python
ans = [7, 89.25, 10.5]
Pour arrondir des nombre flottant vous pouvez vous aider de ``round(f,n)`` où ``f`` est le nombre flotant à arrondir et ``n`` le nombre de décimales à garder.
environment: default
evaluate: best
groups: false
input_random: '0'
limits:
time: '30'
memory: '100'
output: '2'
name: TP6 Exercice 2
network_grading: false
problems:
q1:
default: ''
type: code
language: python
header: Implementer la methode ``def tempete(M)``
name: Implémentation
stored_submissions: 0
submission_limit:
amount: -1
period: -1
tags: {}
weight: 1.0

0 comments on commit 791542c

Please sign in to comment.