// check_answers.cgi: applicazione per controllare i punteggi e memorizzare le risposte // dei test. #include #include "applicat.h" #include "questionnaire.h" class Check_answers_Application : public Application { private: String _dbname; String _utente; // Utente corrente String _modulo; // Numero del modulo del quale controllare le risposte String _testnum; // Numero del test del quale controllare le risposte PgEnv _environment; bool _blank_test; String _user_answers; Questionnaire _questionario; PgTransaction *_db; protected: virtual bool create(); virtual bool destroy(); virtual void main_func(); void check_answers(); void print_access_error(); bool load_corrector(); public: Check_answers_Application() { _db = NULL; } virtual ~Check_answers_Application() {}; }; bool Check_answers_Application::create() { String separator, ws; String qs[3]; char answers[MAXQUESTIONS][MAXANSWERS]; for (int i=0; iLunghezza del buffer: " << cl << "
" << endl; #endif if (cl < 8192) { // Evita di ricevere troppa roba sullo stdin (8kb sono abbastanza??) for (int x = 0; cl && (!feof(stdin)); x++) { t1 = fmakeword(stdin, '&', &cl); t2 = makeword(t1, '='); unescape_url(t1); unescape_url(t2); if (!strcmp(t2,"MODULO")) _modulo = t1; if (!strcmp(t2,"TESTNUM")) _testnum = t1; if (!strcmp(t2,"BLANK_TEST")) _blank_test = !strcmp(t1,"ON"); // Carica le risposte fornite if (t2[0] == 'Q') { // Si tratta di una risposta del test; formato Q__ // Estrae il numero relativo alla domanda ed il numero della risposta ws = t2; const int e = split(ws, qs, 3, separator); if (e == 3) { const int qnum = atoi(qs[1]) - 1; // riferimento alla domanda const int anum = atoi(qs[2]) - 1; // riferimento alla risposta if (qnum < MAXQUESTIONS && anum < MAXANSWERS) if (!strcmp(t1,"ON")) answers[qnum][anum] = 'V'; } } } // Compone _user_answers for (int i=0; iRisposte fornite

" << endl; for (int j = 0; j < MAXQUESTIONS; j++) { cout << "Domanda " << j+1 << ":
"; for (int k = 0; k < MAXANSWERS; k++) if (answers[j][k] == 'V') cout << "VERO "; else cout << "FALSO "; cout << "
" << endl; } return FALSE; #endif } else { cout << "

Troppi dati inviati



" << endl; cout << "

L'applicazione ha ricevuto troppi dati sul buffer d'ingresso.


" << endl; return FALSE; } return TRUE; } bool Check_answers_Application::destroy() { print_footer(); return TRUE; } bool Check_answers_Application::load_corrector() { bool loaded = FALSE; String command, correct_answers, separator; separator = ";"; command = "SELECT * FROM CORRETTORI WHERE modulo="; command += _modulo; command += " AND testnum='"; command += _testnum; command += "'"; _db->ExecCommandOk(command); const int tuples = _db->Tuples(); if (tuples > 0) { correct_answers = _db->GetValue(0, "risposte"); loaded = _questionario.load(correct_answers, _user_answers); } return loaded; } void Check_answers_Application::check_answers() { if (!load_corrector()) { cout << "

Correttore inesistente



" << endl; cout << "

Impossibile caricare il correttore per il test immesso.

"; cout << "

Rivolgersi al docente della lezione odierna.

