Skocz do zawartości


Close Open
Close Open
Zdjęcie
- - - - -

pascal baza


  • Please log in to reply
35 replies to this topic

#21 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 10 March 2006 - 17:43 PM

dziękuję, miał Pan rację. Zadeklarowanie zmiennych oddzielnie dla każdej procedury pomogło :)
A powi mi Pan jak miałaby wyglądać procedura licząca dla mojej bazy tzn. ja zaczęłam tak że dla wybranego ucznia wiersze od 1 do 21(na próbę do 2-3) dla każdej z kolumn i wynik zapisuje w innej macierzy, choć ona chyba zbyteczna, ale niewiem.

#22

  • Goście

Napisany 10 March 2006 - 18:35 PM

Yyy... Gdzie tu jakis Pan jest????

A jeszcze raz, co ma liczyć ta procedura?

#23 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 11 March 2006 - 10:14 AM

Chodziło mi o to żeby w pętli Licz, umieścić procedurę która liczyła by, po koleji godziny dla poszczególnych tygodni (o tyle wierszy/tygodni ile zażyczymy sobie) w ten sposób, że np. dla 1szego semestru liczylaby od 1 do 21 wiersza dodając wyniki poszczególnych kolumn(każdy wiersz ma 3 kolumny tak aby każda kolumna była dodana w wierszu kolejnym ale w tej samej kolumnie) wierszy i zapisywała je do nowej macierzy(semestr1), tak by potem np osoba[j]+1 mogła być w kolejnym wierszu nowej macierzy o nazwie semestr1.
Niewiem czy dobrze to wytłumaczyłam ale chodzi o najzwyklejsze dodawanie komórek macierzy przez szereg wierszy i zapisanie wyniku jako pierwszego wiersza w nowej macierzy o nazwie semestr1.

#24

  • Goście

Napisany 11 March 2006 - 12:35 PM

Wystarczy zrobić sobie pętlę

repeat ... until

Teraz dwie zmienne pomocnicze wskazujące na tabelę źródłową i docelową. Warunkiem końcowym w pętli będzie osiągnięcie kresu zadanego przedziału. Zaś obie zmiene powinny się zmieniać odpowiednio: jedna po każdym odczycie - druga po każdym zapisie w drugiej tabeli.

A tak wizualnie - przedstaw może to na rysunku, bo coś mi dziś nawala funkcja TWyobraźnia.Rysuj

#25 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 11 March 2006 - 15:51 PM

uczeń 1{osoba[j]} w obecności u niego zawarte są 3 kolumny:
ilość zajęć w tygodniu k[1](łączna-podajemy), obecność k[2] (podajemy),nieobecność k[3](l.godzin-obecność).
Tak jest dla każdego z tygodni (czyli w).
Np. uczeń 1 ma pwrowadzone takie dane z okresu 2 tygodni:
osoba[1]:
w[1](tydzień1), k[1] liczba godzin:40, k[2] obecność:35, k[3] nieobecność:5;
w[2](tydzień2), k[1] liczba godzin:40, k[2] obecność:25, k[3] nieobecność:15;

Chodziło o to żeby dla ucznia1 czyli osoby[j], j:=1; zsumować wartości z kolumn k[1], dla tygodnia1 czyli w[1] i wartośc z kolumny dla tygodnia2 czyli w[2] i wynik zapisać w nowej macierzy np. semestr1 gdzie wynik dla pierwszej osoby czyli osoba[1]{j:=1} zapisane zostaną w pierwszym wierszu nowej macierzy w odpowiednich kolumnach, tak by każdy uczeń(osoba[j]) miał sumę swoich tygodni w godzinach w nowej macierzy np. semestr1.

Myślałam o czymś takim, że zaczynam od j:=1; for osoba[j] to ile do(niewiem jak określić ilośc wprowadzonych osób wcześniej, może np przez zmienną ile jak wczesniej) i wtedy żeby dodawać tylko niewiem jak zapisać k[1] z w[1] + k[1] z w[2]. Mógłby Pan napisać szkielet pętli bo ja mam jak widać niemały problem z pętlą, myślałam nad for to do ale nie wychodzi, z repeat będzie podobnie u mnie.
Dodaj obrazek

