ArrayList obsługa

0

Mam dwa problemy po kolei je opisze.
Mam dwie tablice:

public static ArrayList<Double> aRate = new ArrayList<Double>( );
public static ArrayList<Object> aPrzedmiot = new ArrayList<Object>( );
aPrzedmiot.add("Matematyka");
	aPrzedmiot.add("Polski");
	aPrzedmiot.add("Angielski");

aRate.add(2.0);
	aRate.add(3.0);
	aRate.add(3.5);
	aRate.add(4.0);
	aRate.add(4.0);
	aRate.add(5.0);

Przedmioty musza byc jak powyzej, oceny maja byc takie ale... i tu pierwszy problem

 case 1:
    	System.out.println("Dodajesz oceny do matematyka");
    	
    	for(int i = 0 ; i <= 4 ; i++)
        {	
    		Collections.shuffle(aRate);	    
    		 for(Double str: aRate){
    	            System.out.println(str );
    	        }
        }
      break;

Chce zeby do aRate bylo losowane 20 ocen takich jak 2,3,3.5,4,4.5,5 . Na ten moment wymyslilem jedynie opcje ze oceny sa dodane na sztywno i przemieszane, ale liczac chodzby srednia z tego zawsze wychodzi to samo ;/
Jak to rozwiazac ? Probowalem jakims random ale nic mi nie dziala z przykadlow internetowych, wiec prosil bym o jakis schemat czy cos co by zadzialalo?

Drugi problem

System.out.println("Dodajesz oceny do matematyka");

Chce by oceny byly dodane podpięte pod dany przedmiot. Wybieranie tego juz zrobilem i cala obsluge. Nie mam wgl pomyslu i nie wiem jak to obsłużyć w jave.

Gdyby to byla tablica to bym jakos to przypisal chodz tez nie.. bo aRate to oceny ktorych z zalozenia ma byc X. a aPrzedmiot to nazwy czyli jakby string, to moj wymysl ze dalem to jako object.

Jakis warunek , jakis if? petla ? pomysl?
bede bardzo wdzieczyny za pomoc..

1

Ad1. Ja bym użył metody https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#nextInt-int- i

schemat

1. utwórz obiekt Random
2. z utworzonego wcześniej obiektu Random pobierz wartość losową
2. z utworzonego wcześniej obiektu Random pobierz wartość losową
2. z utworzonego wcześniej obiektu Random pobierz wartość losową
2. z utworzonego wcześniej obiektu Random pobierz wartość losową
...

a co dokładnie Ci nie działało?

Ad2. Obecnie oceny nie są powiązane z przedmiotami, więc co masz na myśli pisząc

Wybieranie tego juz zrobilem i cala obsluge.
?
Proponuję HashMap<List>

2

Utwórz klasę - Przedmiot, która będzie zawierała listę(lub też tablicę) ocen oraz nazwę przedmiotu.

0

ad1. sprawdze

ad2.
z obsluga chodzilo o to ze zrobilem switcha w swichu czyli wybierz uzytkownika wybierz przedmiot ale gdy wybieram przedmiot i chce dla niego liczyc to zonk bo w przedmiocie nie ma ocen czyli sredniej(niech to bedzie srednia) nie policzy

HashMap<List> --> co to da jak uzywam ListArray a samo List jest z innej biblioteki? jak to obsluzyc?

pomysl z klasa przedmiot no ok.. ale czy lista ocen nie powinna byc w klasie uczen ? w koncu oceny sa przypisane do konkretnej osoby

przeniesc liste i metody sie da ale jesli tak postapie to:
-przedmiot bedzie mial swoje oceny to plus!
-uczen nie bedzie mial ocen? bedzie mial tylko ocene z konkretnego przedmiotu
i tu sie zrodzi problem jak liczyc srednia ogolna dla ucznia ktory bedzie w klasie uczen(lista uczniow w klasie uczen)
-srednia z przedmiotu licze w klasie przedmiot teraz

  • w jakiej klasie licze srednia ogolna?(gdzie taka metoda powinna sie znajdowac)

Z innej beczki:
jezeli tworze ArrayList w klasie np Uczen i jest to ListaUczniow to nie moge sie juz do tej listy odwolac np w klasie przedmiotu? chyba ze da sie to jakos zrobic? probowalem nadawac public ale to nie pomaga, lista jest dostepna tylko wewnatrz jednej klasy

1

Nie korzystasz z ListArray tylko z ArrayList. A ArrayList jest klasą implementującą interfejs List. Jeżeli nie wiesz co oznacza poprzednie zdanie, to musisz się jeszcze pouczyć javy (do czego zachęcam), a do tego czasu załóż, że napisałem tam HashMap<ArrayList>.

Wcześniej nie wspominałeś, że będzie więcej niż jeden uczeń... No cóż, warto do tego podejść zupełnie inaczej:

Mamy następujące połączenia między danymi: Przedmiot -< Ocena >- Uczeń >- Klasa (jeżeli jest tylko jedna klasa, to można ją pominąć), gdzie X -< Y oznacza, że X zawiera wiele Y, ale jeden Y jest przypisany tylko do jednego X. A zatem każdy obiekt Przedmiot powinien mieć listę przypisanych do niego obiektów Ocena. Tak samo każdy obiekt Uczeń. Natomiast każdy obiekt Ocena powinien mieć w atrybucie zapisany obiekt Przedmiot i w drugim atrybucie obiekt Uczeń.

I teraz w Przedmiot masz metodę średnia() liczącą średnią dla przedmiotu, a w Uczeń masz metodę średnia() liczącą średnią dla ucznia.

Trochę się zgubiłem w twoich pytaniach. Ponów te, których nie rozwiązuje powyższe rozwiązanie...:)

1

Ja też się pogubiłem w tym co autor już zrobił, i jakie "raporty" chce uzyskiwać. Być może wystarczą: lista możliwych ocen (już istnieje - aRate), lista przedmiotów (też istnieje - aPrzedmiot, nie wiem dlaczego zawiera Objecty a nie Stringi), lista uczniów i jedna typu ArrayList<Ocena>, klasa Ocena ma takie pola:

class Ocena
{
     double rate;
     String przedmiot;
     //identyfikator ucznia
}
0

Dobra jeszcze raz.
Program ma byc dziennikiem gdzie mamy ucznikow i dodajemy ocene(w sumie losujemy) do konkretnego przedmiotu.
Z logicznego pkt widzenia
Powinny byc klasy:
1.Dziennik -> klasa glowna (?) -> w dzienniku lista uczniow?
2.Uczen - > wlasciwosci ucznia -> ( czy lista uczniow ma byc tu czy raczej w klasie dziennik)?
3.Przedmiot -> powinna zawierac liste przedmiotow i liste ocen? -> a moze lista przedmiotow powinna byc w dzienniku jak lista uczniow?
4. Ocena -> ??? Tylko dla na potrzeby listy?

Jezeli tworze liste to, nie pisze object tylko :

public static ArrayList<Uczen> aUsers = new ArrayList<Uczen>( );   --->>>???? czy to jest poprawne?

private static  ArrayList<Ocena> aRate = null;
public static ArrayList<Dziennik> aPrzedmiot = new ArrayList<Przedmiot>( );

cos w tym stylu?

i teraz najwazniejsze !!?
pkt1.
Jesli mam liste np uczniow w klasie Dziennik to jak kurde powiazac ja z lista ocen z klasy Ocena.
Piszac w klasie np. dziennik aRate. - nic mi sie nie wyswietli bo to nie ma zadnego powiazania listy nie staja sie publiczne na zasadzie z klasy do klasy.

pkt2.
Czy tworzac liste ocen w klasie przedmiot bede mogl dodac ocene do odpowiedniego przedmiotu dodanego statycznie na zasadzie

aPrzedmiot.add("matematyka");
aPrzedmiot.add("polski");

itp..
czy i jak przypisac ocene a moze bedzie ona przypisana do takiej matematyki po dodaniu jej odpowiednia metoda.

1

Potrzebujesz 4 klas, takich jak napisałeś:

  1. Dziennik - zawiera listę Uczniów, listę Przedmiotów i listę Ocen
  2. Uczeń - zawiera dane ucznia i listę wszystkich jego ocen
  3. Przedmiot - zawiera dane przedmiotu i listę wszystkich ocen związanych z tym przedmiotem
  4. Ocena - zawiera ocenę właściwą (np. wyrażoną liczbowo), informację z jakiego przedmiotu jest oceną i jakiego ucznia jest oceną

Zważywszy na powyższe atrybuty z listami nie powinny być static, bo dotyczą one tego konkretnego dziennika tej konkretnej klasy (w sensie tego konkretnego zbioru nieletnich). Gdybyś miał zamiar mieć dzienniki kilku klas można się zastanawiać czy lista przedmiotów nie powinna być statyczna, ale jak masz jeden, to zdecydowanie nie.

Tak, piszesz w <> nazwę klasy, której obiekty będą zawarte na liście (lub nazwę którejś z jej nadklas lub nazwę interfejsu, który implementuje, ale chyba nie jesteś jeszcze tak zaawansowany). Generalnie powinieneś wpisać tą klasę przy deklaracji atrybutu, ale nie musisz przy tworzeniu nowego obiektu (zawsze to trochę mniej kodu), zawartość <> można pozostawić pustą.

Czyli

public ArrayList<Uczen> users = new ArrayList<>( );
private ArrayList<Ocena> = new ArrayList<>( );
public ArrayList<Przedmiot> przedmioty = new ArrayList<>( );

Odpowiedzi na dwa ostatnie są zawarte na samej górze tego postu. Zauważ, że zgodnie z tym co napisałem Przedmiot nie jest stringiem, tylko osobną klasą zawierającą m.in. nazwę przedmiotu (czyli tego stringa), ale też listę ocen.

1

Jeśli Uczeń i Przedmiot zawierają listę ocen, oraz Ocena zawiera informację o uczniu i przedmiocie to mamy sporą nadmiarowość i utrudnienia przy aktualizacji. Jestem za tym by Uczeń i Przedmiot nie mieli listy ocen.

1

Można i tak, ale wtedy aby wyliczyć średnią przedmiotu (lub ucznia) będziemy potrzebowali wyselekcjonować oceny z danego przedmiotu (lub danego ucznia), a tak będzie już gotowe.

Nie sądzę by nadmiarowość w przypadku tej wielkości projektu miała znaczenie, za to @viamarimar bardziej się nauczy jak używać języka obiektowego jakim jest java. Nie widzę też utrudnień przy aktualizacji, dodanie obiektu do dwóch list, to tylko dwie dodatkowe linie, które można dodać w konstruktorze Oceny. Podtrzymuję wersję z listami ocen;p

0

będę próbował zastosować się kolejno do wskazówek ale przedemną pierwszy haczyk ..

dodaje ucznia do aUczen:

for(int i = 1 ; i <= ile ; i++)
	    {	
		System.out.println("Podaj imie i nazwisko: " + i);
		Uczen u = new Uczen();
		u.sDane = sc.nextLine();
		aUczen.add(u);
		System.out.println(u.sDane);
		
	    }

i chce to wyswietlic, otrzymuje pustke:

 for (int i = 0; i < aUczen.size(); i++) {
				System.out.println(aUczen.get(i));
			}

Rozumiem ze informacje z danymi dodaje do u.sDane , zas do listy zostaje wpisany "caly" uczen czyli u, zwrocony tez jako u ale jak dobrac sie do u.sDane czyli jak go wyswietlic w takiej petli

bo aUczen.sDane ->> nie ma takiej opcji nawet i nie wiem czy by sie dalo

1

Jeszcze jeden post bez wstawienia kodu w znaczniki <code class="java"></code> i wątek ląduje w koszu.
Są co najmniej dwa sposoby:
1.

System.out.println(aUczen.get(i).sDane);

