messaggio per mercurial

Moderator: Enrico Maria Giordano

User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

messaggio per mercurial

Post by Silvio.Falconi »

Ti spiego ho perso i sorgenti che avevo per il mio programma e ho decompilato un vecchio exe in dos clipper ( non trovo neache i sorgenti di questo in dos)

Orario .dbf
è un elenco di lezioni che devono fare i docenti
per ogni docente ci sono x record a seconda delle ore di cattedra
per esempio il prof Bartolini ha 11 ore di cattedra materia RELIGIONE (12) e nell'archivio ci sono elencate le sue lezioni
per esempio

Image

ogni volta che devo inserire il giorno e l'ora ( giorno 1-6 e ora 1-6) vado a controllare se la classe e le aule solo libere

quindi ho alcune funzioni che devo ricostruire

Classelib()

AulaLib()

che sono quasi identiche cambiano solo per cosa bisogna ricercare la classe o le aule

Code: Select all

static function CLASSELIB(Arg1, Arg2, Arg3)

   local Local1:= orario->classe, Local2:= orario->(RecNo()), ;
      Local3:= 1
   orario->(dbSetOrder(3))
   for Local3:= 0 to Arg1 - 1
      if (orario->(dbSeek(Local1 + Str(Arg2, 1) + iif(Arg3 + Local3 ;
            == 10, "0", Str(Arg3 + Local3, 1)))))
         orario->(dbSetOrder(8))
         orario->(dbGoto(Local2))
         return .F.
      endif
   next
   orario->(dbSetOrder(8))
   orario->(dbGoto(Local2))
   return .T.

********************************

static function AULALIB(Arg1, Arg2, Arg3)

   local Local1:= orario->aula, Local2:= orario->(RecNo()), Local3:= 1
   orario->(dbSetOrder(4))
   for Local3:= 0 to Arg1 - 1
      if (orario->(dbSeek(Local1 + Str(Arg2, 1) + iif(Arg3 + Local3 ;
            == 10, "0", Str(Arg3 + Local3, 1)))))
         orario->(dbSetOrder(8))
         orario->(dbGoto(Local2))
         return .F.
      endif
   next
   orario->(dbSetOrder(8))
   orario->(dbGoto(Local2))
   return .T.

 
gli indici di orario sono

Code: Select all

 

   INDEX ON str(PROF,3) TAG ORARIO1 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1

   INDEX ON (str(PROF,3)+upper(CLASSE)+upper(GG_ORA)+ORESEQ) TAG ORARIO2 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
  
   INDEX ON   (upper(CLASSE)+upper(GG_ORA)) TAG ORARIO3 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
  
   INDEX ON   (upper(AULA)+upper(GG_ORA))  TAG ORARIO4 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
  
   INDEX ON ((str(GRUPPO,3))+upper(GG_ORA)) TAG ORARIO5 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
   
   INDEX ON  ((str(PROF,3))+upper(GG_ORA))  TAG ORARIO6 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
   
   INDEX ON  (str(MATERIA,3)+str(PROF,3)+ORESEQ) TAG ORARIO7 EVAL (oProgress:SetPos(nProgress++), Sysrefresh()) EVERY 1
 

poi la vecchia procedur ain dos crea altri due file index Orario.$$1 e orario $$2
ma non si capisce molto

Code: Select all

 or->(dbCreateIndex("orario.$$1", ;
      "ma->prec + do->punti", {|| ;
      (ma->(dbGoto(or->materia)), ;
      do->(dbGoto(or->prof)), ma->prec + ;
      do->punti + eval({|| (DevPos(14, 14), iif(!EOF(), ;
      DevOut(Replicate("²", RecNo() * 51 / LastRec())), Nil), ;
      "")}))}))


      or->(dbCreateIndex("orario.$$2", ;
      "or->classe + str( or->gruppo, 3 ) + or->gg_ora", ;
      {|| or->classe + Str(or->gruppo, 3) + or->gg_ora + ;
      eval({|| (DevPos(14, 14), iif(!EOF(), DevOut(Replicate("²", ;
      RecNo() * 51 / LastRec())), Nil), "")})}))