#26

  • Goście

Napisany 11 March 2006 - 17:25 PM

Aha, czyli generalnie osoba jest macierzą 3-wymiarową.. Tak z czysto praktycznego punktu - K[1]=K[2]+K[3] - prawda? więc jedna z kolumn jest nadmiarowa.

Jeśli dobrze zrozumiałem, to musiało by to wyglądać tak:
for uczen:=1 to ... do begin
   semestr[uczen].zajec:=0;
   semestr[uczen].obecnosc:=0;
   semestr[uczen].nieobecnosc:=0;
   for tydzien:=1 to ... do begin
      semestr[uczen].zajec:=semestr[uczen].zajec+osoba[uczen][tydzien].zajec;
      semestr[uczen].obecnosc:=semestr[uczen].obecnosc+osoba[uczen][tydzien].obecnosc;
      semestr[uczen].nieobecnosc:=semestr[uczen].nieobecnosc+osoba[uczen][tydzien].nieobecnosc;
   end;
end;
Powinno wystarczyć. Oczywiście Zamiast rekordu .zajec, .obecnosc, .nieobecnosc - można wstawiać kolumny, a więc [1], [2], [3] żeby było, jak w przykładzie.

I raz ejszcze proszę - nie jestem żaden Pan, tylko Dawid!

#27 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 11 March 2006 - 22:51 PM

procedure licz;
 var j,w,k,l,m,s:byte;
  begin
   writeln('Podaj nazwe pliku: ');
   readln(nazwa1);
   assign(plik,nazwa1);
   reset(plik);
   write('Ktorego ucznia chcesz przegladac: ');
   readln(j);
   while not eof(plik) do
  begin
   read(plik,osoba[j]);
   with osoba[j] do
   begin
    semestr1[m,k]:=0; {zeruje macierz semestr}
     for k:=1 to 3 do
      begin
       m:=1;   {ponizej obecnosc ma format w,k}
       semestr1[m,k]:=obecnosc[1,k]+obecnosc[2,k]; {dla 2 tygodni}
      end; 
     writeln;
     writeln(nazw,'  ',imie);
     for k:=1 to z do
      begin
       write(godziny[k]:15,' - ',semestr1[m,k]:2);
      end;
   end;
  end;
  close(plik);
  readln;
 end;
Napisałam procedurkę w oparciu o Twoją powyżej, która liczy obecności z dwóch wcześniej zapisanych tygodni i zapisuje je do macierzy semestr1 a na końcu wyswietla wynik. Tylko dziwne jest to że pytając się o jaką osobę mam policzyć(wyświetlić) mimo iż wyraźnie jest podane program liczy wszystkie jakie zapisane są w pliku z rekordami. Mam też pytanie,jak miałabym zrobić by liczyła ona dla wybranych(a nie jak powyżej wszystkich uczniów) i żeby było to 21 tygodni bo na próbę dałam 2, ale jak widać na dłuższą metę moja procedura nie zda egzaminu.
Przyznam się że trochę się zgubiłam w Twojej procedurze gdy zastosowałam ją u siebie, dlatego zapisałam tak jak powyżej. Wiersze(czyli tygodnie - z macierzy dla każdego ucznia) z podrekordu obecność zastąpiłam cyframi tak jak w innej procedurze zapisywania obecności i działa wszystko ok, ale tak jak wspomniałam to tylko na 2 wiersze(tygodnie) a do 21 musiałabym pisać zbyt dużo, jak mogę to ułatwić by program wiedział o co chodzi?
Przepraszam za tego Pana, już nie będe :)

#28

  • Goście

Napisany 12 March 2006 - 08:36 AM

