def __init__(self, connue, composite): # on appelle ExerciseFunction.__init__ pour remplir tous les champs # mais self.datasets sera en fait rempli plus tard # une petite clôture.. def target(inconnue): return composite ExerciseFunction.__init__( self, target, None, render_name = False, column_headers = ("inconnue", "composite", "connue + inconnue + connue" ) ) self.connue = connue self.composite = composite
(45_001, 150_000, 40), (150_001, math.inf, 45), ) def taxes_ter(income): due = 0 for floor, ceiling, rate in TaxRate2: due += (min(income, ceiling) - floor + 1) * rate / 100 if income <= ceiling: return int(due) def taxes_ko(income): return (income - 11_500) * 20 / 100 taxes_values = [ 0, 45_000, 11_500, 5_000, 16_500, 30_000, 100_000, 150_000, 200_000, 11_504 ] taxes_inputs = [Args(v) for v in taxes_values] exo_taxes = ExerciseFunction(taxes, taxes_inputs, nb_examples=2) if __name__ == '__main__': for value in taxes_values: tax = taxes(value) print(f"{value} -> {tax}")
# enfin on extrait la racine avec math.sqrt return math.sqrt(sum([x**2 for x in args])) # @END@ # ceci est testé mais je préfère ne pas l'exposer dans les corriges pour l'instant def distance_bis(*args): "idem mais avec une expression génératrice" # on n'a pas encore vu cette forme - cf Semaine 6 # mais pour vous donner un avant-goût d'une expression # génératrice: return math.sqrt(sum((x**2 for x in args))) distance_inputs = [ Args(), Args(1), Args(1, 1), Args(1, 1, 1), Args(1, 1, 1, 1), Args(*range(10)), ] exo_distance = ExerciseFunction(distance, distance_inputs, nb_examples=3) def distance_ko(*args): return sum([x**2 for x in args])
def correction(self, student_diff, extended=extended, abbreviated=abbreviated): self.datasets = [Args(extended, abbreviated).clone('deep')] return ExerciseFunction.correction(self, student_diff)
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args from math import sqrt def isPrime(n): if n==2 or n==3: return True if n%2 == 0 or n<=1: return False d=3 while n%d!=0 and d <= sqrt(n): d+=2 return n%d!=0 inputs_isPrime = [ Args(1), Args(2), Args(3), Args(5), Args(17), Args(1001) ] exo_isPrime = ExerciseFunction( isPrime, inputs_isPrime, layout='pprint', layout_args=(40, 25, 25), )
# si a est impair et b est pair elif a % 2 != 0 and b % 2 == 0: return (a - 1) * b # sinon - c'est que a et b sont impairs else: return a * a - b * b # @END@ def dispatch1_ko(a, b, *args): return a * a + b * b exo_dispatch1 = ExerciseFunction(dispatch1, inputs_dispatch1) #################### samples_A = [(2, 4, 6), [2, 4, 6]] samples_B = [{6, 8, 10}] inputs_dispatch2 = [ Args(a, b, A, B) for a, A in zip(range(3, 5), samples_A) for b in range(7, 10) for B in samples_B ] # @BEG@ name=dispatch2 def dispatch2(a, b, A, B): """ dispatch2 comme spécifié
# @END@ def numbers_ko(liste): return ( # la builtin 'sum' renvoie la somme sum(liste), # les builtin 'min' et 'max' font ce qu'on veut aussi max(liste), min(liste), ) def numbers_input(): length = randint(2, 6) result = [] for i in range(length): result.append(randint(5, 15)) return result numbers_inputs = [Args(), Args(6)] + [Args(*numbers_input()) for i in range(4)] exo_numbers = ExerciseFunction( numbers, numbers_inputs, layout_args=(30, 25, 25), nb_examples=3, )
def correction(self, student_index, bateaux=abbreviated): self.datasets = [Args(bateaux)] return ExerciseFunction.correction(self, student_index)
def correction(self, student_decode_zen): args_obj = Args(this) self.datasets = [ args_obj ] return ExerciseFunction.correction(self, student_decode_zen)
Prend en argument une liste, et retourne la liste modifiée: * taille paire: on intervertit les deux premiers éléments * taille impaire >= 3: on fait tourner les 3 premiers éléments """ # si la liste est de taille 0 ou 1, il n'y a rien à faire if len(liste) < 2: pass # si la liste est de taille paire elif len(liste) % 2 == 0: # on intervertit les deux premiers éléments liste[0], liste[1] = liste[1], liste[0] # si elle est de taille impaire else: liste[-2], liste[-1] = liste[-1], liste[-2] # et on n'oublie pas de retourner la liste dans tous les cas return liste # @END@ def surgery_ko(liste): if len(liste) % 2 == 0: liste[0], liste[1] = liste[1], liste[0] return liste inputs_surgery = [Args(list(range(i))) for i in range(8)] exo_surgery = ExerciseFunction(surgery, inputs_surgery, nb_examples=5)
def correction(self, student_comptage): # call the decorator on the student code return ExerciseFunction.correction( self, exercice_compliant(student_comptage))
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args def calcul(x): resultat = 3 * (x - 2) / 5 return resultat inputs_calcul = [Args(7), Args(0), Args(12), Args(2), Args(-3)] exo_calcul = ExerciseFunction(calcul, inputs_calcul)
def correction(self, inconnue): # dans notre cas il n'y a qu'un seul jeu d'entrées self.datasets = [ Args(inconnue) ] def check(inconnue): return self.connue + inconnue + self.connue return ExerciseFunction.correction(self, check)
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args def minimum(a, b): if a < b: mini = a else: mini = b return mini inputs_minimum = [ Args(3, 8), Args(7, 4), Args(1.264, 1.283), Args(-3, -1), Args(2, 2) ] exo_minimum = ExerciseFunction(minimum, inputs_minimum)
def alternat(l1, l2): "renvoie une liste des éléments pris un sur deux dans l1 et dans l2" # pour réaliser l'alternance on peut combiner zip avec aplatir # telle qu'on vient de la réaliser return aplatir(zip(l1, l2)) # @END@ # @BEG@ name=alternat more=bis def alternat_bis(l1, l2): "une deuxième version de alternat" # la même idée mais directement, sans utiliser aplatir return [element for conteneur in zip(l1, l2) for element in conteneur] # @END@ alternat_inputs = [ Args((1, 2), ('a', 'b')), Args((1, 2, 3), ('a', 'b', 'c')), Args((1, (2, 3)), ('a', ['b', 'c'])), ] exo_alternat = ExerciseFunction(alternat, alternat_inputs, nb_examples=2) def alternat_ko(l1, l2): return l1 + l2
args("".join(random.sample(alphabet, random.randint(3, 6))), "".join(random.sample(alphabet, random.randint(5, 8)))) for i in range(4) ] # @BEG@ name=inconnue # pour enlever à gauche et à droite une chaine de longueur x # on peut faire composite[ x : -x ] # or ici x vaut len(connue) def inconnue(composite, connue): return composite[len(connue):-len(connue)] # @END@ # @BEG@ name=inconnue more=bis # ce qui peut aussi s'écrire comme ceci si on préfère def inconnue_bis(composite, connue): return composite[len(connue):len(composite) - len(connue)] # @END@ exo_inconnue = ExerciseFunction(inconnue, inconnue_inputs) def inconnue_ko(big, small): return big[len(small):-4]
def fact(n): "une version de factoriel à base de reduce" return reduce(mul, range(1, n + 1), 1) from math import factorial fact_inputs = [0, 1, 5] compare_all_inputs.append(Args(fact, factorial, fact_inputs)) def broken_fact(n): return 0 if n <= 0 \ else 1 if n == 1 \ else n*fact(n-1) compare_all_inputs.append(Args(broken_fact, factorial, fact_inputs)) #################### the exercice instance exo_compare_all = ExerciseFunction(compare_all, compare_all_inputs, nb_examples=2, call_layout='truncate', layout_args=(50, 8, 8)) def compare_all_ko(*args): return [not x for x in compare_all(*args)]
first = args[0] remains = args[1:] return func(2 * first, *remains) # @END@ doubler_premier_inputs = [] from operator import add from operator import mul from .exo_distance import distance # pour l'exemple on choisit les 3 premiers inputs # avec des fonctions différentes for i in (1, 3, 5): doubler_premier_inputs.append(Args(add, i, 4)) doubler_premier_inputs.append(Args(mul, i, 4)) doubler_premier_inputs.insert(2, Args(distance, 1.5, 4.)) doubler_premier_inputs.insert(3, Args(distance, 2.0, 4., 4., 4.)) exo_doubler_premier = ExerciseFunction(doubler_premier, doubler_premier_inputs, nb_examples=4, render_name=False, layout_args=(40, 10, 10), call_layout='truncate') def doubler_premier_ko(f, first, *args): return f(3 * first, *args)
# @BEG@ name=carre more=bis def carre_bis(line): # pareil mais avec, à la place des compréhensions # des expressions génératrices que - rassurez-vous - # l'on n'a pas vues encore, on en parlera en semaine 5 # le point que je veux illustrer ici c'est que c'est # exactement le même code mais avec () au lieu de [] line = line.replace(' ', '').replace('\t', '') entiers = (int(token) for token in line.split(";") if token) return ":".join(str(entier**2) for entier in entiers) # @END@ inputs_carre = [ Args("1;2;3"), Args(" 2 ; 5;6;"), Args("; 12 ; -23;\t60; 1\t"), Args("; -12 ; ; -23; 1 ;;\t"), ] exo_carre = ExerciseFunction(carre, inputs_carre, nb_examples=0, layout_args=(40, 20, 20)) def carre_ko(s): return ":".join(str(i**2) for i in (int(token) for token in s.split(';')))
########## step 2 # You need to provide datasets< # This is expected to be a list of Args instances # each one describes all the arguments to be passed # to the function # in this particular case we define 2 input sets, so # the correction will have 2 meaningful rows inputs_percentages = [ Args('ACGTACGA'), Args('ACGTACGATCGATCGATGCTCGTTGCTCGTAGCGCT'), ] ########## step 3 # finally we create the exercise object # NOTE on names: # # this is the only name that should be imported from this module exo_percentages = ExerciseFunction( # first argument is the 'correct' function # it is recommended to use the same name as in the notebook, as the # python function name is used in HTML rendering percentages, # the inputs inputs_percentages, # various tweaks on how to display input arguments layout='pprint', # in particular here, the widths of the first 3 columns in the correction table layout_args=(40, 25, 25), )
# @END@ # @BEG@ name=morceaux more=ter # on peut aussi faire des tests d'intervalle # comme ceci 0 <= x <= 10 def morceaux_ter(x): if x <= -5: return -x - 5 elif -5 <= x <= 5: return 0 else: return x / 5 - 1 # @END@ inputs_morceaux = [Args(x) for x in (-10, 0, 10, -6, -5, -4, 4, 5, 20)] exo_morceaux = ExerciseFunction( morceaux, inputs_morceaux, nb_examples=3, ) def morceaux_ko(x): return morceaux(x) if x <= 15 else x
def fact(n): "une version de factoriel à base de reduce" return reduce(mul, range(1, n + 1), 1) compare_args_inputs.append(Args(fact, factorial, fact_inputs)) ########## dataset #4 def plus(x1, x2): return x1 + x2 compare_args_inputs.append(Args(add, plus, add_inputs)) #################### the exercise instance exo_compare_args = ExerciseFunction( compare_args, compare_args_inputs, call_layout='truncate', layout_args=(50, 8, 8), render_name=False, nb_examples=2, ) def compare_args_ko(*args, **keywords): return [not x for x in compare_args(*args, **keywords)]
# on peut aussi faire tout simplement comme ça # sans faire de if du tout return a % b == 0 or b % a == 0 # @END@ def divisible_ko(a, b): return a % b == 0 inputs_divisible = [ Args(10, 30), Args(10, -30), Args(-10, 30), Args(-10, -30), Args(8, 12), Args(12, -8), Args(-12, 8), Args(-12, -8), Args(10, 1), Args(30, 10), Args(30, -10), Args(-30, 10), Args(-30, -10), ] exo_divisible = ExerciseFunction( divisible, inputs_divisible )
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args # @BEG@ name=npmodif def npmodif(n, a, b): '''on va créer une arange(n) et transformer en leurs opposés les termes d'indices compris entre a et b. La fonction retourne le tableau np modifié''' import numpy as np Z = np.arange(n) Z[(a < Z) & (Z <= b)] *= -1 return list(Z) # @END@ inputs_npmodif = [ Args(10, 3, 5), Args(10, 2, 8), Args(5, 1, 3), Args(15, 10, 14), ] exo_npmodif = ExerciseFunction(npmodif, inputs_npmodif)
from math import sqrt #------------ # Fonction solution du probleme def __estPair(n): return n % 2 == 0 # Jeu de donnees sur lequel la fonction de l'eleve sera testee inputs_estPair = [Args(1), Args(2), Args(3), Args(8), Args(17), Args(1001)] # Fabrication de l'instance pour l'autoevaluation sol_estPair = ExerciseFunction( __estPair, # La fonction solution du probleme inputs_estPair, # Le jeu de donnees ) #------------ # Fonction solution du probleme def __carre(x): return x**2 # Jeu de donnees sur lequel la fonction de l'eleve sera testee inputs_carre = [Args(-2), Args(0), Args(1), Args(1.5), Args(17)] # Fabrication de l'instance pour l'autoevaluation sol_carre = ExerciseFunction(
Args(''), Args('abc'), Args('abc \t'), Args(' \tabc \n'), Args('a b c d e f g h i j k l m n o p q r s t u v w x y z\n'), Args('''The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! '''), ) exo_wc = ExerciseFunction(wc, wc_input, layout_args=(80, 15, 15))
# ... iterable[i] def produit_scalaire_ter(X, Y): scalaire = 0 n = len(X) for i in range(n): scalaire += X[i] * Y[i] return scalaire # @END@ from fractions import Fraction inputs_produit_scalaire = [ Args((1, 2), (3, 4)), Args(range(3, 9), range(5, 11)), Args([-2, 10], [20, 4]), Args([Fraction(2, 15), Fraction(3, 4)], [Fraction(-7, 19), Fraction(4, 13)]), Args([], []), ] exo_produit_scalaire = ExerciseFunction( produit_scalaire, inputs_produit_scalaire, ) def produit_scalaire_ko(X, Y): return [x * y for x, y in zip(X, Y)]
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args def difference(a, b): resultat = b - a return resultat inputs_difference = [Args(3, 7), Args(6, 2), Args(4, 4), Args(-5, 1)] exo_difference = ExerciseFunction(difference, inputs_difference)
a, b = b, a % b return a # @END@ def pgcd_ko(a, b): return a % b inputs_pgcd = [ Args(0, 0), Args(0, 1), Args(1, 0), Args(15, 10), Args(10, 15), Args(3, 10), Args(10, 3), Args(10, 1), Args(1, 10), ] inputs_pgcd += [ Args(36 * 2**i * 3**j * 5**k, 36 * 2**j * 3**k * 5**i) for i in range(3) for j in range(3) for k in range(2) ] exo_pgcd = ExerciseFunction( pgcd, inputs_pgcd, nb_examples = 6, )
liste.sort(reverse=reverse) # on retourne la liste de départ return listes # @END@ def multi_tri_reverse_ko(listes, reverses): for liste in listes: liste.sort() return listes inputs_multi_tri_reverse = [ Args([[1, 2], [3, 4]], [True, False]), Args([[1, 2], [3, 4]], (True, True)), Args([[1, 3, 2], [3, 4]], [False, True]), Args([[1, 2], [3, 5, 4]], [False, False]), Args([[1, 3], [9, 5], [4, 2]], (True, False, True)), Args( [[], ['a', 'z', 'c']], [False, True], ), ] exo_multi_tri_reverse = ExerciseFunction(multi_tri_reverse, inputs_multi_tri_reverse, layout_args=(24, 24, 24), nb_examples=2)
# -*- coding: utf-8 -*- from nbautoeval.exercise_function import ExerciseFunction from nbautoeval.args import Args def seuilSomme(seuil): m = 150 n = 0 while m <= seuil: m = m + 3 n = n + 1 return n inputs_seuilSomme = [Args(1000), Args(2000), Args(150), Args(3000)] exo_seuilSomme = ExerciseFunction(seuilSomme, inputs_seuilSomme) def seuilProduit(seuil): m = 150 n = 0 while m <= seuil: m = m * 2 n = n + 1 return n inputs_seuilProduit = [Args(7000), Args(100000), Args(150), Args(4800)] exo_seuilProduit = ExerciseFunction(seuilProduit, inputs_seuilProduit)
Args('nat2018_r300.csv', 1043), Args('nat2018_r300.csv', 2011), Args('nat2018_n20.csv', 30082) ] inputs_averages = [ Args('nat2018_epured_5k.csv', 1045), Args('nat2018_r300.csv', 24), Args('nat2018_n20.csv', 58), Args('nat2018_epured_5k.csv', 386), Args('nat2018_epured_5k.csv', 1136), Args('nat2018_r300.csv', 1000), Args('nat2018_r300.csv', 2011), Args('nat2018_n20.csv', 1691) ] # Fonctions de correction exo_import_donnee = ExerciseFunction( verifier_donnees, inputs_import, layout='pprint', layout_args=(40, 40, 40) ) exo_calcul_moyennes = ExerciseFunction( verifier_aver_ages, inputs_averages, layout='pprint', layout_args=(40, 40, 40) )
def correction(self, student_merge, extended=extended, abbreviated=abbreviated): self.datasets = [Args(extended, abbreviated)] return ExerciseFunction.correction(self, student_merge)