.Tigas. Posted February 26, 2012 at 06:05 PM Report Share #441223 Posted February 26, 2012 at 06:05 PM Bem, esta é outra dúvida para o mesmo programa. São procedimentos totalmente diferentes portanto acho que é melhor escrever as coisas aqui. Como podem ver aqui estou a fazer um programa de reserva de bilhetes do Sumol Summer Fest (XD). O meu programa tem 9 procedimentos, 8 dos quais estão presentes num menu: 0. Criar ficheiro (o ficheiro sumol.dat é criado automaticamente se não existir) 1. Ver a informação do cartaz 2. Reservar bilhetes 3. Listagem de bilhetes reservados 4. Cancelar uma reserva de um bilhete 5. Pesquisar uma reserva de um bilhete 6. Editar uma reserva de um bilhete 7. Verificar a stock de bilhetes (agradecimentos ao nunopicado pela ajuda) 8. Sair Funcionam todos perfeitamente excepto o 4º que está a negrito. A minha ideia é a seguinte, passar toda a informação (reservas) contida no ficheiro excepto a que o utilizador decidiu eliminar para outro ficheiro criado (sumol_.dat) e apagar o ficheiro antigo. Depois criava o ficheiro antigo outra vez (sumol.dat) e passava a informação do novo ficheiro para o antigo acabando por apagar o novo. Bem, pelo menos esta foi a única maneira que arranjei de eliminar um registo/reserva visto que não posso apagar uma posição. Ou seja, se eu apagasse uma certa posição: imaginemos que tenho 3 reservas e eu apagava a 2ª reserva o 2º registo ainda lá estava só que vazio e o 3º continuava a ser o 3º. O que eu pretendo é apagar o conteúdo e a posição fazendo com que o registo que vem a seguir, neste caso o 3º passe para o 2º e assim sucessivamente. De qualquer forma, este é o código do meu procedimento: procedure cancelar; //elimina um registo do ficheiro Begin ASSIGN (fich, 'sumol.dat'); RESET (fich); Writeln ('Digite o número da reserva que pretende cancelar.'); Readln (reg); i:=0; //o i funciona como um contador seek (fich, 0); //posicionar no inicio do ficheiro assign (fichNovo, 'sumol_.dat'); rewrite (fichNovo); while not eof (fich) do Begin read (fich, bilhete); if ((reg-1)<>i) then //não é o registo a eliminar write (fichNovo, bilhete); i:=i+1; End; erase (fich); reset (fichNovo); i:=0; seek (fichNovo, 0); assign (fich, 'sumol.dat'); rewrite (fich); //ERRO EXITCODE AQUI NA EXECUÇÃO DO PROGRAMA while not eof (fichNovo) do Begin read (fichNovo, bilhete); if ((reg-1)<>i) then write (fich, bilhete); i:=i+1; End; readln; end; Ah, é verdade, o erro que me dá também é na execução do procedimento em que dá exitcode. Ao fazer execução step over dá-me um erro no rewrite (fich) (que está comentado em CAPS). De notar também que o ficheiro original (sumol.dat) nunca chega a ser eliminado. Estou a usar mal a função erase? Será por causa do ficheiro não ser apagado que o rewrite não funciona? Obrigado desde já. Link to comment Share on other sites More sharing options...
nunopicado Posted February 26, 2012 at 06:27 PM Report Share #441224 Posted February 26, 2012 at 06:27 PM Eu sugeria-te outra maneira de fazeres isso... Implica fazeres uma ou outra alteração no programa, mas creio que seria mais eficaz, ou pelo menos, menos propenso a erros. Adicionavas mais um campo do tipo boolean ao teu record. Algo do tipo Active:Boolean; Depois, quando adicionares uma reserva, colocas esse calor a True. Ao apagares uma reserva, colocas a False. Quando criares a reserva, em vez de a colocares sempre na última posição, irás colocar na primeira que tenha o valor Active = false. No outro procedimento de contagem de stocks, em vez do filesize, usas um while not eof(fich) e contas só os que estão active = true. Pessoalmente, optaria por esta opção. Se quiseres manter o esquema que tens, experimenta não fazeres o erase(fich) e depois o assign novamente. Faz simplesmente rewrite(fich); Já agora, no segundo while, quando estás a passar novamente os dados para o ficheiro principal, não precisas de testar o reg. Nessa fase, os registos que estão no sumol_.dat são todos para passar. "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
.Tigas. Posted February 26, 2012 at 07:26 PM Author Report Share #441239 Posted February 26, 2012 at 07:26 PM Eu sugeria-te outra maneira de fazeres isso... Implica fazeres uma ou outra alteração no programa, mas creio que seria mais eficaz, ou pelo menos, menos propenso a erros. Adicionavas mais um campo do tipo boolean ao teu record. Algo do tipo Active:Boolean; Depois, quando adicionares uma reserva, colocas esse calor a True. Ao apagares uma reserva, colocas a False. Quando criares a reserva, em vez de a colocares sempre na última posição, irás colocar na primeira que tenha o valor Active = false. No outro procedimento de contagem de stocks, em vez do filesize, usas um while not eof(fich) e contas só os que estão active = true. Pessoalmente, optaria por esta opção. Agradeço essa nova opção mas não vou usá-la. Acredita, se pudesse faria o que me sugeriste mas infelizmente o meu professor nunca me ensinou a matéria referente aos valores True/False e Booleans. Acredito que seja fácil mas infelizmente não me dou bem com isso. Ainda estou para estudar essa matéria por mim mesmo quando tiver tempo. :S Se quiseres manter o esquema que tens, experimenta não fazeres o erase(fich) e depois o assign novamente. Faz simplesmente rewrite(fich); OMG! Fiz o que disseste e resultou sem nenhum problema. Obrigado por me safares mais uma vez. x') Já agora, no segundo while, quando estás a passar novamente os dados para o ficheiro principal, não precisas de testar o reg. Nessa fase, os registos que estão no sumol_.dat são todos para passar. Eish, bem visto. Na altura em que me surgiu esta ideia eu fiz C/P e nem pensei nisto. Já editei. 😕 Bem, parece que o programa está 99,99% completo. Amanhã na aula vou fazer os testes finais para confirmar que não há nenhum erro na execução (visto que tenho que apresentar o programa à turma ?). Se calhar adiciono ainda mais uma coisa no programa que tem haver com a stock. Eu informo o utilizador dos bilhetes disponíveis mas mesmo que já tenha ultrapassado o limite dos 30 bilhetes eu posso sempre reservar mais e não quero que isso aconteça. Obrigado por tudo mais uma vez Nuno. 😉 EDIT: Já fiz o que queria. Adicionei o seguinte código ao procedimento de reserva de bilhetes (é basicamente o mesmo que o do stock só que aqui adiciono a exit function para voltar ao menu): y:=FileSize(fich); x:=30; z:=(x-y); If z<=0 then Begin Writeln ('BILHETES ESGOTADOS!'); Writeln ('Não pode reservar mais bilhetes!'); Readln; Exit; End; 🙂 Link to comment Share on other sites More sharing options...
pwseo Posted February 26, 2012 at 08:09 PM Report Share #441243 Posted February 26, 2012 at 08:09 PM (...) mas infelizmente o meu professor nunca me ensinou a matéria referente aos valores True/False e Booleans. (...) O que me leva a perguntar: se não vos ensinou a usar todos os tipos de dados simples (neste caso os booleanos) que está ele a tentar conseguir com os tipos de dados compostos (records)? De qualquer modo, repara que sempre que fazes if condição then instrução estás de facto a utilizar valores booleanos (true/false). Se fosse a ti utilizava a solução dada pelo nunopicado independentemente do teu professor já ter ou não falado desse tipo de dados (e já agora ficas a saber que é dessa forma que funcionam as bases de dados de alta performance). Link to comment Share on other sites More sharing options...
.Tigas. Posted February 26, 2012 at 09:45 PM Author Report Share #441248 Posted February 26, 2012 at 09:45 PM O professor que está a dar este módulo é diferente. E já disse a razão pela qual não vou utilizar a solução que ele sugeriu. Também, se o programa já está feito e a correr como deve ser não vejo porquê inventar. Se eu tivesse 100% certezas do que ia fazer tudo bem mas neste caso dos booleans não tenho e não quero estragar o que tenho feito. Quando arranjar tempo para aprender prometo que começo a usar estas técnicas que me sugeriram. Obrigado. 😕 Link to comment Share on other sites More sharing options...
nunopicado Posted February 26, 2012 at 10:01 PM Report Share #441254 Posted February 26, 2012 at 10:01 PM Realmente é estranho não terem falado dos boolean, estando já a mexer em records e ficheiros, mas... são os professores que temos... Boa sorte, qualquer coisa apita! "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
thoga31 Posted February 26, 2012 at 10:26 PM Report Share #441257 Posted February 26, 2012 at 10:26 PM Abordar dados complexos sem abordar a base das bases dos dados simples, que é o booleano, deixa-me astronomicamente assustado, sem exageros. O tipo de dado boolean é a base de tudo - as condições em quanquer estrutura de controlo trabalham com booleanos. True e False. Nada mais simples. Mas enfim, como diz o @nunopicado, são os professores que temos - a dar o avançado sem dar as bases. E decerto que não estragarias o que tinhas, @.Tigas., ficavas com um programa mais limpo e eficiente. 😕 O professor não deu. Mas eu conselho-te a estudares isso o quanto antes. Auto-aprendizagem é extremamente importante. And the point is, como entendes os Ifs e os ciclos que fazes se nem sabes o que é um booleano? Knowledge is free! Link to comment Share on other sites More sharing options...
passarito Posted February 27, 2012 at 12:02 PM Report Share #441308 Posted February 27, 2012 at 12:02 PM Boas a todos, estive a ler o tópico, e no que se refere aos booleans também eu quero colocar aqui uma acha na fogueira... Estranho o professor não dar booleans nesta altura do campeonato, muito estranho mesmo, porque quando fazes uma condição estás sempre a usar os booleanos que é a base de toda a programação, repara: if i=4 then .... o i=4 é um booleano que pode ser verdadeiro ou falso! se não te dás bem com booleanos experimenta usa um tipo byte, integer, ou algo do género e apenas lhes dás os valores de ZERO ou UM... ORA AÍ TENS UM BOOLEANO FEITO À MEDIDA! E voilá, já podes e deves aplicar o método que o Nuno te disse! Por questão de principio o ZERO é Falso e UM é Verdadeiro. Assim, já podes fazer: if activo=0 then preenche_registo Ainda nos booleanos, como já noutros tópicos se disse, se o professor não ensinou trata de aprender por ti. Nesta área da programação o "autodidactismo" é uma questão normal! Link to comment Share on other sites More sharing options...
nunopicado Posted February 27, 2012 at 12:33 PM Report Share #441318 Posted February 27, 2012 at 12:33 PM Normal, necessária e até desejável... Se eu me tivesse ficado pelo que os professores ensinaram, hoje só sabia fazer programas que calculassem a área de uma figura geométrica qualquer e pouco mais. Nem sempre eles gostavam muito quando eu aparecia com coisas que eles não tinham ensinado (possivelmente por muitas delas ainda nem tinham aprendido), mas como dizia a furriel Silva quando eu estava na tropa, "AZAR!!! Não quero saber de nada disso..." 🙂 Uma sugestão ao Tigas: Tens o programa feito e a trabalhar, excelente. Faz uma cópia de segurança e começas e tentar implementar a estrutura que falei em cima. Se precisares de ajuda, cá estamos para isso. Se entretanto chegar o dia de entregar o trabalho e ainda não tenhas essa nova versão pronta, entregas a cópia que fizeste da solução actual. Se a alteração estiver concluida, ficas com duas à escolha para entregar. Como em tudo na vida, a prática conduz à perfeição, e mesmo que não usásses a alteração por algum motivo, sempre estavas mais à vontade para fazer o próximo programa, nem que não tenha nada a ver com stocks da sumol. Já agora uma nota, para o Tigas, mas também para todos os que andam agora na escola a aprender programação: Há professores que efectivamente não gostam muito que se use coisas que eles não deram. Geralmente porque são nabos e têm medo que o aluno apareça com algo que eles não saibam o que é. Mas atenção que também há professores que deixam certas coisas por dizer, para testar os alunos e ver se eles são capazes de, perante um problema "sem solução", eles são capazes de raciocinar e desencantar a solução sem terem a paparoca toda feita na aula. A estes problemas eu chamo Kobayashi Maru (google it if you want). Este é o meu tipo de professor, e os únicos que eu acho que deviam ser autorizados a dar aulas de programação. Eu pessoalmente tive vários professores de programação, uns maus, uns médios, e uns bons... Adivinhem quem eram os bons? Pois é, esses que eu falei por último. Tive um que nos disse no inicio do ano algo deste género: "Escolham um projecto, qualquer coisa, em qualquer linguagem que vos apeteça. No fim do ano, têm de o apresentar, e é bom que valha um ano de trabalho". Um bem haja ao professor Mario Bernardo, de Águeda... Quem quiz trabalhou, quem não quis mandriou. Ele esteve lá para ajudar quem precisasse (não havia internet 😄 ) mas não oferecia ajuda a ninguém. No fim do ano separou-se os alunos que realmente queriam aprender daqueles que andaram a matar tempo! E bons projectos sairam de lá! "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
.Tigas. Posted February 27, 2012 at 07:46 PM Author Report Share #441372 Posted February 27, 2012 at 07:46 PM Estive a ler o que disseram. É assim, modéstia à parte posso dizer que sou bom entendedor de programação e que sei seguir lógica como deve ser. Percebo todas as matérias que me foram dadas incluindo os ifs e os ciclos que acabaram de mencionar. Também estou disposto a implementar a sugestão que o Nuno me deu no programa. Sendo assim, alguém me pode explicar essa matéria dos booleans como deve ser? Ou mandar-me um link para um guia ou algo do género? É assim, eu percebo as condições do género: (if x:=1 then instruções, etc, etc). Mas tipo, como hei de explicar, não percebo o que o true difere do false (sem ser o óbvio, condição verdadeira e falsa). Como é que o programa sabe o que fazer? Ok, if x:=1 then True. E True significa o quê para o programa? É isso que eu não entendo (e que infelizmente nunca me foi explicado). Quem puder despender algum tempo para ensinar agradeço e tentarei implementar no programa já que ainda tenho esta semana para fazer o programa. Quanto ao que disseram de eu dar o avançado e não dar o básico. Não tenho a certeza do que estou a dizer (porque lá está, nunca dei os booleans) mas o meu professor deve-me ter ensinado técnicas alternativas que simulam os valores true/false mas que eu considero normais e portanto não as menciono aqui (porque lá está, se para mim foram as únicas ensinadas logo não são alternativas e são as regras normais). Isto é só uma adivinha porque como disseram, seria estranho conseguir trabalhar com arrays, records, ciclos, etc e não saber o básico. Link to comment Share on other sites More sharing options...
pwseo Posted February 27, 2012 at 07:57 PM Report Share #441374 Posted February 27, 2012 at 07:57 PM Tigas, Relativamente ao exemplo que deste (if x = 1 then True;), não faz sentido, uma vez que é o mesmo que escreveres algo como if x = 1 then 42;. True, tal como 42, é apenas um valor e não uma instrução. Um exemplo útil seria: var isGood: boolean; begin isGood := checkIfIsGood(); // ...mais coisas aqui... if isGood then doSomething() else doSomethingElse(); end; Claro que neste exemplo podíamos colocar a chamada a checkIfIsGood na própria condição (isto nem sempre será verdade), mas quis apenas reforçar que usamos um boolean para armazenar o resultado dessa função. O que há que perceber aqui é que os booleanos são valores que representam um de dois estados: verdadeiro ou falso. São utilizados quando precisas de representar dicotomias no teu programa, como por exemplo, saber se um determinado registo está ou não activo. Noutras linguagens (pensemos em C), não há um tipo de dados booleano, e como tal representa-se isso num int, onde 0 é falso e todos os outros valores são verdadeiros. Não há praticamente mais nada a saber sobre isto... Se tiveres alguma dúvida específica coloca-a 🙂 Link to comment Share on other sites More sharing options...
bsccara Posted February 27, 2012 at 08:34 PM Report Share #441378 Posted February 27, 2012 at 08:34 PM Desculpem-me o 'off-topic' mas as dificuldades do OP lembraram-me da primeira vez em que ouvi falar em computadores. Lá para 1980 um amigo meu disse-me que tinha lido num sítio qualquer sobre uma máquina espectacular, que permitia jogar jogos gravados em cassete. Como na altura já andava metido na electrónica achei aquilo muito interessante mas fiquei com uma dúvida enorme: se os jogos são gravados numa cassete, a cassete toca sempre o mesmo (o que lá está gravado), então o jogo era sempre a mesma coisa; raquete para cima, raquete para baixo. Como raio é que o jogo responderia às minhas acções ? Só esclareci essa dúvida quando comprei o manual traduzido do ZX81 (melhor livro técnico que alguma vez vi) e me iniciei na programação. Voltando ao tópico, o jogo varia precisamente por causa dos True e False. Link to comment Share on other sites More sharing options...
.Tigas. Posted February 27, 2012 at 09:04 PM Author Report Share #441381 Posted February 27, 2012 at 09:04 PM Tigas, Relativamente ao exemplo que deste (if x = 1 then True;), não faz sentido, uma vez que é o mesmo que escreveres algo como if x = 1 then 42;. True, tal como 42, é apenas um valor e não uma instrução. Um exemplo útil seria: var isGood: boolean; begin isGood := checkIfIsGood(); // ...mais coisas aqui... if isGood then doSomething() else doSomethingElse(); end; Claro que neste exemplo podíamos colocar a chamada a checkIfIsGood na própria condição (isto nem sempre será verdade), mas quis apenas reforçar que usamos um boolean para armazenar o resultado dessa função. O que há que perceber aqui é que os booleanos são valores que representam um de dois estados: verdadeiro ou falso. São utilizados quando precisas de representar dicotomias no teu programa, como por exemplo, saber se um determinado registo está ou não activo. Noutras linguagens (pensemos em C), não há um tipo de dados booleano, e como tal representa-se isso num int, onde 0 é falso e todos os outros valores são verdadeiros. Não há praticamente mais nada a saber sobre isto... Se tiveres alguma dúvida específica coloca-a 🙂 Sim, sim, eu não disse que aquilo estava correcto. Foi só para entenderem a minha perspectiva que é: eu não sei. XD Quanto ao programa, fiz uma pesquisa e acho que já entendi. Por exemplo, este programa: Program sair; Var sair: Boolean; a: char; Begin Repeat Write('Digite s para sair.'); Readln(a); If a = 's' then quit := True else quit := False; If quit = True then exit; Until quit = True; End. Seria o mesmo se eu tivesse um if a='s' then exit. Se é assim, para quê criar uma variável quando posso fazer a mesma coisa sem ocupar espaço nas variáveis? Não entendo a razão de ser disto. E como tal, ainda não entendo a sugestão que o Nuno me deu. Para já nem entendo bem a ideia mas mesmo que eu a aplicasse, isso não faria com os registos se dispersassem pelo ficheiro? Ou seja, o 1º registo a ser introduzido teria a posição 3, o 2º teria a posição 7 e assim sucessivamente. É que isso não me dá jeito nenhum porque no meu programa tenho um procedimento editar que pede ao utilizador a posição que ele pretende editar. Provavelmente estou a perceber mal as coisas porque estou a aprender isto agora (lol) mas é o que estou a entender. EDIT: GeSHi adicionado. thoga31 Link to comment Share on other sites More sharing options...
nunopicado Posted February 27, 2012 at 09:27 PM Report Share #441388 Posted February 27, 2012 at 09:27 PM É isso Tigas, mas com alguns ajustes (o que fizeste funciona, mas pode ser optimizado): a='s' -> Isto é uma condição, logo já é ela mesma True ou False (ou é igual ou não). Como tal, podes fazer isto: quit := a='s'; // Vai atribuir à variável quit o valor da expressão a='s' Pelo mesmo motivo, quit = true não tem de ser usado. Bastava usares: . . until quit; // Repete até que quit seja True Quanto à utilidade: Efectivamente no exemplo que deste, não serviria de muito usar o boolean. o Quit resolvia. Mas imagina que tens um ciclo em que se a tecla for s ele tem de sair, mas tem tem de indicar se o utilizador não conseguiu acertar na tecla à primeira... Program sair; Var Falhou,Sair: Boolean; a: char; Begin Falhou:=False; // Assumimos à partida que ele não falhará Repeat Write('Digite s para sair.'); Readln(a); If a <> 's' then Falhou:=True; // Se a não for 's', então o utilizador falhou Sair:= a='s'; // Sair ficará com o valor da expressão a='s', seja True ou False Until Sair; // Repete até Sair = True (o =True é subentendido pelo compilador) if Falhou // Se Falhou é verdadeiro, executa o Then, se for False executa o Else then writeln('O utilizador não conseguiu sair à primeira') else writeln('Muito bem, acertou à primeira!'); End. "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
pwseo Posted February 27, 2012 at 09:33 PM Report Share #441389 Posted February 27, 2012 at 09:33 PM Tigas, A vantagem de usar variáveis é poderes incorporá-las num record, por exemplo. Ou imagina uma situação em que uma determinada função devolve um booleano que tens que armazenar antes de o utilizar (com procedimentos entre as duas instruções). De qualquer modo, voltando ao problema dos registos, seria fácil: fazes uma lista que relacione a posição "no ecrã" com a posição real do registo (chamemos-lhe ID) e tudo ficará bem. No teu programa não há problema nenhum em fazer como fizeste... Mas se estivéssemos a falar de uma base de dados com milhares e milhares de registos, seria complicado ter que reescrever todo o ficheiro sempre que apagasses um registo. Link to comment Share on other sites More sharing options...
nunopicado Posted February 27, 2012 at 09:41 PM Report Share #441392 Posted February 27, 2012 at 09:41 PM Quanto à minha sugestão: Funcionará possivelmente até melhor do que eliminando fisicamente, visto estares a usar o numero do registo para chamar as reservas. Por exemplo, reservas a numero 1. Depois reservas a 2, e novamente, a 3. Agora queres cancelar a 1. Como estás a fazer, a 2 passará a ser 1, a 3 passará a ser 2. Mas o cliente tinha a reserva 3 e agora quando vais chamar, já não existe, porque a dele agora é 2. Estás a ver a confusão que isto pode criar? Pelo método comum, que te sugeri: Por exemplo, reservas a numero 1. Depois reservas a 2, e novamente, a 3. Agora queres cancelar a 1. Para tal, apenas colocar a variável Valido (ou outro nome qualquer) a False. Esta variável tem de fazer parte do próprio record. Neste momento, a reserva está virtualmente eliminada. Virtualmente, porque não a apagaste mesmo. Simplesmente disseste que afinal já não é válida. A partir daqui o programa ignora-a para todos os efeitos, o que na prática é o mesmo que estar apagada. Claro que isto implica que prepares o programa para a ignorar. Por exemplo, quando consultas uma reserva. Queres consultar a 1 (depois de a apagar). O programa não pode simplesmente ler o registo e mostrá-lo. Deverá ler, e testar se Valido é True. Se for, mostra. Se não for, ignora (porque significa que está apagada). Podes se quiseres é aproveitar que a reserva não foi mesmo apagada, e se consultares uma que tenha Valido = False, dizes ao utilizador que essa reserva foi apagada, e perguntas se quer recuperar (basta voltar a meter a true para ela ficar valida novamente). Para contar as reservas, basta contares quantos registos têm Valido = True. Deste modo, além do programa ficar mais eficaz (andares a transferir dados entre ficheiros é pedir para dar problemas), o numero da reserva é sempre único independentemente de apagares reservas ou não, podes "desapagar" reservas, etc. Se ainda houver algo que não percebas desta "ideia" avisa. PS: Para teres uma ideia, o teu sistema operativo funciona mais ou menos assim. Quando apagas um ficheiro, seja windows, mac, linux, etc., estás somente a apagar um índice, e não o próprio ficheiro. "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
.Tigas. Posted February 27, 2012 at 09:53 PM Author Report Share #441396 Posted February 27, 2012 at 09:53 PM É isso Tigas, mas com alguns ajustes (o que fizeste funciona, mas pode ser optimizado): a='s' -> Isto é uma condição, logo já é ela mesma True ou False (ou é igual ou não). Como tal, podes fazer isto: quit := a='s'; // Vai atribuir à variável quit o valor da expressão a='s' Pelo mesmo motivo, quit = true não tem de ser usado. Bastava usares: . . until quit; // Repete até que quit seja True Quanto à utilidade: Efectivamente no exemplo que deste, não serviria de muito usar o boolean. o Quit resolvia. Mas imagina que tens um ciclo em que se a tecla for s ele tem de sair, mas tem tem de indicar se o utilizador não conseguiu acertar na tecla à primeira... Program sair; Var Falhou,Sair: Boolean; a: char; Begin Falhou:=False; // Assumimos à partida que ele não falhará Repeat Write('Digite s para sair.'); Readln(a); If a <> 's' then Falhou:=True; // Se a não for 's', então o utilizador falhou Sair:= a='s'; // Sair ficará com o valor da expressão a='s', seja True ou False Until Sair; // Repete até Sair = True (o =True é subentendido pelo compilador) if Falhou // Se Falhou é verdadeiro, executa o Then, se for False executa o Else then writeln('O utilizador não conseguiu sair à primeira') else writeln('Muito bem, acertou à primeira!'); End. Penso que percebi que tudo mas quero confirmar uma coisa. O true é sempre para os thens e o false é sempre para os elses? Do género, True tem o valor esperado (por exemplo 1) logo (then) faz x instruções. False tem o valor inesperado (por exemplo 0) logo (else) faz y instruções. Tigas, A vantagem de usar variáveis é poderes incorporá-las num record, por exemplo. Ou imagina uma situação em que uma determinada função devolve um booleano que tens que armazenar antes de o utilizar (com procedimentos entre as duas instruções). De qualquer modo, voltando ao problema dos registos, seria fácil: fazes uma lista que relacione a posição "no ecrã" com a posição real do registo (chamemos-lhe ID) e tudo ficará bem. No teu programa não há problema nenhum em fazer como fizeste... Mas se estivéssemos a falar de uma base de dados com milhares e milhares de registos, seria complicado ter que reescrever todo o ficheiro sempre que apagasses um registo. Certo. Realmente faz sentido, nesses projectos grandes seria trabalhoso para o programador fazer o que fiz e também usava mais memória desnecessariamente. Quanto à minha sugestão: Funcionará possivelmente até melhor do que eliminando fisicamente, visto estares a usar o numero do registo para chamar as reservas. Por exemplo, reservas a numero 1. Depois reservas a 2, e novamente, a 3. Agora queres cancelar a 1. Como estás a fazer, a 2 passará a ser 1, a 3 passará a ser 2. Mas o cliente tinha a reserva 3 e agora quando vais chamar, já não existe, porque a dele agora é 2. Estás a ver a confusão que isto pode criar? Pelo método comum, que te sugeri: Por exemplo, reservas a numero 1. Depois reservas a 2, e novamente, a 3. Agora queres cancelar a 1. Para tal, apenas colocar a variável Valido (ou outro nome qualquer) a False. Esta variável tem de fazer parte do próprio record. Neste momento, a reserva está virtualmente eliminada. Virtualmente, porque não a apagaste mesmo. Simplesmente disseste que afinal já não é válida. A partir daqui o programa ignora-a para todos os efeitos, o que na prática é o mesmo que estar apagada. Claro que isto implica que prepares o programa para a ignorar. Por exemplo, quando consultas uma reserva. Queres consultar a 1 (depois de a apagar). O programa não pode simplesmente ler o registo e mostrá-lo. Deverá ler, e testar se Valido é True. Se for, mostra. Se não for, ignora (porque significa que está apagada). Podes se quiseres é aproveitar que a reserva não foi mesmo apagada, e se consultares uma que tenha Valido = False, dizes ao utilizador que essa reserva foi apagada, e perguntas se quer recuperar (basta voltar a meter a true para ela ficar valida novamente). Para contar as reservas, basta contares quantos registos têm Valido = True. Deste modo, além do programa ficar mais eficaz (andares a transferir dados entre ficheiros é pedir para dar problemas), o numero da reserva é sempre único independentemente de apagares reservas ou não, podes "desapagar" reservas, etc. Se ainda houver algo que não percebas desta "ideia" avisa. PS: Para teres uma ideia, o teu sistema operativo funciona mais ou menos assim. Quando apagas um ficheiro, seja windows, mac, linux, etc., estás somente a apagar um índice, e não o próprio ficheiro. É assim, eu penso que já estou a perceber a ideia. No entanto, ainda não me sinto preparado para editar o meu projecto que é um pouco grande. Vou tentar mas duvido que consiga alguma coisa. Link to comment Share on other sites More sharing options...
nunopicado Posted February 27, 2012 at 10:23 PM Report Share #441406 Posted February 27, 2012 at 10:23 PM Penso que percebi que tudo mas quero confirmar uma coisa. O true é sempre para os thens e o false é sempre para os elses? Do género, True tem o valor esperado (por exemplo 1) logo (then) faz x instruções. False tem o valor inesperado (por exemplo 0) logo (else) faz y instruções. No caso do IF, se o valor da expressão for True, é executado o Then, se for False é executado o Else. Podes sempre alterar o valor da expressão colocando o NOT atrás, caso queiras que o comportamento seja o inverso. Certo. Realmente faz sentido, nesses projectos grandes seria trabalhoso para o programador fazer o que fiz e também usava mais memória desnecessariamente. Exacto. É assim, eu penso que já estou a perceber a ideia. No entanto, ainda não me sinto preparado para editar o meu projecto que é um pouco grande. Vou tentar mas duvido que consiga alguma coisa. Não te esqueças de alterar uma cópia. Tens o programa pronto, não vale a pena arriscar a ficares sem um nem outro. De qualquer maneira, fica à vontade para expor duvidas. Tentando antecipar o que vais encontrar, e se não me falha a memória, vais precisar de: 1. Adicionar uma variável boolean ao teu tipo record 2. Alterar o procedimentos seguintes: 0. Criar ficheiro (o ficheiro sumol.dat é criado automaticamente se não existir) // Sem alteração 1. Ver a informação do cartaz // O que faz este? 2. Reservar bilhetes // Antes de gravares o registo no ficheiro tens de incluir um Bilhete.Valido := True; 3. Listagem de bilhetes reservados // Terás provavelmente um while not eof(fich) do neste procedimento a ler os dados e escrever no ecrã, certo? Terás de por um if bilhete.valido then begin <bla bla bla> end; 4. Cancelar uma reserva de um bilhete // Basta ler a reserva escolhida, alterar o bilhete.valido para False, e voltar a gravar esse registo. 5. Pesquisar uma reserva de um bilhete // Incluir um if como em cima na listagem. Se for Bilhete.Valido = True, mostra os valores. 6. Editar uma reserva de um bilhete // Como no 3 e no 5, incluir um if Bilhete.Valido then .... Se quiseres podes acrescentar um else a esse if, e perguntar se quer reactivar a reserva eliminada 7. Verificar a stock de bilhetes (agradecimentos ao nunopicado pela ajuda) // Metes um while not eof(fich) do e uma variavel Cont:Integer que deverá ser inicializada a 0 antes do while. Depois, dentro do while, lês o registo, e metes um if bilhete.valido then inc(cont); No fim, a variavel Cont terá o total de bilhetes reservados. (inc(cont); é a mesma coisa que meter Cont:=Cont+1;) 8. Sair Alguma duvida, apita... 🙂 "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
.Tigas. Posted February 29, 2012 at 09:20 AM Author Report Share #441564 Posted February 29, 2012 at 09:20 AM No caso do IF, se o valor da expressão for True, é executado o Then, se for False é executado o Else. Podes sempre alterar o valor da expressão colocando o NOT atrás, caso queiras que o comportamento seja o inverso. Exacto. Não te esqueças de alterar uma cópia. Tens o programa pronto, não vale a pena arriscar a ficares sem um nem outro. De qualquer maneira, fica à vontade para expor duvidas. Tentando antecipar o que vais encontrar, e se não me falha a memória, vais precisar de: 1. Adicionar uma variável boolean ao teu tipo record 2. Alterar o procedimentos seguintes: 0. Criar ficheiro (o ficheiro sumol.dat é criado automaticamente se não existir) // Sem alteração 1. Ver a informação do cartaz // O que faz este? 2. Reservar bilhetes // Antes de gravares o registo no ficheiro tens de incluir um Bilhete.Valido := True; 3. Listagem de bilhetes reservados // Terás provavelmente um while not eof(fich) do neste procedimento a ler os dados e escrever no ecrã, certo? Terás de por um if bilhete.valido then begin <bla bla bla> end; 4. Cancelar uma reserva de um bilhete // Basta ler a reserva escolhida, alterar o bilhete.valido para False, e voltar a gravar esse registo. 5. Pesquisar uma reserva de um bilhete // Incluir um if como em cima na listagem. Se for Bilhete.Valido = True, mostra os valores. 6. Editar uma reserva de um bilhete // Como no 3 e no 5, incluir um if Bilhete.Valido then .... Se quiseres podes acrescentar um else a esse if, e perguntar se quer reactivar a reserva eliminada 7. Verificar a stock de bilhetes (agradecimentos ao nunopicado pela ajuda) // Metes um while not eof(fich) do e uma variavel Cont:Integer que deverá ser inicializada a 0 antes do while. Depois, dentro do while, lês o registo, e metes um if bilhete.valido then inc(cont); No fim, a variavel Cont terá o total de bilhetes reservados. (inc(cont); é a mesma coisa que meter Cont:=Cont+1;) 8. Sair Alguma duvida, apita... 🙂 O procedimento do cartaz só mostra um cartaz que eu fiz com writelns. Não está gravado num ficheiro, está feito no programa mesmo. É este: procedure cartaz; Begin Writeln (' _________________________________________________________'); Writeln ('| |'); Writeln ('| CARTAZ 2012 - SUMOL SUMMER FESTIVAL |'); Writeln ('|_________________________________________________________|'); Writeln ('| Dia 1 | Dia 2 |'); Writeln ('|__________________________|______________________________|'); Writeln ('| Israel Vibrations (19:30)| Ponto de Equilibrio (19:40) |'); Writeln ('| Natiruts (20:40)| Dezarie (20:50) |'); Writeln ('| Matisyahu (21:50)| Rebelution (22:00) |'); Writeln ('| SOJA (23:00)| Dub Inc (23:10) |'); Writeln ('| Anthony B (00:10)| Damian Marley (00:20) |'); Writeln ('|--------------------------|------------------------------|'); Readln; End; Basicamente o utilizador digita 1 no menu se quiser ver o cartaz. São questões estéticas, nada que contribua para o programa em si. x) Obrigado. Vou tentar fazer. Link to comment Share on other sites More sharing options...
nunopicado Posted February 29, 2012 at 09:23 AM Report Share #441565 Posted February 29, 2012 at 09:23 AM Ah, ok... Então força! Qualquer coisa, avisa! "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now