Po pierwsze - zauważ, że zerujesz tablicę semestr1 w momencie, gdy zmienne m i k nie są jeszcze zainicjalizowane! (nie mają nadanych wartości początkowych)
2. CZemu dodajesz obecności ręcznie z wierszy? Napisałem, że masz w pętli inkrementować w tablicy semestr1 o wartość z tablicy osób k-tego ucznia.
Więc:
.
.
.
    for k:=1 to 3 do
     begin
      semestr1[m,k]:=0; {zeruje macierz semestr}
      m:=1;   {ponizej obecnosc ma format w,k}
       for bleble:=1 to tygodni do
          semestr1[m,k]:=semestr1[m,k]+obecnosc[bleble,k]; {dla 2 tygodni}
     end;
    writeln;
    writeln(nazw,'  ',imie);
    for k:=1 to z do
     begin
      write(godziny[k]:15,' - ',semestr1[m,k]:2);
     end;
.
.
.
Zwróc uwagę jeszcze raz na pętle zagnieżdżoną!

#29 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 15 March 2006 - 10:16 AM

Myślałam że poradzę sobie z tym ale jednak muszę napisać,mam problem z tym sumowaniem godzin. Tzn. program sumuje i jest ok, ale gdy podczas tej samej sesji w programie raz jeszcze wejdę na opcje policzenia godzin to 1sza kolumna dla 1szego ucznia powiększy się (w moim wypadku o 200), natomiast cała reszta pozostaje bez zmian,nawed dla drugiego ucznia nic się nie zmienia,troche nie kapuje czemu tak jest.
Drugą sprawą będzie to, że przy otwarciu danych jest zapytanie, którego konkretnie ucznia ma liczyć a pętla liczy wszystko, pytam bo będę musiała zrobic dla ogółu i pojedyńczo dla każdego.

Wiem że zmienne semestr1 i semestr2 nie należą do rekordu ale chyba powinny być zapisane gdzieś w tym pliku skoro jest otwierany przy liczeniu. Jeśli tak to jak mam sprawić by te zmienne były wraz z rekordem i bez niego pamiętane,bo
próbując odczytać tylko semestr1(który nie należy do bazy) wychodzą mi nie stworzone dane, ale pamięta jednak ostatnie policzne godziny ostatniego ucznia.
Program wygląda tak (deklaracja i pętla liczenia):

const z=3;
      godziny:array[1..z] of string[18]=('ilosc godzin zajec','obecnosc','nieobecnosc');

type dane=record
     nazw:string[20];
     imie:string[15];
     obecnosc:array[1..40,1..3] of word;
     data:record
          dz,mc:byte;
          rok:integer;
          end;
       msc:string[30];
     adres:record
           ul,msc2:string[20];
           dom,mieszk:integer;
           end;
     end;


 var osoba:array[1..40] of dane;
     plik: file of dane;
     nazwa1:string[20];
     dec,dec0,dec1,ob:char;
     semestr1,semestr2:array[1..40,1..3] of word;
     p:string[40];
     label 1,2,3;

 procedure licz;
 var j,w,k,m:byte;
 begin
  writeln('Podaj nazwe pliku: ');
  readln(nazwa1);
  assign(plik,nazwa1);
  reset(plik);
  write('Ktorego ucznia chcesz przegladac: ');
  readln(j);
  while not eof(plik) do
  begin
   read(plik,osoba[j]);
   with osoba[j] do
   begin
     for k:=1 to 4 do
      begin
       semestr1[m,k]:=0;
       m:=1;
        for w:=1 to 4 do
        begin
         semestr1[m,k]:=semestr1[m,k]+obecnosc[w,k];
        end;
      end;
     writeln;
     write(nazw,'  ',imie);
     writeln;
     for k:=1 to z do
      begin
       write(godziny[k]:15,' - ',semestr1[m,k]:2);
      end;writeln;
   end;
  end;
  close(plik);
  readln;
 end;


#30

  • Goście

Napisany 15 March 2006 - 15:28 PM

przeanalizuj linia po linii...
1. ustawiamy k na 1
2. zapisujemy do semestr1[m,k]:=0; - k=1, m=????????
3. ustawiamy m na l.

Nie za późno z tym m???

