PDA

View Full Version : [c++]mi aiutate a fare un programma per mio padre?


mikisx
16-07-2007, 14:54
ciao,da 1 anno (scolastico)studio c++,ma la prof nn ci ha spiegato uan cosa secondo me importantissima....

sono pratico nel uso dei vettori e delle stringhe,conosco vari tipi di ricerca ,gli if ecc ...lecose basilari...

pero' ho sempre lavorato sulla ram!
nn sono in grado di memorizzare idati sul hd
es:
faccio una rubrica,inserisco i nomi,come chiudo il prog perdo i dati,io voglio che restino memorizzati sul hd....

mio padre gestisce dei condomini,lo vorrei aiutare nel tenere i conti e le varie spese ,se mi potete cortesemente spiegare il procedimento per memorizzare i file inizio a fare una bella bozza....poi a sorgente completa ve la passo e la condividiamo che ve ne pare?

ciao

michele

PGI-Bis
16-07-2007, 15:12
Se la quantità di dati che devi conservare non è eccessiva, diciamo tra i 500 megabyte e un gigabyte, puoi usare un logger.

Dico 500-1000 megabyte pensando ad un sistema desktop non recentissimo ma il limite teorico è semplicemente la quantità di memoria disponibile al programma.

Un logger tiene i dati nella memoria del programma e realizza la persistenza registrando gli eventi che causano una mutazione dei dati conservati.

Che detto così magari sembra chissà che, ma è facilissimo da fare, manutenere ed estendere.

Non è l'unica alternativa (anzi, è sicuramente la meno tradizionale) ma ha parecchi vantaggi.

Se l'idea di sollazza e mi dici quali dati devono essere conservati, ti dico come si fa.

mikisx
16-07-2007, 15:20
grazie mille!

allora,ho un condominio e devo:
1-memorizzare i dati dei condomini-cf recapito telefonico ecc.-(lo faccio con le stringhe e poi uso lo strcat?)
2-tenere conto delle spesa mensile(avendo la possibilita' di vedere il mese di maggio le spese per la pulizia ,luce acqua ecc..e cosi per gli altri mesi) e di quella annuale...
3-dividere la spesa tramite i millesimi per singoli condomini(ce la fo)
4-poter tenere conto di quanto a pagato ogni condomino(per vedere se è in defict o eccesso)
5-tenere conto degli impiegati del condominio con relativi dati anagrafici,paga mensile e giorni di lavoro(portiere -giardiniere ecc...)

grazie

ps come mi ritorna tra le mani il c++(a scuola me lo danno free) inizio a mettermi sotto...e questione di giorni

cionci
16-07-2007, 15:22
Per i file in C++ questa guida non è male per partire: http://www.daniweb.com/forums/thread6542.html

mikisx
16-07-2007, 15:27
mi sa che con il vostro aiuto come torno a scuola il 10 in programmazione nn me lo toglie nessuno:D

PGI-Bis
17-07-2007, 08:44
Il logger funziona in questo modo.

Supponiamo che i dati da conservare siano degli oggetti Condomino così fatti:

class Condomino
+long getId();
+string getNome();
+string getCognome();
+string getTelefono();
+string getCodiceFiscale();

Le operazioni che coinvolgono la persistenza dei Condomini, cioè la conservazione dei dati dei condomini tra un'esecuzione e l'altra dell'applicazione, sono solo tre.

1. crea un nuovo condomino
2. elimina un condomino
3. modifica i dati di un condomino

Quando nel programma si verifica uno di questi eventi noi prendiamo e scriviamo sul file di log, che è un file di testo, una stringa di identificazione dell'evento seguita da tutti i dati necessari per ricostruirlo.

Stabiliamo che le stringhe di identificazione siano:

CREA CONDOMINO
ELIMINA CONDOMINO
MODIFICA CONDOMINO

Per poter essere ricostruibile, l'evento "crea un nuovo condomino" richiede che il file di log riporti i dati del condomino creato. I dati necessari alla creazione di un condomino sono:

a) una intero long come identificatore univoco
b) una stringa per il nome
c) una stringa per il cognome
d) una stringa per il recapito telefonico
e) una stringa per il codice fiscale

Supponiamo che il programma crei, dietro richiesta dell'utente, questo Condomino:

id = 0
nome = mario
cognome = rossi
telefono = 123456
codice fiscale = blabla

Il logger scriverà sul file:

CREA CONDOMINO
0
mario
rossi
123456
blabla

L'eliminazione di un condomino può essere registrata sul file di log con l'identificatore ELIMINA CONDOMINO seguito dall'identificatore univoco del condomino eliminato:

ELIMINA CONDOMINO
0

La mutazione dei dati di un condomino sarà invece registrata come la creazione ma con un'intestazione diversa:

MODIFICA CONDOMINO
0
mario
rossi
789012
blabla

Alla fine della fiera, il contenuto del file di log somiglierà a questo:

CREA CONDOMINO
0
mario
rossi
123456
blabla
CREA CONDOMINO
1
gianni
verdi
123333
blibli
CREA CONDOMINO
2
pietro
neri
44444
frufru
ELIMINA CONDOMINO
2
CREA CONDOMINO
3
franco
gialli
222222
gnagna
MODIFICA CONDOMINO
1
gianni
verdi
678888
blabla
...
...eccetera

La ricostruzione dello stato del programma a partire dal file di log è banale. Apri il file a applichi un algoritmo di questo tipo:

per ogni linea X nel file di log

se X è CREA CONDOMINO
1. la linea seguente è l'identificatore
2. la linea seguente è il nome
3. la linea seguente è il cognome
4. la linea seguente è il telefono
5. la linea seguente è il codice fiscale
6. prendi i dati letti, crea un condomino e infilalo nella memoria del programma

+se X è ELIMINA CONDOMINO
1. la linea seguente è l'identificatore del condomino da eliminare
2. cerca nella memoria il condomino che abbia quell'identificatore ed eliminalo

+se X è MODIFICA CONDOMINO
1. la linea seguente è l'id del condomino modificato
2. la linea seguente è il nuovo nome
3. la linea seguente è il nuovo cognome
4. la linea seguente è il nuovo telefono
5. la linea seguente è il nuovo codice fiscale
6. cerca nella memoria il condomino di identificatore id, eliminalo e rimpiazzalo con un nuovo condomino oppure cambia i suoi dati

Applichi lo stesso principio a tutte le altre modifiche e sei a posto. E che posto. Il logger, richiedendo la presenza di una controparte in memoria per l'uso dei dati da parte del programma, ciuccia una valanga di memoria. In cambio ti offre un motore di persistenza transazionale, cioè puoi isolare un gruppo di modifiche ed eliminarle in caso di errore, molto rapido nell'accesso ai dati, essendo conservati nella memoria volatile e, sopratutto, reversibile: il file di log non è altro che una pila delle transizioni che hanno portato il programma dal stato iniziale, vuoto, allo stato attuale. Eliminando l'ultima transizione registrata fai un passo indietro nel tempo. Nel campo delle applicazioni desktop si tratta di un valore assoluto. L'utente può compiere sui suoi dati le più distratte nefandezze ed avere comunque la garanzia che, in ogni istante, quella nefandezza sarà annullabile.

mikisx
17-07-2007, 13:07
grazie,molto utile,credo di avere capito tutto,ma...:
non mi fare sembrare lollo, ma
questo
class Condomino
+long getId();
+string getNome();
+string getCognome();
+string getTelefono();
+string getCodiceFiscale();
in quale parte lo metto?

io uso scrivere cosi:

#include<iostream.h> //inserisco le librerie//
int //o float o double ecc ,dichiarazione dellevariab//
void main()
{



tieni conto che so utilizzare i vettori,le operazioni sulle stringhe,l'uso dello switch
,la ricerca binaria...cose che si fanno a scuola,purtroppo i prof non sono arrivati a finire e spero che con il vostro aiuto(da quello che ho capito siete programmatori)possa riuscire nel mio intento


dimenticavo,il log in che cartella si va a posizionare?

PGI-Bis
17-07-2007, 14:10
Il file di testo che contiene le righe sputate dal logger lo puoi mettere dove ti pare ma sarebbe meglio metterlo nella cartella del tuo programma (magari in una sub directory "data").

Condomino è una classe. In C++, lingua che fortunatamente non uso, è una cosa che potrebbe somigliare a:

...in Condomino.h
class Condomino {
private:
long id;
string nome;
string cognome;
...eccetera

public:
long getId();
string getNome();
string getCognome();
...eccetera
};

...in Condomino.cpp
#include "Condomino.h"
long Condomino::getId() { return id; }
string Condomino::getNome() { return nome; }
string Condomino::getCognome() { return cognome; }
...eccetera

mikisx
17-07-2007, 15:02
ma perchè in cpp mi hanno insegnato a scriverlo cosi?

cionci
17-07-2007, 15:04
ma perchè in cpp mi hanno insegnato a scriverlo cosi?
Probabilmente non hai ancora fatto la programmazione ad oggetti ;)