prima di salvare il giorno e l'ora della lezione corrispondente la procedura vede se la classe e le aule solo libere però è strano perchè mentre per le classi il controllo mi puo stre bene per le aule no perchè è logico per esempio che la classe 1A stia alla'aula 1A anche se per alcune materie è possibile che l'aula per esempio la palestra sia occupata
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Quindi in pratica in orario.dbf in una prima fase "sviluppi" la cattedra di un docente per poi in un secondo momento andare ad indicare giorno e ora.

Il controllo deve essere doppio perché alcuni docenti potrebbero dover usare un laboratorio... ma questo dovrebbe essere settabile quando sviluppi la cattedra...

ora vedo
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

si... quando inserisco un docente gli inserisco anche le cattedre per quel docente.

Adesso ho un 'altro problema in un altro pezzo della procedura dove assegna le ore .. non capisco il perchè non entra in questo ciclo

Code: Select all

if (!Empty(DO->oredispo))


       while (OR->prof == DO->(RecNo()))

             XBROWSE()
            if (Empty(OR->gg_ora) .AND. OR->classe == DA->cla_dis)

               AAdd(Local7, {or->(RecNo()), ""})

            elseif (!Empty(OR->gg_ora) .AND. OR->classe != DA->cla_dis)

               AAdd(Local6, Val(or->gg_ora))

            endif

            or->(dbSkip())

         end




....

endif
e quindi non popola gli array local7 e local6
ma l'espressione while (OR->prof == DO->(RecNo())) è corretta?
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Faccio riferimento al pezzettino di codice che hai inviato l'altro giorno:

Code: Select all

SELECT CL
CL->(dbSeek(OR->classe))
nOreClasse := CL->MAX_ORE-CL->ORE_ASS
....
IF CLASSELIB( nOreClasse, nGiorno, nOre )
   cl->ore_ass += 1
   or->gg_ora := nGG_Ora
ENDIF
 
nOreClasse cosa rappresenta?
Hai scritto: "The parameter passed nOreClasse is a number corresponding to the difference in how many hours a class must be committed [un]less the value of the field ore_as"
Non capisco... che range di valori può assumere nOreClasse?
Perché vedo che ORE_ASS è incrementato di 1 e lo puo essere in teoria 36 volte...


Veniamo al codice

Code: Select all

static function CLASSELIB(nOreClasse, nGiorno, nOre)

   local Local1:= orario->classe
   local Local2:= orario->(RecNo())
   local Local3:= 1

   orario->(dbSetOrder(3)) // upper(CLASSE)+upper(GG_ORA)

   // questo loop cicla da 0 a nOreClasse - 1
   for Local3:= 0 to nOreClasse - 1
      // la dbSeek su order 3 ci dice che
      // Local1 è la classe (e si legge sopra)
      // nGiorno è il giorno
      // Arg3 è l'ora
      // Quindi se hai fatto ClasseLib( 2, 2, 3 )
      // il loop *può* venir fatto per
      // 1A23
      // 1A24
      if (orario->(dbSeek( ;
         Local1 + ;
         Str(nGiorno, 1) + ;
         iif(Arg3 + Local3 == 10, "0", Str(Arg3 + Local3, 1)))))

         orario->(dbSetOrder(8))
         orario->(dbGoto(Local2))
         return .F.
      endif
   next

   orario->(dbSetOrder(8))
   orario->(dbGoto(Local2))
   return .T.
 
Quindi sembra che la funzione controlli se la classe non è disponibile un determinato giorno (nGiorno) in una determinata ora (nOre) e per nOreClasse consecutive.

Infatti se la dbSeek trova almeno un'ora assegnata fra quelle controllate, la funzione ritorna .F.
Se invece esce dal FOR/NEXT significa che tutti i test sono andati a vuoto perché la classe non è assegnata in quell'ora (GG_ORA è vuoto) e la funzione ritorna .T.

Non posso andare oltre perché mi mancano delle informazioni e soprattutto mi manca un pezzo di codice integro e sicuramente funzionante in cui questa funzione è usata.


Mi rimane invece forte il dubbio su nOreClasse e sul range di valori che può acquisire perché un valore alto andrebbe a inficiare la chiave della dbSeek...

Quindi, per me, analizzando la funzione, questa svolge - correttamente - un compito preciso, con l'unico dubbio su nOreClasse: verifica se una classe è disponibile in un dato giorno e per un numero consecutivo di ore.