jeżeli pole sDane jest public. Jeśli nie, to dopisz (wygeneruj) odpowiedni getter.
2. Napisz w klasie Uczen metodę

public String toString(){
    return sDane;
}

Wtedy wystarczy

System.out.println(aUczen.get(i));
0

Jak stworzyc identyfikator oceny?
W sensie zeby ocena byla przypisana do uzytkownika. Pomysl z ID w klasie ocena jest fajny, ale ..
stworzylem nawet ID uzytkownika ale nie potrafie przypisac go do klasy ocena i tamtego ID.

Przeciez tworzac uzytkownika nie moge rownoczenie tworzyc mu oceny bo to bezsensu.

1

Moja szklana kula mówi, że w pętli otaczającej switch tworzysz obiekt d. W konsekwencji, w niedziałającym kodzie, d w case 2 jest inne niż d w case 1 (jest puste).
W klasie mogą być np. dwie Joanny Fogiel, zatem imię i nazwisko nie wystarczy do rozróżniania uczniów. Mój pomysł był taki:

public class Uczen{
     String dane = "";
     int id = 0;
     static int licznik = 1;
     public Uczen(){
         this("");
     }
     public Uczen(String dane){
         this.dane = dane;
         id = licznik;
         licznik++; 
     }
     public String toString(){
         return dane+"("+id+")";
     } 
}
0

albo ja zle zrozumialem albo to co piszesz jest zupelnie z innej beczki. Identyfikator w klasie uczen czy dziennik jest do zrobienia, ale pisaliscie by zrobic identyfikator w klasie ocena

class ocena{
private integer id; //identyfikator? 

}

problem w tym ze w tej klasie ma nie byc ani listy ani zadenego powiazania tak naprawde z dziennikiem / z uczniem , jedynie parametry oceny

ale staram sie by dzialalo jakkolwiek i tu rodzi sie kolejne pytanie:

Jest klasa przedmiot, chce dodac do niej tak "statycznie" kolejne nazwy przedmiotow. W sposob jak ponizej tylko tak jak ja robie zawsze dodaje sie ta ostatania tylko, czy jest jakis sposob czy tylko wpisywanie reczne przedmiotow do list zostaje?

Przedmiot p = new Przedmiot();
		p.sNazwa = "Matematyka";	
		aPrzedmiot.add(p);
		p.sNazwa = "Polski";
		aPrzedmiot.add(p);
		p.sNazwa = "Angielski";
		aPrzedmiot.add(p);

sprawdzam to na zasadzie..

if ((aPrzedmiot.get(0).sNazwa == "Matematyka"))
			{

ps. dobrze ze istnieja takie szklane kule :) dziekuje za wszelka pomoc.

0
  1. W klasie Ocena pamiętaj: Przedmiot, wartość liczbową oceny i identyfikator Ucznia (a nie jego imię i nazwisko).
  2. Źle dodajesz do listy p. Tworzysz tylko jeden obiekt typu Przedmiot, a potem tylko zmieniasz jego właściwości.
Przedmiot p = new Przedmiot();
p.sNazwa = "Matematyka";    
aPrzedmiot.add(p);
p = new Przedmiot(); //tego brakowało
p.sNazwa = "Polski";
aPrzedmiot.add(p);
  1. Źle porównujesz, operator == w klasie String porównuje referencje.
if ((aPrzedmiot.get(0).sNazwa.equals("Matematyka")))
0

Rozumiesz dobrze. Przy takim wyświetlaniu powinieneś otrzymać listę obiektów Uczen (bo wypisujesz obiekt, a nie jego atrybut, który jest stringiem), ale nie pustkę. Spróbuj wypisywać dla każdego ucznia sDane. Aby zmienić sposób wyświetlania całego obiektu możesz do niego dodać metodę

public String toString(){
     return sDane;
}

</del> Ech nie zauważyłem, że jest już druga strona...

A tak w ogóle, to zauważyłem, że starasz się zawierać w nazwach zmiennych ich typ. Myślę, że w javie to zdecydowanie zbędne, trochę dziwne i zaciemnia kod. Co o tym sądzisz @bogdans?

A w Ocena nie ma być identyfikator ucznia (to nie SQL), tylko obiekt Uczeń jako atrybut w klasie Ocena. I tak samo z Przedmiot'em...

0

coz stosuje takie nazwenictwo bo ostatnio musialem skakac pomiedzy roznymi jezykami programowania, z jaka mam pierwszy raz do czynienia a takie nazewnictwo po prostu mi utkwilo coz..

program jakos napisalem i niby dziala z tym ze ciezko go przetestowac.

int MIN = 2;
		int MAX = 5;
		double rndOcena = MIN + (int)(Math.random()*((MAX-MIN)+1));
		
		if (aPrzedmiot.get(0).sNazwa.equals("Matematyka")) 
		{
			
		for (int x = 0; x < 3; x++) 
	 		{
			Ocena o = new Ocena();
			o.dOcena = rndOcena;
			aOcena.add(o);	
	 		}
		}

tu losuje kolejne oceny randomowo od 2 do 5 , dla jednego ucznia 3 oceny, problem w tym ze wszystkie wylosowane to te same oceny i np jak wylosuje 2 to potem srednia zawsze tez bedzie 2 , dodajac 10 osob wszyscy beda mieli oceny 2 i srednia 2 ...

po tej poprawce moge nawet wam udostepnic program i wytkniecie mi co jest nie tak w calym kodzie

0

Bo losujesz wartość oceny raz i przypisujesz ją trzy razy...
Poza tym w ocenie nie zapisujesz jeszcze przedmiotu i ucznia...

Tzn. to jest odpowiedź dlaczego wszystkie oceny ucznia są takie same.

Jest jeszcze drugi powód dlaczego oceny ucznia jak i wszystkich uczniów są takie same:
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random%28%29
Sprawdź zakres wartości z jakiego pochodzi wynik random() i użyj tego:
https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#nextInt-int-

