]> git.llucax.com Git - software/sercom.git/blobdiff - sercom/model.py
Ordenar mejor ejercicios.
[software/sercom.git] / sercom / model.py
index 5e6ec2a1b9d90a0baf4ce7b692733618468b8c37..a8670824a4577d9e5a78aa09865217329ee131c0 100644 (file)
@@ -281,8 +281,6 @@ class Tarea(InheritableSQLObject): #{{{
     nombre              = UnicodeCol(length=30, alternateID=True)
     # Campos
     descripcion         = UnicodeCol(length=255, default=None)
-    terminar_si_falla   = BoolCol(notNone=True, default=True)
-    rechazar_si_falla   = BoolCol(notNone=True, default=True)
     # Joins
     enunciados          = RelatedJoin('Enunciado', addRemoveName='_enunciado')
 
@@ -314,8 +312,8 @@ class TareaPrueba(Tarea): #{{{
     # Joins
     comandos    = MultipleJoin('ComandoPrueba', joinColumn='tarea_id')
 
-    def add_comando(self, orden, **kw):
-        return ComandoPrueba(tarea=self, orden=orden, comando='', **kw)
+    def add_comando(self, orden, comando='', **kw):
+        return ComandoPrueba(tarea=self, orden=orden, comando=comando, **kw)
 
     def remove_comando(self, orden):
         ComandoPrueba.pk.get(self.id, orden).destroySelf()
@@ -347,13 +345,27 @@ class Comando(InheritableSQLObject): #{{{
     max_locks_memoria   = IntCol(default=None)
     terminar_si_falla   = BoolCol(notNone=True, default=True)
     rechazar_si_falla   = BoolCol(notNone=True, default=True)
+    publico             = BoolCol(notNone=True, default=True)
     archivos_entrada    = BLOBCol(default=None) # ZIP con archivos de entrada
                                                 # __stdin__ es caso especial
+                                                # Si un caso de prueba tiene
+                                                # comandos que tiene algún
+                                                # archivo de entrada (incluyendo
+                                                # stdin) con los propios, se usa
+                                                # el archivo del caso de prueba,
+                                                # no del comando.
     archivos_a_comparar = BLOBCol(default=None) # ZIP con archivos de salida
                                                 # __stdout__, __stderr__ y
                                                 # __stdouterr__ (ambos juntos)
                                                 # son casos especiales
-    archivos_a_guardar  = TupleCol(notNone=True, default=()) # TODO SetCol
+                                                # Si un caso de prueba tiene
+                                                # comandos que tiene algún
+                                                # archivo a comparar (incluyendo
+                                                # stdout/err) con los propios,
+                                                # se compara contra el archivo
+                                                # del caso de prueba, no del
+                                                # comando.
+    archivos_a_guardar  = TupleCol(notNone=True, default=()) # TODO FrozenSetCol
                                                 # __stdout__, __stderr__ y
                                                 # __stdouterr__ (ambos juntos)
                                                 # son casos especiales
@@ -392,7 +404,7 @@ class ComandoFuente(Comando): #{{{
 
 class ComandoPrueba(Comando): #{{{
     _inheritable = False
-    RET_PRUEBA = -2 # Espera el mismo retorno que el de la prueba.
+    RET_PRUEBA = -257 # Espera el mismo retorno que el de la prueba.
     # XXX todos los campos de limitación en este caso son multiplicadores para
     # los valores del caso de prueba.
     # Clave
@@ -401,7 +413,7 @@ class ComandoPrueba(Comando): #{{{
     pk                  = DatabaseIndex(tarea, orden, unique=True)
 
     def __repr__(self):