PS: poi in un altro thread avevi postato una ClasseLib completamente diversa... hai letto le mie risposte ai vari thread inglesi?
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Silvio.Falconi wrote:si... quando inserisco un docente gli inserisco anche le cattedre per quel docente.

Adesso ho un 'altro problema in un altro pezzo della procedura dove assegna le ore .. non capisco il perchè non entra in questo ciclo

Code: Select all

       while (OR->prof == DO->(RecNo()))
 
Perché OR->prof è diverso da DO->(Recno())... (non sono bravo a usare le faccine, mettici quella giusta...)
e quindi non popola gli array local7 e local6
ma l'espressione while (OR->prof == DO->(RecNo())) è corretta?
L'espressione è sintatticamente corretta ma non è detto che lo sia logicamente. Ti hanno già detto che usare il Recno() come chiave sia una cosa molto pericolosa e sulla quale occorre fare molta attenzione, soprattutto se il programma consente di fare DELETE e PACK....

Dovresti prima della IF stampare il valore di OR-prof e di DO->(RecNo()) e vedere se sono quelli che ti aspetti... magari qualche funzione ti ha spostato il record corrente senza ripristinarlo...

Una curiosità: questo programma era stato sviluppato con un CASE?
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

scusa mancava un or->(dbSetOrder(1))
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

>Una curiosità: questo programma era stato sviluppato con un CASE?
si sweet..qualchecosa non mi ricordo il nome nel 92
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

>Perché OR->prof è diverso da DO->(Recno())... (non sono bravo a usare le faccine, mettici quella giusta...)

faccine ? non capisco
il file index è INDEX ON str(PROF,3) TAG ORARIO1

or->prof è numerico e do->recno() dovrebbe essere numerico
è stato usato il numero del record , lo so che è sbagliato ma adesso devo usare lo stesso metodo , poi in futuro potro moficarlo nelle prime 4 lettere del cognome che so per farti un esempio
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

La funzione assegnaore poi è ingarbugliata...ma solo non capisco il perchè lui assegna le ore solo per lunedi,martedi,mercoledi e giovedi

Image


probabilmente non ci sono i controlli per classelib e aulalib e giornolib del docente

probabilmente perchè le ore cioè le cattedre finiscono e non ha altre da inserire
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Silvio.Falconi wrote:>Una curiosità: questo programma era stato sviluppato con un CASE?
si sweet..qualchecosa non mi ricordo il nome nel 92
Per caso era dbSee?

Comunque si spiegano alcune cose, così come quella follia dell'indice orario.$$1 che un qualunque essere umano avrebbe gestito con una serie di SET RELATION TO... perché un umano non avrebbe mai scritto una cosa del genere... spero...
Comunqnue questo indice serve per mettere in relazione 3 tabelle. Non so come viene usata quindi non saprei dire ma in un relazionale avremmo dovuto creare (e gestire) una apposita tabella mentre in questo modo l'indice gestisce tutto.

Quindi hai recuperato tutte le funzioni decompilando un vecchio exe clipper ma mancano queste due funzioni? Come è possibile che manchino se erano nell'exe? o forse erano usate in una versione successiva? non è che stai mischiando sorgenti di versioni differenti?


Comunque a mettere le mani su codice generato da un CASE e poi decompilato è veramente un'impresa !
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

mercurial wrote: Quindi sembra che la funzione controlli se la classe non è disponibile un determinato giorno (nGiorno) in una determinata ora (nOre) e per nOreClasse consecutive.

nOreClasse secondo me non è data da quella operazione che avevo messo ma è dato dal calcolo della materia e quindi nOremateria cioè

tale docente X insegna la materia RELIGIONE (12) ma questa materia puo' essere ripetuta in quella classe solo 1 volte alla settimana cioè nei 6 giorni e la materia ha un valore di precedenza 9 cioè alla fine della piramide valori da Da 1 a 9
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