0
for (int x = 0; x < 3; x++) 
	 		{
			double rndOcena = MIN + (int)(Math.random()*((MAX-MIN)+1));
			Ocena o = new Ocena();
			o.dOcena = rndOcena;
			o.sPrzedmiot = "Matematyka";
			aOcena.add(o);	
	 		}

W ten sposob jak losowanie jest w petli tez nie dziala lub mam strasznego pecha.
Ja to rozumiem tak:
1 iteracja:
-losuje liczbe
-tworzy obiekt
-dodaje wylosowana liczbe do dOcena
-podpisuje co to za przedmiot (tak nie bylo tego)
-dodaje do listy
2. iter
-losuje (juz inna liczbe? - w koncu to chyba random?)
-tworzy kolejny obiekt oceny
-?? wylosowana ocene wpisuje w dOcena
-podpisuje przedmiot
-dodaje do listy

itd itd..?

0
randomno.setSeed(20);
		int a = randomno.nextInt();

To losuje liczby jak trzeba, coprawda sa one idiotyczne ale rózne:

System.out.println("Object after seed: " + randomno.nextInt());

Przypisanie w ten sposob ciagle zwraca szereg tych samych ocen.

		o.dOcena = randomno.nextInt();

Naprawde dzieki za cierpliwość..:)

Może zechcecie zerknąć i napisać jak to się nie stosuje do waszych rad .. inaczej co mam jeszcze poprawic ?
http://wklejto.pl/240801

1

W Javie nie trzeba ustawiać ziarna, instrukcja

randomno.setSeed(20);

jest całkowicie zbyteczna. Jak chcesz losować sensowne oceny (od 2 do 5), to
int a = 2 + randomno.nextInt(4);

Ocena nadal nie ma ucznia.
To jest tylko część kodu.
Dlaczego wszystko jest `static`?
0

WYJSCIE:(po dodaniu 1 ucznia)
a - 0
Matematyka // powstaje poprzez aPrzedmiot.add(p);
Ocena: 4.0----Matematyka //(oznacza do jakiego przedmiotu jest przypisna ocena)
Ocena: 4.0----Matematyka
Ocena: 4.0----Matematyka
Polski
Ocena: 5.0----Matematyka
Ocena: 5.0----Matematyka
Ocena: 5.0----Matematyka
Angielski
Ocena: 4.0----Matematyka
Ocena: 4.0----Matematyka
Ocena: 4.0----Matematyka

No dobra a teraz wniosek:
Caly czas mam 3 problemy.

  1. losowanie liczb - nie wiem w czym rzecz
  2. przypisywanie ocen do przedmiotu - oceny sa przypisane ale wszystkie segreguja sie w matematyke
    tak jakby to dzialalo:
if (aPrzedmiot.get(0).sNazwa.equals("Matematyka")) 
		{

a to juz nie

if (aPrzedmiot.get(0).sNazwa.equals("Polski"))
		{

nie umiem okreslic czy :

 if ((aPrzedmiot.get(0).sNazwa.equals("Angielski")))
	    {	
	    	for (int i = 0; i < aOcena.size(); i++) 
	    	{
			
	        sum += aOcena.get(i).dOcena;
	    	}
	    }

liczy czy tez nie liczy sredniej dla przedmiotu skoro jest jak jest , ogolnie nota za program slaba , bo nie dziala jak powinno ;/
prosze o pomoc w poprawie

-jak nie bylo static to nie dzialalo i kompilator rozwiazal to slowkiem static ..
-w gruncie rzeczy w innych klasach sa tylko poszczegolne atrybuty i pola

1

Przecież w kolekcji aPrzedmiot na pierwszym miejscu (indeks = 0) jest Matematyka. Jaki cudem zatem miałby być spełniony warunek:

if (aPrzedmiot.get(0).sNazwa.equals("Polski"))

Słowo static stało się konieczne bo umieściłeś całe menu w statycznej metodzie main. W metodach statycznych można korzystać tylko z pól i metod statycznych. Początek kodu powinien wyglądać tak:

	public static void main(String[] args) throws Exception {
            Dziennik dziennik = new Dziennik();
        }
	public Dziennik()
	{
		System.out.println("WITAJ W NASZYM DZIENNIKU");	
		
		do 
		{
			System.out.println("********************** MENU ***********************");
			System.out.println("1 - Dodaj uczniow(losuje oceny)");
			System.out.println("2 - Lista uczniow");
			System.out.println("3 - Lista ocen z przedmiotu");
			System.out.println("4 - Srednia dla ucznia");
			System.out.println("5 - Srednia z przedmiotu");
			System.out.println("***************************************************");
			
		int i = sc.nextInt();
		sc.nextLine();


		 switch (i) {
		 	
		 	case 1:
		          System.out.println("Dodaj uczniow");
		          dziennik.DodajUcznia();
		       
		      break;		 
		      
		    case 2:
		         System.out.println("Lista uczniow");
		         dziennik.ListaUczniow();
		      
		      break;
		 
		    case 3:
		    	  System.out.println("Lista ocen z przedmiotu");
		    	  dziennik.ListaOcenPrzedmiot();
		    	  break;
		      
		    case 4:
			      System.out.println("Srednia dla ucznia");
			      dziennik.Wybierz();
			      dziennik.SredniaUczen();
			      break;
			      
		    case 5:
		    	  System.out.println("Srednia z przedmiotu");
		    	  dziennik.Wybierz();
		    	  dziennik.WybierzPrzedmiot();
			  dziennik.SredniaPrzedmiot();
			  break;
		 
		    default:
		           System.out.println("nieprzewidziana sytuacja");
		  }
		}while(true);
		
	}		
	}

Na razie nie zmieniaj.

0

if (aPrzedmiot.get(1).sNazwa.equals("Polski"))
if (aPrzedmiot.get(2).sNazwa.equals("Angielski"))

tez sie nie sprawdza juz to dojrzalem..

1

Zaraz się na Ciebie wścieknę @viamarimar... na @bogdans trochę też... Mam wrażenie, że tworzycie SQLową bazę, a nie program w języku obiektowym...

Proponuję, żebyś zaczął od początku, chyba będzie Ci prościej.

  1. Tak powinny wyglądać klasy Uczen, Przedmiot i Ocena:
public class Uczen{

     private static int idCounter=0;

     public final String dane;
     public final int id=idCounter++;

     public final ArrayList<Ocena> oceny=new ArrayList<>();

     public Uczen(String nazwisko){
          dane=nazwisko;
     }

     public double srednia(){
          return 0; //TODO
     }

}

public class Uczen{

     public final String nazwa;

     public final ArrayList<Ocena> oceny=new ArrayList<>();

     public Przedmiot(String nazwa){
          this.nazwa=nazwa;
     }

     public double srednia(){
          return 0; //TODO
     }

}

public class Ocena{

     public final float ocena;
     public final Przedmiot przedmiot;
     public final Uczen uczen;

     public Ocena(float ocena, Przedmiot przedmiot, Uczen uczen){
          this.ocena=ocena;
          this.przedmiot=przedmiot;
          this.uczen=uczen;

          przedmiot.oceny.add(this);
          uczen.oceny.add(this);
     }
}

A poza tym zacznij się uczyć dobrych nawyków:

  1. Przestań określać typ w nazwie zmiennej, to nie ma sensu w języku typowanych statycznie jakim jest java, zmniejsza zrozumiałość kodu i po prostu się tego nie robi.
  2. Niech poprawne używanie tabulatorów do pokazania zagłębień w kodzie będzie dla Ciebie nie mniej ważne niż poprawność algorytmów. (To samo dotyczy używania pustych linii, ale z tym akurat sobie radzisz dobrze chyba). Czytelność kodu jest na prawdę ważna, zaczniesz wtedy dwa razy więcej rozumieć.
  3. W javie klamerek nie piszemy w osobnych liniach, jeżeli można je napisać w linii poprzedniej ( dla {) lub następnej (dla }. Taki obyczaj. A poza tym czytelniej. Czyli:
if(a>b){
     a=1;
     b=2;
}else{
     a=2;
     b=1;
}
  1. Jeżeli pomiędzy { i } miałaby się znaleźć tylko jedna instrukcja, to (dla czytelności kodu) można klamerek nie pisać...
1

Trudność w pomocy Tobie polega na tym, że muszę Ci nie tyle powiedzieć co i jak masz poprawić, co nauczyć Cię myśleć w odpowiedni sposób. Np. żebyś rozumiał po co stosuje się statyczność i wiedział kiedy ją zastosować, a kiedy nie, a nie dodawał jej tylko dlatego, że kompilator się rzuca, że zmienna nie jest statyczna... Notabene właśnie z powodu tego static wszystkie średnie wychodzą Ci takie same...

Jeżeli masz jakieś materiały z zajęć, których nie przerobiłeś i mimo to próbujesz robić projekt, to wróć do nich i zrozum co, jak i w jakim celu. A tymczasem postaram się nauczyć Cię tego myślenia, ale że jesteś początkujący, to żeby Ci nie namieszać, będę Ci pisał tylko o tym co będzie miało zastosowanie przy projekcie, a nie o wszystkich wariantach wszystkich wariantów... Zakładam, że ich nauczysz się sam kiedyś... Więc zacznijmy jeszcze raz:

  1. Niech klasy Ocena, Przedmiot i Uczeń wyglądają dokładnie tak, jak Ci napisałem. Nie wstawiaj tam żadnych dodatkowych static. Ponieważ w Twoim menu nie ma żadnej edycji już wprowadzonych danych, to dodałem do większości atrybutów słowo final, oznacza ono, że po zainicjalizowaniu atrybutu jego wartość nie ulegnie już zmianie. Uzupełnij zawartość metod srednia() tak, jak to zrobiłeś, ale bez static i bez wypisywania komunikatu na konsolę.

  2. Nadal sugeruję byś stosował zasady pisowni, o których Ci pisałem. Na prawdę będzie łatwiej zrozumieć kod jako całość... Dodam do tego jeszcze, że w javie zwyczajowo nazwy typów rozpoczynają się od wielkiej litery, a nazwy metod, atrybutów i zmiennych z małej (chyba, że z jakiegoś powodu cała nazwa jest wielkimi literami).

  3. Nowa filozofia. Wydziel z klasy Dziennik nową klasę Menu. Od tego momentu klasy Dziennik, Uczeń, Przedmiot i Ocena będą reprezentować konkretne byty zgodnie z nazwami, które je opisują.
    a) Np. obiekt klasy Uczen będzie reprezentował jednego, konkretnego ucznia i będzie zawierał informacje tylko o tym uczniu, m.in. listę jego ocen, dlatego ta lista nie będzie static.
    b) Obiekt klasy Dziennik będzie reprezentował dziennik jednej konkretnej klasy i będzie zawierał tylko trzy atrybuty: listę przedmiotów, listę uczniów i listę ocen (wszystkie public final). Jako że będą to dane jednej konkretnej klasy, to też nie będą static. W zasadzie lista ocen będzie potrzebna tylko wtedy, gdybyśmy chcieli liczyć średnią ze wszystkich ocen całej klasy, jeżeli nie chcesz mieć takiej funkcjonalności, to możemy zrezygnować z tej listy.

  4. Klasa Menu jak nie trudno się domyślić będzie odpowiadać za kontakt z użytkownikiem i przeprowadzanie operacji na danych. Dla ścisłości można dodać, że będzie reprezentować jeden konkretny terminal do kontaktu z użytkownikiem... Ale zrobimy ją trochę inaczej niż była zrobiona, a mianowicie podzielimy ją bardziej na metody. To będzie drugi element tego nowego myślenia.
    a) Utwórz metode public void start() (bez static) odpowiedzialną za najwyższy poziom menu, a w niej while, a w nim kolejno: wypisanie dostępnych opcji, pobranie od użytkownika odpowiedzi, switch ale niech każda z opcji będzie tylko wywoływała metodę odpowiedzialną za przeprowadzenie tej opcji. Przewidź też opcję zakończenia programu (ona akurat może nie mieć specjalnej metody;p )
    b) Niech metoda main wygląda dokładnie tak:

public static void main(String[] args){
     new Menu().start();
}

c) Niech obiekt klasy Menu ma tylko jeden atrybut, o taki:

private final Dziennik dziennik=new Dziennik();

d) Dodaj i wypełnij treścią następujące metody:

private void wypiszPrzedmioty()
private Przedmiot wybierzPrzedmiot() // niech korzysta z powyższej metody

private void wypiszUczniow()
private Uczen wybierzUcznia() // niech korzysta z powyższej metody

Wypisz i wybierz zostały rozdzielone, gdyż albowiem masz w menu opcję wypisywania, gdybyś jej nie miał, to można by je połączyć w jedną metodę.

  1. Spróbuj wymyślić jak ładnie napisać pozostałe metody z menu w tym samym stylu i wklej kod, zobaczymy co wymyśliłeś:) Niektóre fragmenty kodu, które napisałeś w kilku liniach można napisać w jednej (nie trzeba zapisywać wyniku funkcji do zmiennej, jeśli chce się ją odczytać tylko raz wstawiając do innej funkcji - można po prostu zrobić a( b() ). Decyzja należy do Ciebie, a kryterium powinna być czytelność kodu (czasami coś jest czytelniejsze jak jest rozbite, a czasami jak zajmuje mniej miejsca).

  2. Proponuję (choć nie zmuszam), byś opcję dodawania uczniów miał tylko w postaci "dodaj ucznia" w sensie jednego i po dodaniu program wraca do menu. To uprości nieco implementację, a dla użytkownika nie będzie wielkim utrudnieniem. Może być nawet ulepszeniem, bo nie musi znać liczby uczniów do wprowadzenia...

No to na razie tyle. Do pracy :p

0

Materiałów z zajęć nie mam, wszystko co robiliśmy to kalkulator i to było jeszcze na zasadzie znacie inne języki wiecie co to zmienna co to tablica itd.. no fajnie to w javie jest tak samo to teraz napiszcie tak samo to i strzelił polecenie koleś i główkuje jak je rozwiązać bo wątpie, żę nawet idąc do niego dostane odpowiedź, niektórzy ludzie już tacy są..

ale do rzeczy ..

  1. OK ! Nie będę nic modyfikował w twoim modelu klas. Chodź to trudniejsze niż myślałem. Kompilator ciągle narzuca te static'ki
  2. Problem z pisaniem kodu na zasadzie

a{
..
}
czy
a
{
..
}
wynika z tego, że jeden koleś mówił, żę trzeba wyrobić swój "styl" no fajnie .. nigdy tak nie pisałem jak teraz bo kod jest brzydki i cieżki. ale po jego zajęciach on sugerował, żeby pisać właśnie tak dlatego sory ale poprawie się :)

co do np
dodajUsera();
DodajUsera();
to z php mi się udzielilo - kiedys pytalem o formu nazewnictwa plikow i ponoc tam wypada pisac z duzych liter dlatego tak, ale ok będę zmienial, trzeba się przystosować do javy ;)

  1. No właśnie zauważyłem, że albo static albo czerwony kod. Teraz też mam z tym problem o czym za chwile.

  2. Staram się zastosować do rad, żęby "coś" wyszło.

  3. W sumie jak zmienilem na dodawnie po jednym nawet szybciej sie obsluguje wiec rzeczywiscie +.

TERAZ PROBLEMY :P :

  1. W klasie menu ktora proponowales stworzyc powinny byc chyba tylko metody wybierajace tak?

Nie potrafie z tego kodu sklicic metody:

 System.out.println("Dodaj uczniow");

					System.out.println("Podaj imie i nazwisko: ");
					String x = sc.nextLine();
					Uczen u = new Uczen(x);
					dziennik.uczniowie.add(u); 

				
				  if (dziennik.przedmioty.get(0).nazwa.equals("Matematyka")) {
						for (int k = 0; k < 3; k++) {
							int a = 2 + dziennik.rand.nextInt(4);
							Ocena o = new Ocena(a,p1,u);
							dziennik.oceny.add(o);	
					   }
				  }
					 if (dziennik.przedmioty.get(1).nazwa.equals("Polski")) {
				  	for (int k = 0; k < 3; k++) {
				  		int a = 2 + dziennik.rand.nextInt(4);
						Ocena o = new Ocena(a,p2,u);
				  		dziennik.oceny.add(o);	
				  	}
					 }
				 if (dziennik.przedmioty.get(2).nazwa.equals("Angielski")) {
				  	for (int k = 0; k < 3; k++) {
				  		int a = 2 + dziennik.rand.nextInt(4);
						Ocena o = new Ocena(a,p3,u);
				  		dziennik.oceny.add(o);	
				  	}	
				 }		

Dlaczego? a no dlatego, ze gdy tworze np. metode o nazwie dodajUcznia to potrzebuje ona dostepu do p1/p2/p3
czyli:

Przedmiot p1 = new Przedmiot("Matematyka");
		dziennik.przedmioty.add(p1);
		Przedmiot p2 = new Przedmiot("Polski");
		dziennik.przedmioty.add(p2);
		Przedmiot p3 = new Przedmiot("Angielski");
		dziennik.przedmioty.add(p3);

a nie moge za kazdym razem tworzyc nowych przedmiotow, z kazdym nowym uczniem nowych przedmiotow
chce by metoda dodajUcznia przypisywala mu Od razu oceny wiec stosujac sie do konstruktora zawrtego w stworzonej przez ciebie klasie ocena nie wiem jak w metocie odwolac sie do obiektu z poza metody(to chyba tak w uproszczeniu)

  1. wlasnie skoro nie wiem takiej rzeczy to nie potrafie albo nie jestem swiadom jak to zrobic.. odwolac sie w klasie dziennik do metod srednia() z klas Uczen i klas Przedmiot
    probuje tak:
public void sredniaUczen() {
	Uczen.srednia();
}

ale w ten sposob chce zebym zmienil metode srednia na static czego mam nie robic , wiec ten rodzaj odwolania jest zly..

Wiem ze musze dla kogos ta srednia liczyc wiec zrobilem tak:

private Uczen wybierzUcznia(){
		int nr;
		 System.out.println("Kogo chcesz wybrac?");
		 nr = sc.nextInt();
		 sc.nextLine(); 
		 
		 
				if(dziennik.uczniowie.isEmpty()){
					 System.out.println("Pusta lista...");
				}
				else{
					System.out.println("Wybrales: " + dziennik.uczniowie.get(nr).dane + "-id:"+dziennik.uczniowie.get(nr).id);
					dziennik.uczniowie.get(nr).srednia();
				}
		
		return null;
		} 

czyli liczenie wrzucilem do wyboru ucznia/przedmiotu.. znow powtarza sie ze nie wiem jak wybrany nr w metodzie wybierzUcznia mial bym przeniesc i wykorzystac np w nowej metodzie liczSrednia(tu chyba jakis nr?)?

WYJSCIE DLA 2 UCZNIOW:

Lista ocen z przedmiotu
Uczen:janek - 0
Ocena: 4.0----Matematyka=janek
Ocena: 2.0----Matematyka=janek
Ocena: 5.0----Matematyka=janek
Ocena: 4.0----Polski=janek
Ocena: 5.0----Polski=janek
Ocena: 5.0----Polski=janek
Ocena: 5.0----Angielski=janek
Ocena: 2.0----Angielski=janek
Ocena: 3.0----Angielski=janek
Ocena: 2.0----Matematyka=marek
Ocena: 2.0----Matematyka=marek
Ocena: 4.0----Matematyka=marek
Ocena: 4.0----Polski=marek
Ocena: 5.0----Polski=marek
Ocena: 2.0----Polski=marek
Ocena: 5.0----Angielski=marek
Ocena: 4.0----Angielski=marek
Ocena: 4.0----Angielski=marek
Uczen:marek - 1
Ocena: 4.0----Matematyka=janek
Ocena: 2.0----Matematyka=janek
Ocena: 5.0----Matematyka=janek
Ocena: 4.0----Polski=janek
Ocena: 5.0----Polski=janek
Ocena: 5.0----Polski=janek
Ocena: 5.0----Angielski=janek
Ocena: 2.0----Angielski=janek
Ocena: 3.0----Angielski=janek
Ocena: 2.0----Matematyka=marek
Ocena: 2.0----Matematyka=marek
Ocena: 4.0----Matematyka=marek
Ocena: 4.0----Polski=marek
Ocena: 5.0----Polski=marek
Ocena: 2.0----Polski=marek
Ocena: 5.0----Angielski=marek
Ocena: 4.0----Angielski=marek
Ocena: 4.0----Angielski=marek

Nie powinno byc tak ze dodajac drugiego uzytkownika znow dodawane sa oceny pierwszemu, a drugi dostaje oceny pierwszego. Wszyscy dodaja kolejna petle ocen tak naprwde.. ale co zmienic? ten problem meczy od poczatku i to co mowiles kazdy indywidualne oceny chyba dalej cos nie tak ale chyba przez to ze dodawanie jest bez metody i jakos tak po chinsku bo nie wiem jak powiazac obiekty przedmiot - uczen -ocena (ich tworzenie)

Coz na czasie mi nie zalezy, ale ogolnie problem stworzenia tego programu chce rozwiazac do konca chodzby to mialo być kroczek po kroczku. Bardzo dziękuję za pomoc, jest ona nieoceniona! Do głowy wbija mi się więcej niż na tych zajęciach :)

1
  1. Postanowiłem się zreflektować, że w atrybutem w klasie Menu powinien być jeszcze skaner (ostatnio o nim zapomniałem).

  2. Można powiedzieć, że w klasie Menu będą metody trzech rodzajów:
    a) metody, które podałem i nie pozwoliłem zmieniać (jak main(String[] args) i start()
    b) metody, które podałem i z których nazw i typów zwracanych wartości wynika do czego będą służyć i dałem Ci do wymyślenia jak ma wyglądać ich treść (to te 2 metody wypisujące i 2 wybierające)
    c) metody, których nie podałem, ale które musisz napisać, żeby zrealizować funkcjonalności...

Coś uporządkujmy: zastanów się czy te trzy ify mogą kiedyś dać fałsz? (Oczywiście przy założeniu, że dodajesz przedmioty właśnie w takiej kolejności)

if (dziennik.przedmioty.get(0).nazwa.equals("Matematyka"))
if (dziennik.przedmioty.get(1).nazwa.equals("Polski")) 
if (dziennik.przedmioty.get(2).nazwa.equals("Angielski")) 

W swojej metodzie korzystasz w ifach z przedmiotów w dzienniku, ale nie dostrzegasz możliwości wybrania ich w ten sam sposób do dodawania ocen. Możesz skorzystać z metody get(nr) tak, jak skorzystałeś w punkcie 2. do wyboru ucznia. Ale chyba najszybciej będzie jednak tak:

private void dodajLosoweOceny(Uczen u){
     for(Przedmiot p : dziennik.przedmioty){
          ...
     }
}
  1. Twoja metoda wybierzUcznia() wybiera ucznia tak jak chciałem, żeby wybierała:) Z tym, że dodałeś tam jeszcze liczenie średniej (być może sądząc, że nie można Ci dodać innych metod). Więc generalnie funkcjonalność została zrealizowana poprawnie:D

2.c.d. Ale oprócz realizowania zadań chcę Cię nauczyć też jak pisać by programowanie obiektowe dużych projektów było proste, więc pokażę o co dokładnie mi chodziło;p