mattia.pascal
17-07-2007, 16:32
Secondo me è pazzesco fare un software del genere nel modo che ti stanno consigliando. Devi usare un database e se proprio ti serve memorizzare lo stato del programma usi la serializzazione.

PGI-Bis
17-07-2007, 16:54
Perchè è addirittura "pazzesco"? :confused:

mattia.pascal
17-07-2007, 17:15
Mi sembra complicarsi inutilmente le cose.

PGI-Bis
17-07-2007, 17:53
Naturalmente è una questione di gusti. Per i professionisti del settore di necessità (se qualcosa va storto dire "ho usato un database come tutti" potrebbe salvarvi la ghirba).

Io credo che al più 300 linee di codice valgano lo sforzo se rapportate al risultato della formula Database = SQL del produttore + DDL + dispiegamento + amministrazione.

Non sono il solo.

http://blogs.sun.com/jag/date/20061020

71104
17-07-2007, 17:59
Perchè è addirittura "pazzesco"? :confused: nemmeno io riesco a capire per quale motivo gli stai consigliando di registrare tutte le operazioni che modificano lo stato del programma anziché solo lo stato del programma così com'è... facendo come dici tu, se ho capito bene, il log non smetterebbe mai di crescere; e poi non gli hai dato alcuna informazione specifica su come fare I/O su files in C++, che è sostanzialmente quello che lui voleva sapere. trovo strano che non lo sappia visto che ha incluso iostream (e pure male :D), forse gli hanno insegnato solo l'I/O sulla console e non quello sui files.

71104
17-07-2007, 18:00
Naturalmente è una questione di gusti. Per i professionisti del settore di necessità (se qualcosa va storto dire "ho usato un database come tutti" potrebbe salvarvi la ghirba).

Io credo che al più 300 linee di codice valgano lo sforzo se rapportate al risultato della formula Database = SQL del produttore + DDL + dispiegamento + amministrazione.

Non sono il solo.

http://blogs.sun.com/jag/date/20061020 infatti anche l'idea del database è decisamente esagerata. ma un semplice I/O su files no? :wtf:

mattia.pascal
17-07-2007, 18:10
nemmeno io riesco a capire per quale motivo gli stai consigliando di registrare tutte le operazioni che modificano lo stato del programma anziché solo lo stato del programma così com'è... facendo come dici tu, se ho capito bene, il log non smetterebbe mai di crescere; e poi non gli hai dato alcuna informazione specifica su come fare I/O su files in C++, che è sostanzialmente quello che lui voleva sapere. trovo strano che non lo sappia visto che ha incluso iostream (e pure male :D), forse gli hanno insegnato solo l'I/O sulla console e non quello sui files.

Si appunto. Posso condividere l'idea che si può fare a meno di un database, ma memorizzare lo stato del sistema in quel modo non mi convince proprio.
Io al nostro amico che è ancora all'inizio e che ha voglia di imparare consiglio di studiarsi prima le basi di OOP, poi i vari metodi per memorizzare in maniera permanente delle informazioni (serializzazione in primis). A quel punto sceglierà da solo l'opzione che gli sembra più semplice.

mattia.pascal
17-07-2007, 18:13
infatti anche l'idea del database è decisamente esagerata. ma un semplice I/O su files no? :wtf:

Esagerata forse, ma siccome penso che lo scopo fondamentale che lo ha spinto a fare questo post sia imparare qualcosa di utile e non fare un programma che possa utilizzare suo padre.

71104
17-07-2007, 18:14
Si appunto. Posso condividere l'idea che si può fare a meno di un database, ma memorizzare lo stato del sistema in quel modo non mi convince proprio.
Io al nostro amico che è ancora all'inizio e che ha voglia di imparare consiglio di studiarsi prima le basi di OOP, poi i vari metodi per memorizzare in maniera permanente delle informazioni (serializzazione in primis). A quel punto sceglierà da solo l'opzione che gli sembra più semplice. quale serializzazione, stiamo parlando di C++, non di Java :D
però l'idea della serializzazione è ottima: io consiglierei a mikisx di trasferirsi su Java, perché se sa usare vettori e strutture varie diventa solo una questione di ObjectOutputStream.writeObject e successivamente di ObjectInputStream.readObject.