non mancano ce le ho le funzioni ma non funzionano come dovrebbero
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Silvio.Falconi wrote:La funzione assegnaore poi è ingarbugliata...ma solo non capisco il perchè lui assegna le ore solo per lunedi,martedi,mercoledi e giovedi
probabilmente non ci sono i controlli per classelib e aulalib e giornolib del docente
Sembrerebbe quello il problema... infatti le classi hanno più docenti in contemporanea...
probabilmente perchè le ore cioè le cattedre finiscono e non ha altre da inserire
Si, sono tutte concentrate all'inizio. Ma come le distribuisci le lezioni? Usi un algoritmo automatico? Mi è venuto in mente che un mio amico una volta mi consigliò di dare uno sguardo agli algoritmi genetici... ma non credo sia possibile cambiare in corsa...
mercurial
Posts: 16
Joined: Wed Feb 04, 2015 2:26 pm

Re: messaggio per mercurial

Post by mercurial »

Silvio.Falconi wrote: nOreClasse secondo me non è data da quella operazione che avevo messo ma è dato dal calcolo della materia e quindi nOremateria cioè
Quindi non devi solo ricompilare il codice (per caso, l'hai fatto? Hai ricompilato il decompilato senza cambiare nulla?) ma devi pure scrivere del codice... se scrivi "non è data da quella operazione che avevo messo" io capisco che stai facendo delle modifiche...

Prima di farle verifica le altre chiamate a CLASSELIB... E poi occorre sapere se il codice che posti sia quello generato/decompilato o tuo, perché si potrebbero sommare due errori...
tale docente X insegna la materia RELIGIONE (12) ma questa materia puo' essere ripetuta in quella classe solo 1 volte alla settimana cioè nei 6 giorni e la materia ha un valore di precedenza 9 cioè alla fine della piramide valori da Da 1 a 9
Si, immagino che ci siano molti parametri di "desiderata" e per questo algoritimi genetici sono da preferire a quelli algoritmici puri... a meno che nel 2015 non vai di forza bruta e ti crei tutte le possibili combinazioni di orario.... sarebbe divertente da provare... poi per religione, in un liceo e se hai una classe con molti che non si avvalgono, conviene piazzare la lezione in prima o ultima...

Comunque mi sembra che anche questa tua seconda ipotesi non sia corretta... che valore avrebbe la prof.ssa Frati che ha 10 ore in 1D? 10?
User avatar
Silvio.Falconi
Posts: 4956
Joined: Thu Oct 18, 2012 7:17 pm

Re: messaggio per mercurial

Post by Silvio.Falconi »

L'archivio dei docenti è l'archivio stravecchio del 1992 .

C'è una procedura che si chiama Ciclone che apre gli archivi, li azzera cioè azzera alcuni campi di orario ( gg_ora se non trova un carattere nel campo Blocco) , classi ed aule ( campo ore_ass cioè le ore assegnate).

Da questa funzione si arriva in un altra funzione che si chiama ciclomater : in questa funzione inizia il ciclo for next che puo' essere fino a 2.
Sempre in questa funzione ci sono tre righe che io avevo erroneamente remmato che vanno a caricare le ore sequenziali e restituendo un array e un'altra variabile quante volte la materia deve essere consecutiva : questa variabile che poi è usata nella funzione Classelib che giustamente tu hai detto la funzione classelib svolge un compito ben preciso cioè verifica se una classe è disponibile in un dato giorno e per un numero consecutivo di ore.


Per assegnare le ore c'è una funzione assegnaore(ngiro) che al momento funziona ma a volte cioè ancora non capisco come funziona , e io ho aggiunto in questa funzione la classe Tprogress ( 3 barre) una per il ciclo delle lezioni, una per il ciclo dei docenti e l'altra il ciclo che è in mezzo dei giorni per vedere ogni volta in quale parte del ciclo si trovi .


In questa funzione AssegnaOre seleziona i docenti e fa un ciclo do while not eof() poi
cerca in orario il record del docente . orario è indicizzato nel primo index cioè INDEX ON str(PROF,3) TAG ORARIO1

OR->(dbSeek(Str(DO->(RecNo()), 3)))

poi apre un IF

if (!Empty(DO->oredispo))

se non è vuota oredispo ma è un controsenso perchè è sempre pieno questo campo anche quando il campo c'è un zero ( il campo è un campo carattere)
poi apre un altro ciclo do while

DO while (OR->prof == DO->(RecNo()))


if (Empty(OR->gg_ora) .AND. OR->classe != DA->cla_dis)

AAdd(Local7, {or->(RecNo()), ""})

elseif (!Empty(OR->gg_ora) .AND. OR->classe != DA->cla_dis)

AAdd(Local6, Val(or->gg_ora))

endif

or->(dbSkip())

end


Local7 e local6 sono due array ma anche qui c'è un controsenso perchè il local6 non si formerà mai perchè all'inizio della funzione ciclone va a cancellare il campo or->gg_ora sempre se il campo or->blocco è vuoto mentre local7 si popola con i numeri dei record . forse nel ennesimo ciclo trova il campo or->gg_ora pieno e popola anche il local6 ma non è detto . ti dico cosi perchè la funzione integra io lo provata e riprovat aun sacco di volte e non salva le ore nell'archivio se invece metto una mappatura oraria nell'array local6 del tipo :

Local6:= {10,20,30,40,50,60,;
11,21,31,41,51,61,;
12,22,32,42,52,61,;
13,23,33,43,53,63,;
14,24,34,44,54,64,;
15,25,35,45,55,65,;
16,26,36,46,56,66 }


allora la parte finale della funzione assegna le ore prendendole dal local6 e poi puoi vedere il risultato della schermata che ti ho postato cioè le ore le mette ma sono tutte in fila ... ma almeno le mette...
ma lo so che non va bene .... se mi scrivi a silvio[dot]falconi[at]gmail[dot]com ti invio il file

E' possible quindi che una lezione sia bloccata cioè che nel campo or-> blocco ci sia un asterisco e quella lezione non deve essere cambiata, in via di sviluppo di formazione orario l'utente puo' attraverso un inserimento visivo assegnare delle ore "a mano" al docente , quando accade questo il programma mette un asterisco nel campo or->blocco

Image


o questo puo' accadere per una determinata classe o aula

Una cosa che non ti ho detto ---- la formazione dell'archivio Orario viene fatto ogni volta che si inserisce un docente ed il totale delle lezioni ( cattedre) è il campo do->ore_catt


Prof il codice recno del docente

Il campo Classe Indica la classe in cui il professore deve insegnare. Per e ore a disposizione inserire il "Codice classe per le
ore a disposizione" caricato nei "Parametri generali" che generalmente e in questo caso è 1DISP ma nel tabello non si vede bene e quindi lo devo cambiare in XX o altro codice tipo DD perchè il tabellone fa vedere solo 2 cr per casella

la materia di insegnamento del professore in quell'ora.

Per il campo Aula bisogna dire che non e' necessario inserire l'aula, in quanto per il programma rimane sottinteso e dovrebbe essere così che ogni classe rimanga nella propria aula per lo svolgimento delle normali ore di lezioni. E' invece obbligatorio inserire il laboratorio per le ore svolte in esso al fine di evitare accavallamenti di piu' classi, non appartenenti ad un gruppo, per la stessa ora nello stesso laboratorio.

FLAG prevede l'inserimento di un flag, che serve poi al programma per conteggiare le ore di cattedra

ORESEQ Nel caso in cui si desidera che piu' ore inserite vengano collocate una di seguito all'altra, bisogna indicare per tali
ore in questa colonna un medesima lettera. Ad esempio supponiamo che il professore insegni 6 ore di
matematica sia in Prima C che in Prima D. Se vogliamo che per entrambe le classi vi siano 2 ore consecutive, basta collocare
in questo campo per due ore cattedra nella classe Prima C, la lettera "A" e indicare "B" per altre 2 ore cattedra nella
classe Prima D.

GRUPPO è il codice di un gruppo inserito nell'archivio complementare. I gruppi servono per gestire la presenza di piu' di
una classe per una medesima ora di lezione. Se si desidera, ad esempio, che la Prima A e la Prima B facciano Chimica insieme e' sufficiente che per tali ore venga indicato il medesimo codice gruppo in questa colonna




l'Index Orario.$$2 quello super ingarbugliato è usato solo in una funzione che ho messo da parte per adesso cioè quella che gestisce i gruppi. che per adesso non voglio occuparmene perchè vorrei risolvere le altre funzioni che non funziano bene o che non capisco cosa fanno ...
I use : FiveWin for Harbour August 2020 (Revision) - Harbour 3.2.0dev (r1712141320) - Bcc7.30 - xMate ver. 1.15.3 - PellesC
Post Reply