Jeśli masz problem samodzielnie prześledzić kolejne iteracje, to zapoznaj się z działaniem debugera, naprawdę!

#31 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 18 March 2006 - 12:11 PM

A jak sprawić by program wiedział że chce akurat tego (j-tego) ucznia odczytać, bo schemat
write('Ktorego ucznia chcesz przegladac: ');
 readln(j);
 while not eof(plik) do
 begin
  read(plik,osoba[j]);
  with osoba[j] do
  begin
... dalej pętla licząca obecności;
z powyzszej procedury nie działa i liczy od początku do końca a nie zadane J.

#32

  • Goście

Napisany 21 March 2006 - 10:27 AM

Zwróć uwagę, że czytasz wszystko. Musiałabyś zrobić licznik, który na wartość:
- poniżej j zareaguje continue (zaraz po pobraniu)
- za wartość równej j dokona obliczeń
- na wartość powyżej j zareaguje przez break (nie potrzebujemy dalej)

#33 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 22 March 2006 - 10:48 AM

mniej więcej rozumem czyli np:
jesli jest x>j kontynuuje i rozpatruje poniższe możliwości:
if x=j then liczy i wyswietla
else
if x<j then exit

w jakie miejsce i jak umieścic tę dodatkową zmienną np x, i jak używać jej do odczytu. Tak wizualnie tego nie potrafie zobaczyć.

#34

  • Goście

Napisany 22 March 2006 - 11:31 AM

każde read to odczyt pojedynczego rekordu. A więc po każdym odczycie zwiększasz tą zmienną x, która będzie wskazywać numer rekordu. Dalej porównujesz i albo contiue (w celu wymuszenia następnego przebiegu petli bez dokonywania operacji) albo break w celu bezwarunkowego zakończenia pętli.

#35 Anna_A

Anna_A

    Kandydat

  • Forumowicze
  • PipPip
  • 27 Postów:

Napisany 22 March 2006 - 14:23 PM

A czy to byłoby dobre rozwiązanie, tylko musiałabym jeszcze wymusić po odczycie wybranego rekordu przejscie na koniec pliku by program nie czytał od początku:
procedure licz;
 var x,j,w,k,m:byte;
  begin
  writeln('Podaj nazwe pliku: ');
  readln(nazwa1);
  assign(plik,nazwa1);
  reset(plik);
  {write('Ktorego ucznia chcesz przegladac: ');
  readln(j);}
  while not eof(plik) do
  begin
   read(plik,osoba[j]);
   with osoba[j] do
   begin
     for k:=1 to 4 do
      begin
       semestr1[m,k]:=0;
        for w:=1 to 4 do
        begin
         semestr1[m,k]:=semestr1[m,k]+obecnosc[w,k];
        end;
      end;

     with osoba[j] do
     begin
     write('Ktorego ucznia chcesz przegladac: ');
     readln(x);
     seek(plik,x-1);
     read(plik,osoba[x]);
     writeln;       write(nazw,'  ',imie);
     writeln;
     for k:=1 to z do
      begin
       write(godziny[k]:15,' - ',semestr1[m,k]:2);
      end;
     writeln;
     end;
   end;
  end;
  close(plik);
  readln;
 end;
seek(plik,filesize(plik)); chciałam wyjść za pomocą tego ale jakoś nie bardzo idzie, tzn chciałam ominąc while not eof przez seek(plik,filesize(plik));

#36

  • Goście

Napisany 22 March 2006 - 14:29 PM

Ale aby zamknąc plik wcale nie musisz być na jego końcu. W dowolnym momencie możesz zamknać plik.

Rozwiązanie nie najlepsze, bo nie wiem, co pierwszy odczyt robi. Proponuję wziac to jeszcze raz od początku napisać... Bo usiłujesz zmieniać kody i wprowadzasz tylko bałagan coraz większy. Zwróć uwagę, że 2 razy masz pytanie o to, którego ucznia chcesz przeglądać.




0 Użytkowników czyta ten temat

0 użytkowników, 0 gości, 0 anonimowych użytkowników