cionci
17-07-2007, 18:16
quale serializzazione, stiamo parlando di C++, non di Java :D
però l'idea della serializzazione è ottima: io consiglierei a mikisx di trasferirsi su Java, perché se sa usare vettori e strutture varie diventa solo una questione di ObjectOutputStream.writeObject e successivamente di ObjectInputStream.readObject.
Addirittura gli consigli di impararsi un nuovo linguaggio invece di scrivere 10 righe per salvare qualche struttura su un file :eek:

71104
17-07-2007, 18:19
Addirittura gli consigli di impararsi un nuovo linguaggio invece di scrivere 10 righe per salvare qualche struttura su un file :eek: "nuovo" per modo di dire, suvvia :D
però in effetti considerando che sembra non aver studiato programmazione a oggetti... :stordita:
ok, torniamo all'idea dell'I/O su files :D

@mikisx: tanto per cominciare di iostream devi includere la nuova versione, che manca dell'estensione nel nome:

#include <iostream>


e questo è un primo passettino :D

PGI-Bis
17-07-2007, 18:27
Scrive ogni evento perchè così se gli va via la corrente al massimo perde l'ultima transizione di stato, se capita proprio durante la scrittura.

La questione della crescita si risolve con tale evidente semplicità che mi rifiuto di dirlo.

mattia.pascal
17-07-2007, 18:31
Librerie per la serializzazione in C++ ne esistono. Certo non sono standard. E poi comunque , volenti o nolenti, c'è sempre il buon vecchio .Net.
Inoltre ribadisco che l'obiettivo è impare e nello stesso tempo, per non annoiarsi ed essere più motivato, fare qualcosa che alla fine funzioni e sia utile.

mikisx
17-07-2007, 18:45
nemmeno io riesco a capire per quale motivo gli stai consigliando di registrare tutte le operazioni che modificano lo stato del programma anziché solo lo stato del programma così com'è... facendo come dici tu, se ho capito bene, il log non smetterebbe mai di crescere; e poi non gli hai dato alcuna informazione specifica su come fare I/O su files in C++, che è sostanzialmente quello che lui voleva sapere. trovo strano che non lo sappia visto che ha incluso iostream (e pure male :D), forse gli hanno insegnato solo l'I/O sulla console e non quello sui files.

ragazzi,dai non litigate,l'ignorante sono io!:(

pero' se facciamo un pezzo di codice ciascuno spiegandomi i vari passagi mi aiutate...

nuovoUtente86
17-07-2007, 19:17
Scrive ogni evento perchè così se gli va via la corrente al massimo perde l'ultima transizione di stato, se capita proprio durante la scrittura.

La questione della crescita si risolve con tale evidente semplicità che mi rifiuto di dirlo.

be cmq forse il suo intento è qualcosa di piu semplice ovvero memorizzare in maniera semplice su un file i dati...tipo condominio x....per cui la scrittura su un file richiamata da un metodo salva...potrebbe gia bastare.Cmq con i log la possibilità che le dimensioni del file crescano oltremodo c' è,le idee che mi vengono per diminuirle sono:ridurre il salvataggio all' ultima modifica per ogni oggetto,ridurre le modifiche ad una determinata data per oggetti in seguito alla stessa modificati...Non so tu che strategia hai in mente per ridurre il file?

cionci
17-07-2007, 19:22
be cmq forse il suo intento è qualcosa di piu semplice ovvero memorizzare in maniera semplice su un file i dati...tipo condominio x....per cui la scrittura su un file richiamata da un metodo salva...potrebbe gia bastare.Cmq con i log la possibilità che le dimensioni del file crescano oltremodo c' è,le idee che mi vengono per diminuirle sono:ridurre il salvataggio all' ultima modifica per ogni oggetto,ridurre le modifiche ad una determinata data per oggetti in seguito alla stessa modificati...Non so tu che strategia hai in mente per ridurre il file?
Quando il log diventa troppo grande o quando chiudi il programma basta salvare lo stato degli oggetti ed azzerare il file di log ;)

cionci
17-07-2007, 19:23
ragazzi,dai non litigate,l'ignorante sono io!:(

pero' se facciamo un pezzo di codice ciascuno spiegandomi i vari passagi mi aiutate...
Nel link che ti ho dato ci sono già diversi esempi che puoi usare. inizia intanto ad imparare a salvare una struttura su un file binario ed a riprenderla.