"; return; } // 1 of theze dayz I'll fall to pieces anywayz String command, verifiche, corso; // Compone la stringa di selezione utente. command = "SELECT * FROM UTENTI WHERE loginname='"; command += _utente; command += "' AND logged='t'"; // Esegue il comando SQL, dovrebbe venir ritornata una sola tupla // al limite se ne vengono ritornate piu' di una verranno ignorate _db->ExecCommandOk(command); const int tuples = _db->Tuples(); if (tuples > 0) { // Aggiorna lo stato dei test effettuati per modulo sulla tabella UTENTI verifiche = _db->GetValue(0, "verifiche"); corso = _db->GetValue(0, "course"); trim(corso); const unsigned int mod_int = atoi(_modulo); const unsigned int l = verifiche.length(); if ((l < mod_int || verifiche[mod_int-1] != _testnum[0]) && mod_int <= MAXMODULES) { if (l< mod_int) for (unsigned int j=l; j < mod_int; j++) verifiche += ' '; verifiche[mod_int-1] = _testnum[0]; command = "UPDATE UTENTI SET verifiche='"; command += verifiche; command += "' WHERE loginname='"; command += _utente; command += "'"; _db->ExecCommandOk(command); // Controlla i punteggi inseriti nella matrice con quelli memorizzati nel correttore // Compone le risposte fornite da memorizzare sulla tabella VERIFICHE in un formato più "umano" Rational punteggio; punteggio = _blank_test ? ZERO : _questionario.calc_score(); long progressivo = 0L; // Blocca la tabella dei progressivi e prende il progressivo command = "LOCK PROGRESSIVI"; _db->ExecCommandOk(command); command = "SELECT * FROM PROGRESSIVI"; if (_db->ExecTuplesOk(command) && _db->Tuples() > 0){ progressivo = atol(_db->GetValue(0, "progverifiche")); } else { // Se non c'è nessuna riga viene aggiunta command = "INSERT INTO PROGRESSIVI VALUES(0,0)"; _db->ExecCommandOk(command); } progressivo++; command = "UPDATE PROGRESSIVI SET progverifiche=progverifiche+1"; // Incrementa il progressivo _db->ExecCommandOk(command); // Aggiorna la tabella PROGRESSIVI // Memorizza il punteggio e le risposte fornite sulla tabella VERIFICHE command = "INSERT INTO VERIFICHE VALUES ("; command += ltoa(progressivo); command += ",'"; command += _utente; command += "',current_timestamp,"; command += _modulo; command += ",'"; command += _testnum; command += "','"; if (_blank_test) command += " " ; else command += _user_answers; // Risposte fornite in formato "umano" command += "',"; command += dtoa((double) punteggio); // Punteggio sottoforma di double command += ")"; _db->ExecCommandOk(command); if (_modulo=="1") // (23/01/01) Il modulo 1 é "speciale" in quanto non ha alcun test; é il modulo di cout << "" << endl; // formazione del tecnico contabile di Eurocampo else cout << "

Risultato del test



" << endl; if (!_blank_test) _questionario.dump_html(corso, atoi(_modulo), _testnum[0]); else { if(_modulo=="1") // (23/01/01) solito modulo 1 speciale cout << "

Benvenuti nel modulo per la formazione del TECNICO CONTABILE




"; else cout << "

Test consegnato in bianco


"; } cout << "
"; cout << "Cliccate sull'icona sottostante per ritornare all'area formativa del modulo."; cout << "

"; cout << ""; cout << "

" << endl; } else { // Se il test è già stato eseguito, nega l'aggiornamento il calcolo punteggio e tutto il resto cout << "

Test già eseguito



" << endl; cout << "

Il test selezionato risulta già eseguito.

"; cout << "

Si prega di riselezionare l'area corretta dalla pagina di selezione moduli.

"; } } else { // Se non trova i dati dell'utente indicato // visualizza la mancanza di informazioni per completare la pagina. cout << "

Mancanza di informazioni



" << endl; cout << "

Impossibile reperire le informazioni relative al percorso formativo dell'utente " << _utente; cout << ".

Controllare l'esattezza delle informazioni inserite.

"; } return; } void Check_answers_Application::print_access_error() { cout << "

Errore di accesso



"; cout << "

Utilizzare la normale procedura di accesso ai corsi.


"; } void Check_answers_Application::main_func() { // Controllo utente: se il CGI viene chiamato senza tutte le indicazioni necessarie // visualizza l'errore if (_utente.empty() || _modulo.empty() || _testnum.empty() || _user_answers.empty()) { print_access_error(); return; } // Se tutto è OK... // Inizia la transazione _db = new PgTransaction(_environment, _dbname); if ( _db->ConnectionBad() ) print_database_error(); else check_answers(); delete _db; // Termina la transazione return; } int main(int argc, char* argv[]) { Check_answers_Application* a = new Check_answers_Application(); a->run(argc, argv); delete a; exit(0); }