Please ignore secret bonuses. Secret tests do NOT award bonus. Max hw grade is 30+2 bonus efficiency

Do you need help?

Notice Board

Per partecipare al corso di Fondamenti di programmazione 2023-24 loggatevi e attivatelo nella vostra pagina dei corsi preferiti. A quel punto il corso appare nel menù personale cliccando sul proprio avatar. Per i materiali degli anni precedenti seguite lo stesso metodo.

To join the Programming/Lab 2023-24 course, log-on and select it on the my courses page. It will appear on the personal menu of your avatar. For earlier years use the same method.

[AVVISO] Test sulla ricorsione. Evitate funzioni nidificate o metodi statici.

andrea.sterbini (207940 points)
756 1270 2377
in Avvisi by (208k points)
edited by

Ho aggiunto ai miei test  una verifica automatica che le funzioni ed i metodi degli esercizi siano ricorsivi o chiamino una funzione o metodo ricorsivo.

I test sembrano funzionare bene tranne per le funzioni dichiarate dentro funzioni o i metodi statici, che ho difficoltà a controllare automaticamente, per cui il codice in questi casi fallisce i test. Vi consiglio quindi di spostare le funzioni ricorsive a livello globale oppure come metodi normali (non statici). 

I test della ricorsione pesano 3 (rispetto ai test funzionali che pesano 1), verranno aggiunti (e pubblicati) altri test funzionali in modo da estendere la casistica controllata e da equilibrare il punteggio delle due parti.

BTW: ... Don't Panic ....

1 Answer

P
Powner (5600 points)
36 68 85
by (5.6k points)
Scusi potrebbe chiarire cosa significa "spostare le funzioni ricorsive a livello globale" e quale sia la differenza tra metodo statico e normale?
l
ldifuccia (720 points)
1 4 11
by (720 points)
Un metodo statico è un metodo intrinseco della classe e non dell'istanza creata dalla classe.
Provo a spiegarmi meglio:

quando creo una classe MyClass, definisco il costruttore __init__ chiamato ogniqualvolta creo un oggetto (o istanza) di tale classe e tutte le relative funzioni (o metodi):

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def print_coord(self):
        print(self.x, self.y)

Il metodo print_coord non riceve nessun argomento se non il "self". Quindi vuol dire che per poterla usare dovrò prima inizializzare un'istanza e poi richiamare la funzione:
>>> MyClass(10, 20).print_coord()
10 20

Se provassi a richiamare tale funzione senza prima inizializzare un oggetto, non avrei più il self e quindi riceverei questo errore:
TypeError: unbound method print_coord() must be called with MyClass instance as first argument (got nothing instead)

Esistono però dei metodi che non per forza devono ricevere il self come primo argomento e che quindi possono essere richiamati senza dover prima inizializzare un'istanza di tale classe. Riprendendo l'esempio di prima potrei definire il seguente metodo statico (tramite decoratori @xxxxxxx - https://goo.gl/uMC5dC):

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def print_coord(self):
        print(self.x, self.y)

    @staticmethod
    def print_hello(name):
        print("Hello %s!!!" % name)

Questo metodo può essere richiamato così (non viene richiamato il metodo __init__):
>>> MyClass.print_hello("Powner")
Hello Powner!!!

Magari loro te lo sapranno spiegare meglio:
https://stackoverflow.com/questions/12179271/meaning-of-classmethod-and-staticmethod-for-beginner

Visto che questi metodi statici non sono collegati al self (quindi ad un'istanza della classe), possono essere definiti come semplici funzioni "globali", esterne alla classe:

def print_hello(name):
    print("Hello %s!!!" % name)

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def print_coord(self):
        print(self.x, self.y)

>>> MyClass(10, 20).print_coord()
10 20
>>> print_hello("Powner")
Hello Powner!!!
Luca T. (5410 points)
3 20 38
by (5.4k points)
Ma quindi per fare in modo che il grader riconosca che ho usato una funzione ricorsiva mi basta definirla fuori dalla classe? Credo di non aver capito, perché al primo esercizio il grader mi assegna un punteggio di 12 (con 12/12 test andati a buon fine). Premetto di non aver usato delle classi, ma solo i dizionari. Per ognuna delle 4 funzioni ho richiamato all'interno una funzione ricorsiva che genera i dizionari, però non viene riconosciuta tale dal grader. Ho capito male io? O per adesso mi conviene usare classi?
P
Powner (5600 points)
36 68 85
by (5.6k points)
Quindi, vediamo se ho capito bene: se nell'es.2 ad esempio il mio metodo esiti non è direttamente ricorsivo, mi basta mettere la funzione ricorsiva a cui si "appoggia" fuori dalla classe, e fine?
Ma nel caso invece dell'es. 1? Se oltre le quattro funzioni che richiama il grader ci sono altrettante funzioni ricorsive? (stessa cosa di Luca T.)