-        return super(ComandoFuente, self).__repr__('tarea=%s, orden=%s'
+        return super(ComandoPrueba, self).__repr__('tarea=%s, orden=%s'
             % (self.tarea.shortrepr(), self.orden))
 
     def shortrepr(self):
@@ -418,9 +430,7 @@ class Enunciado(SQLObject): #{{{
     descripcion     = UnicodeCol(length=255, default=None)
     autor           = ForeignKey('Docente', cascade='null')
     creado          = DateTimeCol(notNone=True, default=DateTimeCol.now)
-    archivo         = BLOBCol(default=None)
-    archivo_name    = UnicodeCol(length=255, default=None)
-    archivo_type    = UnicodeCol(length=255, default=None)
+    archivos        = BLOBCol(default=None)
     # Joins
     ejercicios      = MultipleJoin('Ejercicio')
     casos_de_prueba = MultipleJoin('CasoDePrueba')
@@ -466,7 +476,7 @@ class CasoDePrueba(Comando): #{{{
     pruebas             = MultipleJoin('Prueba')
 
     def __repr__(self):
-        return super(ComandoFuente, self).__repr__('enunciado=%s, nombre=%s'
+        return super(CasoDePrueba, self).__repr__('enunciado=%s, nombre=%s'
             % (srepr(self.enunciado), self.nombre))
 
     def shortrepr(self):
@@ -512,7 +522,8 @@ class InstanciaDeEntrega(SQLObject): #{{{
     # Campos
     inicio          = DateTimeCol(notNone=True)
     fin             = DateTimeCol(notNone=True)
-    procesada       = BoolCol(notNone=True, default=False)
+    inicio_proceso  = DateTimeCol(default=None)
+    fin_proceso     = DateTimeCol(default=None)
     observaciones   = UnicodeCol(default=None)
     activo          = BoolCol(notNone=True, default=True)
     # Joins
@@ -521,9 +532,10 @@ class InstanciaDeEntrega(SQLObject): #{{{
 
     def __repr__(self):
         return 'InstanciaDeEntrega(id=%s, numero=%s, inicio=%s, fin=%s, ' \
-            'procesada=%s, observaciones=%s, activo=%s)' \
+            'inicio_proceso=%s, fin_proceso=%s, observaciones=%s, activo=%s)' \
                 % (self.id, self.numero, self.inicio, self.fin,
-                    self.procesada, self.observaciones, self.activo)
+                    self.inicio_proceso, self.fin_proceso, self.observaciones,
+                    self.activo)
 
     def shortrepr(self):
         return self.numero
@@ -620,7 +632,16 @@ class Grupo(Entregador): #{{{
     def add_miembro(self, alumno, **kw):
         if isinstance(alumno, AlumnoInscripto):
             alumno = alumno.id
-        return Miembro(grupo=self, alumnoID=alumno, **kw)
+        # FIXME acá habría que sacarle la unicidad a Miembro.pk para que
+        # un alumno pueda ser miembro varias veces del mismo grupo, de
+        # manera de tener la historia completa, pero hay que tener cuidad
+        # y arreglar todos los lugares donde se asume esa unicidad
+        try:
+            m = Miembro.selectBy(grupo=self, alumnoID=alumno).getOne()
+            m.baja = None # si ya existía, le sacamos la fecha de baja
+            return m
+        except SQLObjectNotFound: # creo uno nuevo
+            return Miembro(grupo=self, alumnoID=alumno, **kw)
 
     def remove_miembro(self, alumno):
         if isinstance(alumno, AlumnoInscripto):
@@ -631,7 +652,13 @@ class Grupo(Entregador): #{{{
     def add_tutor(self, docente, **kw):
         if isinstance(docente, DocenteInscripto):
             docente = docente.id
-        return Tutor(grupo=self, docenteID=docente, **kw)
+        # FIXME ídem add_miembro()
+        try:
+            t = Tutor.selectBy(grupo=self, docenteID=alumno).getOne()
+            t.baja = None # si ya existía, le sacamos la fecha de baja
+            return t
+        except SQLObjectNotFound: # creo uno nuevo
+            return Tutor(grupo=self, docenteID=docente, **kw)
 
     def remove_tutor(self, docente):
         if isinstance(docente, DocenteInscripto):
@@ -648,7 +675,7 @@ class Grupo(Entregador): #{{{
     @classmethod
     def selectByAlumno(self, alumno):
         return Miembro.select(AND(Miembro.q.alumnoID == AlumnoInscripto.q.id,
-                AlumnoInscripto.q.alumnoID == alumno.id))
+                AlumnoInscripto.q.alumnoID == alumno.id, Miembro.q.baja == None))
 
     def shortrepr(self):
         return 'grupo:' + self.nombre