mikisx
17-07-2007, 19:26
be cmq forse il suo intento è qualcosa di piu semplice ovvero memorizzare in maniera semplice su un file i dati...tipo condominio x

si

nuovoUtente86
17-07-2007, 19:35
Quando il log diventa troppo grande o quando chiudi il programma basta salvare lo stato degli oggetti ed azzerare il file di log ;)

probabilmente da quello che ho capito lui utilizza il file di log come file dati,ovvero va da li a caricare "la base di dati".
Per il dimensionamento probabilmente diciamo la stessa cosa o cmq simile.
Se ho ben capito tu dici:
il file supera una certa dimensione,salvo lo stato attuale di tutti gli oggetti ed elimino i precedent log?

mikisx
17-07-2007, 19:45
Steps:

1. Declare an ofstream var.
2. Open a file with it.
3. Write to the file (there are a couple of ways.)
4. Close it.


Eg Program 1.1

#include <fstream.h>

void main
{
ofstream file;

file.open("file.txt"); //open a file

file<<"Hello file\n"<<75; //write to it

file.close(); //close it
}


1:ma come lo devo dichiarare?
char vett[10][20] ?
2:apre il file che dichiaro???
mi sto confondendo!


file<<"Hello file\n"<<75; perchè il 75?

PGI-Bis
17-07-2007, 19:52
Quando il log diventa troppo grande o quando chiudi il programma basta salvare lo stato degli oggetti ed azzerare il file di log ;)

yesss.

Se togliamo la reversibilità delle transizioni allora lo "stato" del programma è semplicemente l'elenco di dati che si trovano nella struttura dati in memoria.

In teoria basta appunto cancellare il file e dare in pasto al logger stesso tutti i dati in memoria.

In pratica occorre sempre tener presente il grande classico dell'informatica, ovvero "il Giuseppe che mi inciampa nella presa" e rendere quindi transazionale il passaggio dal vecchio al nuovo file di log.

Quanto al quando può essere alla chiusura ma, dopo qualche prova, mi sono stabilizzato sull'uso di una "soglia utile". Vale realmente la pena fare il "dump" solo se il numero di transizioni inutili (le modifiche e gli inserimenti di oggetti che risultano poi eliminati) è proporzionalmente maggiore di quelle utili (gli inserimenti di oggetti). Cioè se ci sono settantamila creazioni e due rimozioni il vantaggio è minuscolo.