private void wypiszUczniow(){
     System.out.println("Uczniowie:");
     for(int i=0; i<dziennik.uczniowie.size; i++){
          Uczen u=dziennik.uczniowie.get(i);
          System.out.println(i+". "+u.dane+" ["+u.id+"]");
     }
     System.out.println();
}


private Uczen wybierzUcznia(){
     wypiszUczniow();

     System.out.print("Podaj numer ucznia: ");
     int nr=sc.nextInt();
     sc.nextLine();

     if(nr>=0 && nr<dziennik.uczniowie.size())
          return dziennik.uczniowie.get(nr);
     else{
          System.out.println("Podano błędny numer!");
          return null;
     }
 
}


private void sredniaUcznia(){
     Uczen u=wybierzUcznia();
     if(u!=null)
          System.out.println("Średnia ucznia "+u.dane+" to "+u.srednia());
}

Każda metoda ma proste i ściśle określone zadanie oraz korzysta z innych metod. Teraz nie będzie trudno dodać funkcjonalności takie jak usuwanie/edycje ucznia, dodawanie oceny konkretnemu uczniowi. Funkcjonalność wypisywania uczniów jest już zrealizowana, wystarczy je podpiąć do switcha...
Proponuję byś dodał powyższy kod do swojego projektu;)

  1. Wygląda, że nadal masz static coś, co takie być nie powinno, być może listę ocen w klasie Uczen. Skoro dodajesz oceny do statycznej (czyli wspólnej dla wszystkich obiektów) listy, to nie oczekuj, że poszczególne obiekty jakoś magicznie wybiorą z niej swoje oceny;)
0

http://wklejto.pl/241040

  1. Nie wiem czy zrozumialem, ale chyba mam wszystkie metody przerzucic do menu? No wiekszosc zreszta zaraz dam kod i bedzie krytyka.
  • w klasie menu wlasnie chyba mialo nie byc maina , po to byla ona stworzona zeby wydzielic statycznego maina?
  1. te ify sa wyrabalem, ale nie wiem do konca co one mialy robic. Wczesniej stosowalem je do prownywania, ale bylo stwierdzonez e to zly sposob.
  2. Losowanie ocen jak podales no niby dziala, ale to chyba jeszcze jedyny problem z tym programem(chyba). Dlaczego? Oceny losuja sie bliskie takim samym, wiec wyniki srednich sa bezsesnsu(bylo lepiej cos popsulem chyba) ale bylo lepiej gdy dodawnie uzytkownika nie bylo w metodzie wiec cos za cos.
    Teraz uzyjmy innych slow... Co sie dzieje?
    -Oceny sa losowane po 3 - po 3 chyba dlatego bo sa 3 przedmioty dodawane w konstruktorze dziennika wydaje mi sie iz tak powinno byc.
    -dlaczego takie same? lub zblizone? bo dla kazdego przedmiotu nadaje te same, nie ma nowego losowania.
    NAJLEPSZE: widze problem nie wiem jak to zmienic.

Pytanie: jak zrobic polowki ocen?
metoda ktora losuje sprawdza co sie wylosowalo a nastepnie dodaje dopiero ocene?
tylko nie z tym schematem losowania

 int a = 2 + dziennik.rand.nextInt(4);

to chyba jest tylko z przedzialu 1 -5 jak mowil czlowiek wyzej

  1. Zastosowalem twoje metody, wywalilem swoje i uzylem try{} catch chodz nie wiem czy czasem nie potrzebnie,albo wgl ponad..

Zeby nie bylo ze zywcem tylko kopiuje czy cos wygrzebalem z smieci swoje z dwie metody i powiedz mi jaka jest roznica w stosunku do swoich(nie ma ich juz w programie)

private void wypiszPrzedmioty(){
		if(dziennik.przedmioty == null || dziennik.przedmioty.isEmpty()){
			 System.out.println("Pusta lista...");
		 }
		 else{
		 for (int i = 0; i < dziennik.przedmioty.size(); i++) {
				System.out.println( i + " -  " + dziennik.przedmioty.get(i).nazwa);
			}
		 }
	}


	private Przedmiot wybierzPrzedmiot() {
		int nr;
		 System.out.println("Jaki przedmiot wybrac?");
		 nr = sc.nextInt();
		 sc.nextLine(); 
		 
				if(dziennik.przedmioty.isEmpty()){
					 System.out.println("Pusta lista...");
				}
				else{
					System.out.println("Wybrales: " + dziennik.przedmioty.get(nr).nazwa );
					dziennik.przedmioty.get(nr).srednia();
					//wybierzNumer(nr);
				}
				return null;
		
		}

Tak patrzac, jako osoba malo znajaca sie na tym to ty operujesz na obiektach a ja staralem sie na tych listach cos wyczarowac. Chodz efekt byl podobny dzialanie bylo inne..

Tu pytanie:
Zarowno w twoich jak i moich metodach jest
return null;
Co to oznacza, nie zwracaj nic? Wiec po co to? Bez tego jest blad.. kiedy to trzeba stosowac? W metodach korzystających z jakiejs klasy?

Twoj schemat otwiera mi oczy na to jak korzystac z obiektow w metodach na tle roznych klas. Nie tylko klasy bazowej.. Nie tylko w metodzie maina czy funkcji swicha. Wielki plus dla takich ludzi jak ty !:)

Jak byś ty/lub ktos inny mi jeszcze pomógł jak to z tym losowaniem w tej javie jest?

No fajnie zrobił, zrobilem metode losuj ocene ale dziala jak opisalem powzej:

private void dodajLosoweOceny(Uczen u){
		try{
	     for(Przedmiot p : dziennik.przedmioty){
	    	   int a = 2 + dziennik.rand.nextInt(4);
				Ocena o1 = new Ocena(a,p,u);
				dziennik.oceny.add(o1); 
	     }
		}catch(Exception e)
		{
			System.out.println("Wystapil blad ex!");
		}	
	     
	}

jestem otwarty na krytyke i dzięki za wszelką pomoc jeszcze raz ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1