@@ -668,6 +695,10 @@ class AlumnoInscripto(Entregador): #{{{
     membresias          = MultipleJoin('Miembro', joinColumn='alumno_id')
     entregas            = MultipleJoin('Entrega', joinColumn='alumno_id')
     correcciones        = MultipleJoin('Correccion', joinColumn='alumno_id')
+    # Notas de la cursada
+    nota_practica       = DecimalCol(size=3, precision=1, default=None)
+    nota_final          = DecimalCol(size=3, precision=1, default=None)
+    nota_libreta        = DecimalCol(size=3, precision=1, default=None)
 
     def _get_nombre(self):
         return self.alumno.padron
@@ -726,7 +757,7 @@ class Miembro(SQLObject): #{{{
 
 class Ejecucion(InheritableSQLObject): #{{{
     # Campos
-    inicio          = DateTimeCol(notNone=True, default=DateTimeCol.now)
+    inicio          = DateTimeCol(default=None)
     fin             = DateTimeCol(default=None)
     exito           = IntCol(default=None)
     observaciones   = UnicodeCol(notNone=True, default=u'')
@@ -767,6 +798,10 @@ class Entrega(Ejecucion): #{{{
         # FIXME self.id, caso_de_prueba
         Prueba.pk.get(self.id, caso_de_prueba).destroySelf()
 
+    def make_correccion(self, corrector, **kw):
+        return Correccion(instancia=self.instancia, entregador=self.entregador,
+            entrega=self, corrector=corrector, **kw)
+
     def __repr__(self):
         return super(Entrega, self).__repr__('instancia=%s, entregador=%s, '
             'fecha=%s' % (self.instancia.shortrepr(), srepr(self.entregador),
@@ -784,7 +819,7 @@ class Correccion(SQLObject): #{{{
     pk              = DatabaseIndex(instancia, entregador, unique=True)
     # Campos
     entrega         = ForeignKey('Entrega', notNone=True, cascade=False)
-    corrector       = ForeignKey('DocenteInscripto', default=None, cascade='null')
+    corrector       = ForeignKey('DocenteInscripto', notNone=True, cascade=False)
     asignado        = DateTimeCol(notNone=True, default=DateTimeCol.now)
     corregido       = DateTimeCol(default=None)
     nota            = DecimalCol(size=3, precision=1, default=None)
@@ -812,7 +847,7 @@ class ComandoEjecutado(Ejecucion): #{{{
     diferencias = BLOBCol(default=None) # ZIP con archivos guardados
 
     def __repr__(self, clave='', mas=''):
-        return super(ComandoFuenteEjecutado, self).__repr__(clave, mas)
+        return super(ComandoEjecutado, self).__repr__(clave, mas)
 #}}}
 
 class ComandoFuenteEjecutado(ComandoEjecutado): #{{{
@@ -828,7 +863,7 @@ class ComandoFuenteEjecutado(ComandoEjecutado): #{{{
                 self.entrega.shortrepr()))
 
     def shortrepr(self):
-        return '%s-%s' % (self.tarea.shortrepr(), self.entrega.shortrepr())
+        return '%s-%s' % (self.comando.shortrepr(), self.entrega.shortrepr())
 #}}}
 
 class ComandoPruebaEjecutado(ComandoEjecutado): #{{{