71104
17-07-2007, 20:05
Scrive ogni evento perchè così se gli va via la corrente al massimo perde l'ultima transizione di stato, se capita proprio durante la scrittura. per quello basta salvare il file su una partizione formattata con un filesystem dotato di journaling :D
mica è lui il primo della terra ad avere problemi con la corrente (ANZI -.-' ), ma si tratta di questioni a cui lui non dovrebbe pensare. al limite, se sarà realmente necessario risolvere qualche problema relativo (e non lo sarà), potrà pensarci dopo, ma prima deve risolvere un problema molto più fondamentale: il suo programma non esiste :D e di conseguenza ancora non scrive alcunché. andiamo con ordine e suggeriamogli di fare un programma che memorizzi determinate informazioni e sotto un appropriato comando le scriva su un file. :p

La questione della crescita si risolve con tale evidente semplicità che mi rifiuto di dirlo. a me non sembrava tanto evidente... fatto sta che continuo a non vedere l'utilità di questo approccio a log. l'unico vantaggio è che permette di annullare le varie transazioni, ma non vedo perché questa feature debba essere implementata sul file anziché direttamente in memoria. potrà anche essere che in futuro lui ne senta la necessità, ma direi che non è ancora il momento di pensarci.

nuovoUtente86
17-07-2007, 20:19
yesss.

.

Quanto al quando può essere alla chiusura ma, dopo qualche prova, mi sono stabilizzato sull'uso di una "soglia utile". Vale realmente la pena fare il "dump" solo se il numero di transizioni inutili (le modifiche e gli inserimenti di oggetti che risultano poi eliminati) è proporzionalmente maggiore di quelle utili (gli inserimenti di oggetti). Cioè se ci sono settantamila creazioni e due rimozioni il vantaggio è minuscolo.
Puoi spiegarlo meglio con un esempio magari,grazie

PGI-Bis
17-07-2007, 21:12
Questo è un estratto di un logger concretamente esistente ed in uso.

public RamDataBase readLog(File file) {
...
boolean overwrite = true;
double ratio = 0;
try {
ratio = readLog(...
overwrite = false;
} catch(Exception ex) {
ex.printStackTrace();
} finally {
RamDataBase database = ...
if(overwrite) {
backupAndPack(file, database);
} else if(ratio > PACK_THRESOLD) {
pack(file, database);
}
return database;
}
}

PACK_THRESOLD è il valore limite oltre il quale il programma compatta il log (vale 0.5, più è alto più è probabile che il file sia da compattare).

Il metodo readLog (in verde) è quello che esamina il file di log e rigenera l'elenco di dati (Ricette, Ingredienti e Gruppi di Ricette, per un milione di euro indovinate che lavoro fa il committente... :D).

Restituisce un double. Dal punto di vista della persistenza dei dati, l'applicazione ha nove stati (aggiungi, elimina, cambia per tre tipi).

readLog ha due contatori interi, used e wasted, inizialmente valgono zero. Quando incontra una sezione "aggiungi", aumenta used di 1. Quando incontra una sezione elimina o cambia, aumenta wasted di 1.

Alla fine restituisce il rapporto tra wasted e used. Cioè se ho tanti elimina/cambia e pochi aggiungi allora il valore è alto. Se lo è abbastanza (> PACK_THRESOLD) allora il log viene rigenerato.

mattia.pascal
17-07-2007, 22:01
yesss.

Se togliamo la reversibilità delle transizioni allora lo "stato" del programma è semplicemente l'elenco di dati che si trovano nella struttura dati in memoria.

In teoria basta appunto cancellare il file e dare in pasto al logger stesso tutti i dati in memoria.

In pratica occorre sempre tener presente il grande classico dell'informatica, ovvero "il Giuseppe che mi inciampa nella presa" e rendere quindi transazionale il passaggio dal vecchio al nuovo file di log.

Quanto al quando può essere alla chiusura ma, dopo qualche prova, mi sono stabilizzato sull'uso di una "soglia utile". Vale realmente la pena fare il "dump" solo se il numero di transizioni inutili (le modifiche e gli inserimenti di oggetti che risultano poi eliminati) è proporzionalmente maggiore di quelle utili (gli inserimenti di oggetti). Cioè se ci sono settantamila creazioni e due rimozioni il vantaggio è minuscolo.


Senti mikisx, qua mi pare che stanno proprio andando fuori dal tema della discussione.

Allora a te fondamentalmente interessa come leggere e scrivere dei file. Per questo io ti consiglio di prenderti un buon manuale di C++ e consultare i capitoli dedicati all'argomento. Io testi semplici in italiano da consigliarti non ne conosco. Se conosci discretamente l'inglese e nel frattempo vuoi imparare un po' di programmazione ad oggetti ti consiglio "Thinking in C++", che forse hanno pure tradotto in italiano (scaricabile gratuitamente da internet). Io,se non ce l'hai già, mi comprerei un manuale cartaceo; è sempre comodo averlo. Avere un buon libro da consultare aiuta molto. Quando avrai capito bene cosa si può fare con i file in C++, e avrai fatto qualche prova sarai in grado da solo di scegliere la soluzione più giusta per il tuo scopo. A quel punto potrai scegliere se continuare con i semplici file di testo o passare a qualcosa di più complesso.

nuovoUtente86
17-07-2007, 23:22
Questo è un estratto di un logger concretamente esistente ed in uso.

public RamDataBase readLog(File file) {
...
boolean overwrite = true;
double ratio = 0;
try {
ratio = readLog(...
overwrite = false;
} catch(Exception ex) {
ex.printStackTrace();
} finally {
RamDataBase database = ...
if(overwrite) {
backupAndPack(file, database);
} else if(ratio > PACK_THRESOLD) {
pack(file, database);
}
return database;
}
}

PACK_THRESOLD è il valore limite oltre il quale il programma compatta il log (vale 0.5, più è alto più è probabile che il file sia da compattare).

Il metodo readLog (in verde) è quello che esamina il file di log e rigenera l'elenco di dati (Ricette, Ingredienti e Gruppi di Ricette, per un milione di euro indovinate che lavoro fa il committente... :D).

Restituisce un double. Dal punto di vista della persistenza dei dati, l'applicazione ha nove stati (aggiungi, elimina, cambia per tre tipi).

readLog ha due contatori interi, used e wasted, inizialmente valgono zero. Quando incontra una sezione "aggiungi", aumenta used di 1. Quando incontra una sezione elimina o cambia, aumenta wasted di 1.

Alla fine restituisce il rapporto tra wasted e used. Cioè se ho tanti elimina/cambia e pochi aggiungi allora il valore è alto. Se lo è abbastanza (> PACK_THRESOLD) allora il log viene rigenerato.
Ok,capito il metodo.Ma perchèse il numero di modifiche /eliminazioni è maggiore degli inserimenti riorganizzi il log?

PGI-Bis
18-07-2007, 00:10
Compatto per contenere la dimensione del file di log. Ovviamente nel caso specifico perdo la possibilità di annullare e ripetere le transizioni. Là ho usato il logger per motivi di performance.

Per capire perchè posso scartare i record modifica e rimuovi penso si possa considerare qual'è l'effetto di queste operazioni sullo stato "utile" del programma.

Diciamo che il programma conserva delle ricette. Insiemi di ingredienti, via. Quando creo una nuova ricetta io devo rendere disponibile questa ricetta al resto programma.

Quando modifico una ricetta, la ricetta resta sempre quella, cambiano i suoi ingredienti.

Al programma non interessa il fatto che questi dati siano cambiati. Interessa l'esistenza di una ricetta con i tal ingredienti.

Se il programma termina e poi riparte, il logger che fa: prima crea una ricetta con gli ingredienti originali, poi vede che deve modificarla e la modifica, infine rende disponibile la ricetta modificata.

Vista così l'effetto complessivo, "utile", della creazione e successiva modifica è equivalente alla creazione di una nuova ricetta che abbia direttamente gli ingredienti modificati.

Lo stesso vale per l'eliminazione. Prima l'utente crea la ricetta, poi a un certo punto non la vuole più e la fulmina. Il logger legge il file, crea la ricetta, la elimina e non rende disponibile nulla.

Così l'effetto complessivo di creare una ricetta ed eliminarla risulta essere: non fare un bel niente.

In questo senso lo spazio occupato dai record elimina e modifica è "wasted", sprecato, buttato via. Perchè l'effetto complessivo delle operazioni su un record esistente è pari alla creazione immediata di un record modificato o alla sua "mancata creazione".

Alla fine della fiera, quello che il logger fa non è altro che contare il numero di operazioni multiple rimpiazzabili da una sola e vedere se è rilevante rispetto al numero di operazioni che non sono sostituibili. Se la risposta è sì significa che la percentuale di spazio inutilmente occupata dal file di log è elevata rispetto alla sua dimensione totale.

Elimino tutto e scrivo un record aggiungi per ogni dato presente nel file.



Quando al post precedente, non sono d'accordo sul fatto che siamo fuori tema. Anzi. Il problema che mikisx deve risolvere attiene alla persistenza delle informazioni. E di questo stiamo parlando. Il logger è solo un esempio delle questioni che la persistenza delle informazioni pone al programmatore. Vale a dire trasformazioni di informazioni tra convenzioni di formato attraverso un canale di comunicazione. Il fatto che suoni strano è probabilmente dovuto all'uso del tanto dispregiato file di testo. Ci si dimentica dell'altro pezzo del sistema, la controparte nella memoria volatile. Che ci da un tempo d'accesso minimo costante di: ...

cionci
18-07-2007, 08:21
1:ma come lo devo dichiarare?
char vett[10][20] ?
2:apre il file che dichiaro???
mi sto confondendo!


perchè il 75?
ofstream file; è la dichiarazione di un output file stream.
Apre il chiamato "file.txt" nella directory corrente.
75 è un numero d'esempio...se te ci scrivi vett[0][1] allora ci vai a scrivere vett[0][1].

mikisx
18-07-2007, 15:14
grazie,ho scaricato il libro che mi avete consigliato ,volume 1 tradotto in italiano....
sicuro che puo' essermi d'aiuto per quello che dovro' andare a fare?

mattia.pascal
18-07-2007, 22:13
grazie,ho scaricato il libro che mi avete consigliato ,volume 1 tradotto in italiano....
sicuro che puo' essermi d'aiuto per quello che dovro' andare a fare?

Mi pare che la parte sui file è nel secondo volume.

mikisx
19-07-2007, 01:38
piccola domanda...
qualcuno è in grado di farlo in 1 mese sotto pagamento!?

PGI-Bis
19-07-2007, 01:49
Controlla prima se non ci sia qualcosa di già fatto. Dovrebbe esserci . Prova a cercare su google "gestionale amministrazione condomini".

mattia.pascal
19-07-2007, 09:15
Programmi di questo tipo ne esistono parecchi e costano pure poco.

AngeL)
19-07-2007, 10:17
piccola domanda...
qualcuno è in grado di farlo in 1 mese sotto pagamento!?
ma non c'è più sfizio a fartelo tu? o magari farlo un pezzo per uno..

tornando al programma, e se si fa una cosa tra il log e il file di dati? tipo che memorizza gli ultimi tre database e poi di volta in volta elimina il piu' vecchio per mettere il nuovo? tipo un backup..

es. primo uso del programma, file inesistente, il prog lo crea e poi parte la GUI.
vengono creati due condomini. alla chiusura del prog questo sarà il file:

CONDOMINO
0
mario
rossi
123456
blabla
CONDOMINIO
1
giovanni
verdi
654321
bleble

la seconda volta, il prog legge il file, trova solo un database ed è quindi quello che deve usare, e parte la GUI.
mettiamo che il condominio 0 cambia amministratore e si crea un altro condominio, il file sarà così alla fine del programma:

CONDOMINO //questo è il db vecchio
0
mario
rossi
123456
blabla
CONDOMINIO
1
giovanni
verdi
654321
bleble
-----
CONDOMINO //questo è quello attuale
0
francesco
bianchi
123456
blabla
CONDOMINIO
1
giovanni
verdi
654321
bleble
CONDOMINIO
2
gianni
gialli
321456
blibli

ora il programma, al successivo avvio, trova due database: il primo è un 'backup', l'altro è quello che deve usare. durante l'esecuzione del prog, l'utente elimina il condominio di giovanni verdi. il file sarà così.

CONDOMINO //vecchio
0
mario
rossi
123456
blabla
CONDOMINIO
1
giovanni
verdi
654321
bleble
-----
CONDOMINO //vecchio
0
francesco
bianchi
123456
blabla
CONDOMINIO
1
giovanni
verdi
654321
bleble
CONDOMINIO
2
gianni
gialli
321456
blibli
-----
CONDOMINO //db attuale
0
francesco
bianchi
123456
blabla
CONDOMINIO
2
gianni
gialli
321456
blibli

ora, al successivo avvio, il prog trova 3 db ed usa il terzo.. quando alla fine scriverà su file, scriverà solo il secondo, il terzo, e l'attuale. (quindi il primo viene scartato)
in questo modo si hanno due backup nel caso si faccia una cavolata.

un'altra soluzione potrebbe essere fare comunque il backup, ma su un file diverso, tipo BUdati.txt, che contiene la versione precedente all'ultima modifica, oppure creare un file ogni volta che come nome abbia la data di modifica (dati_12-7-07.txt, dati_15-7-07.txt...) e poi si cancellano a mano i db vecchi che si è sicuri che non serviranno piu' (magari se i file vecchi sono molti si puo' anche implementare una funzione nel programma, che permetta di eliminare tutti i db (file) antecedenti una data (ad es. eliminadb 16-7-07)

mikisx
19-07-2007, 10:33
ho gogolato parecchio,ma nienteche mi piaccia...io capisco di essere molto inesperto in materia programmazione e vorrei un prog fatto su misura,quindi riporgo la domanda:
c'è qualcuno disporso a farlo sotto pagamento?
se siete disponibili aggiungetemi ad msn o chiedete email in pvt....
ciao

mikisx
20-07-2007, 16:24
allora?

PGI-Bis
20-07-2007, 16:33
Apri un nuovo thread in cui dichiari le specifiche del programma oppure richiedi di essere contatto in privato per conoscere i dettagli dell'offerta.

marko.fatto
25-07-2007, 16:49
io come te studio informatica solo da un anno ma rispetto al resto della classe sono mooolto + avanti... il progr ke vuoi te fatto in c++ si fa serenamente in 1-2 giorni senza la parte grafica... avevo fatto a scuola una cosa simile... una rubrica con nome cognome ecc ke veniva salvata su una file, aggiornata ecc... se vuoi aggiungimi su msn e t dico...

mikisx
25-07-2007, 16:51
raga,ho preso il consiglio di un utente,nn sara' come un prog,ma usare excel oppure access