Parametisieren

Medhusalem

Mitglied
Hallo Leute,

habe mal wieder eine Frage.
Im Moment habe ich große Probleme Struktur in meinen Programmcode zu bringen.
Ich lerne nach einem Buch, das heißt: "Building Java Programs - A Back to Basic Approach" aber leider bin ich anscheinend nicht gescheit genug zu verstehen wie das genau funktionieren soll, denn ich bekomme es einfach nicht hin, trotz guter Beispiele.

Bin nun im 4ten Kapitel und soll folgende Aufgabe bearbeiten:
Write a method called fractionSum that accepts an integer parameter n and returns as a double the sum of the first n terms of the sequence
In other words, the method should generate the following sequence:

1 + 1/2 + 1/3 + 1/4 ... etc. also 1/n + 1/n+1 etc

Ich habe überhaupt kein Problem die Aufgabe zu lösen, mein Code sieht dann so aus:

Java:
import java.util.*;

public class Chapter_4_Exercise_1_BilligLösung {
	public static void main(String[] args){
		Scanner console = new Scanner(System.in);
		
		//Introduction to the program
		System.out.println("This programm accepts an integer parameter\n" +
				"n and returns it as a double of the sum of the first" +
				"n terms of the sequence");
		System.out.println();
		
		//Prompts the user for input
		System.out.print("Please enter your parameter as an integer: ");
		int input = console.nextInt();
		
		//Calculates
		double sum = 0;
		for (double i = 1; i <= input; i++){
			sum += 1/i;
			}
			
		//Returns the result
		System.out.println("Sie haben die Zahl: " + input + " eingeben\n" +
		"Die Summe ist: " + sum);
		
	}
}

Ihr seht sicher schon wo das Problem ist...
Laut meinem Buch ist das eine schlechte Lösung alles in die Main-Methode zu packen weil es das Programm unübersichtlich werden lässt und man solle es doch in verschiedene Untermethoden teilen.
Damit habe ich aber nun größte Schwierigkeit

Java:
import java.util.*;

public class Chapter_4_Exercise_1 {
	public static void main(String[] args){
		Scanner console = new Scanner(System.in);
		
		
		introduction();
		int input = getResult(console);
		result(input, sum);
		
	}
	
	//Introduction to the program
	public static void introduction(){
	System.out.println("This programm accepts an integer parameter\n" +
			"n and returns it as a double of the sum of the first" +
			"n terms of the sequence");
	System.out.println();
	}
	
	//Prompts the user for input
	public static int getResult(Scanner console){
		System.out.print("Please enter your parameter as an integer: ");
		int input = console.nextInt();
		
		for (double i = 1; i <= input; i++){
			double sum = 0;
			sum += 1/i;
			}
		return input;	
	}
	
	//Returns the result
	public static void result(int input, double sum){
		System.out.print("You entered the numer : " + input +
				"The sum is: " + sum);
	}
}

Ich bin hier echt schon am Verzweifeln, eigentlich wollte ich auch noch die Rechnung und das Eingeben des Integers trennen aber dann war das nur NOCH verwirrender.
Sitze an dem Problem nun schon eine ganze Weile und komme einfach nicht weiter, in dem Beispiel was angeführt wurde fande ich das schon ziemlich schwer nachzuvollziehen aber da ging das noch einigermaßen aber hier kann ich das einfach nicht mehr anwenden.

Kann mir vielleicht bitte einer helfen?

PS: Das heir ist das Beispiel, nach dem ich meine Programme schreiben möchte, da es sehr übersichtlich aussieht.


Java:
// This program finds the body mass index (BMI) for two
// individuals. This variation includes several methods
// other than main.
import java.util.Scanner;

public class bmi_1_own_b {
	public static void main(String[] args){
		Scanner console = new Scanner(System.in);
		
		
		introduction();
		double bmi1 = getBMI(console);
		double bmi2 = getBMI(console);
		reportResults(bmi1, bmi2);
	}

	// introduces the program to the user
	public static void introduction(){
		System.out.println("This program reads data for two\n" +
				"people and computes their body\n" +
				"mass index and weight status.\n");

	}
	// prompts for one person’s statistics, returning the BMI
	public static double getBMI(Scanner console){
		System.out.println("Enter next person's information: ");
		System.out.print("height in m? ");
		double height = console.nextDouble();
		System.out.print("weight in kg? ");
		double weight = console.nextDouble();
		double bmi = BMIFor(height, weight);
		return bmi;
	}
	// reports the weight status for the given BMI value
	public static void reportStatus(double bmi){
		
		
		if (bmi < 18.5){
			System.out.println("underweight");
		} else if (bmi < 24.9) {
			System.out.println("normal");
		} else if (bmi < 29.9) {
			System.out.println("overweight");
		} else {
			System.out.println("obese");
		}	
	}

	// this method contains the body mass index formula for
	// converting the given height (in meter) and weight
	// (in kilogram) into a BMI
	public static double BMIFor(double height, double weight) {
		return weight / (height * height);
	}

	// reports the overall bmi values and weight status
	public static void reportResults(double bmi1, double bmi2){
		System.out.printf("Person #1 body mass indes = %5.2f\n", bmi1);
		reportStatus(bmi1);
		System.out.printf("Person #1 body mass indes = %5.2f\n", bmi2);
		reportStatus(bmi2);
		
	}
}
 

fidibus

Mitglied
Java:
import java.util.Scanner;
 
public class Chapter_4_Exercise_1 {
	
	
	public double calculate( int n)
	{
		 //Calculates
        double sum = 0;
        for (double i = 1; i <= n; i++){
            sum += 1/i;
            }
        return sum;
	}
	
	public void printResault(int input, double result)
	{
		//Returns the result
        System.out.println("Sie haben die Zahl: " + input + " eingeben\n" +
        "Die Summe ist: " + result);	
	}
	
	
	 public static void main(String[] args){
	        Scanner console = new Scanner(System.in);
	        
	        //Introduction to the program
	        System.out.println("This programm accepts an integer parameter\n" +
	                "n and returns it as a double of the sum of the first" +
	                "n terms of the sequence");
	        System.out.println();
	        
	        //Prompts the user for input
	        System.out.print("Please enter your parameter as an integer: ");
	        int input = console.nextInt();
	        
	        // Instanz der Klasse erstellen 
	        Chapter_4_Exercise_1 ce =new Chapter_4_Exercise_1();
	        
	        //verschachjtelter Methodenaufruf
	        ce.printResault(input, ce.calculate(input));
	           
	    }
	}
 

AquaBall

Top Contributor
PS: Das ist das Beispiel
Java:
		double bmi1 = getBMI(console);
		double bmi2 = getBMI(console);
		reportResults(bmi1, bmi2);

An dieses Beispiel würde ich mich nicht unbedingt halten.
Es hat 2 große Schwächen, von denen ich unbedingt abraten würde.
1) Die Übergabe der Console als FunktionsParameter würde ich hier nie nehmen.
Das mag sinnvoll ein, wenn man für Streams programmiert, du willst aber später sicher genau im Gegensatz dazu für eine Benutzeroberflächer weiterentwickeln. Viel sinnvoller ist eine reine Berechnungsfunktion, der du die Ausgangswerte übergibst. (Bei fidibus heißt die calculate.)
2) Die reportResults ist völlig unmotiviert für genau 2 Werte angelegt. Das mag zwar mit der Aufgabe übereinstimmen, ist aber thematisch überhaupt nicht nachvollziehbar. Ist also völlig unlogisch und nimmt schon vom Konzept auch die Möglichkeit mal für 1 oder beliebig viel Personen zu verwenden.

Doch zu deinem Code, (unter dem Vorsuch ihn möglichst wenig abzuändern):
Du kannst natürlich auf sum nicht zugreifen, wenn du es nicht definiert hast, und du gibst die Eingabe als Ergebnis deiner getResult zurück, was ja schon von der Bezeichnung ein Widerspruch ist.
Das Dilemma ist klar: Eine Methode gibt nicht 2 Werte zurück, solange man nicht mit Classen arbeitet.
Also: schmeiß deine Dateneingabe in eine eigene Methode, und übergib's AN die Methode.

Java:
import java.util.*;
 
public class Chapter_4_Exercise_1 {
    public static void main(String[] args){
        Scanner console = new Scanner(System.in);
        
        introduction();
        int input = getAnzahl(console);
        double sum = getResult(input);
        // oder auch: double sum = getResult( getAnzahl(console) );
        reportResult(input, sum);
    }
    
    //Introduction to the program
    public static void introduction(){
    System.out.println("This programm accepts an integer parameter\n" +
            "n and returns it as a double of the sum of the first" +
            "n terms of the sequence");
    System.out.println();
    }
    
    //Prompts the user for input
    public static int getAnzahl(Scanner console){
        System.out.print("Please enter your parameter as an integer: ");
        int input = console.nextInt();
        return input;   
    }

    //Calculates Sum
    public static int getResult(int input){
        for (double i = 1; i <= input; i++){
            double sum = 0D;
            sum += 1/(double)i;
            }
        return sum;   
    }
    
    //Returns the result
    public static void reportResult(int input, double sum){
        System.out.print("You entered the numer : " + input +
                "The sum is: " + sum);
    }
}

[OT]PS: Bitte verwende nicht solche Schriften, keiner lässt sich hier gerne anschreien, schon gar nicht wenn's nicht wichtig ist, sodnern ein Kommentar.[/OT]

@fidibus:
Übrigens, warum erstellst du die Klasse nochmal?
Code:
Chapter_4_Exercise_1 ce =new Chapter_4_Exercise_1();
Nur exemplarisch, als Beispiel?
 
Zuletzt bearbeitet:

irgendjemand

Top Contributor
@fidibus:
Übrigens, warum erstellst du die Klasse nochmal?
Code:
Chapter_4_Exercise_1 ce =new Chapter_4_Exercise_1();
Nur exemplarisch, als Beispiel?

mit sicherheit um nicht im static-context zu arbeiten wie es leider viele anfänger machen

da java OOP ist sollte in [c]public static void main(String[])[/c] als erste zeile eh erstmal eine instanzierung der klasse folgen ... und auf diese instanz werden dann die methoden gecallt ... *natürlich NICHT im konstruktor der klasse* ...

scheint als ob du selbst viel im static-context arbeitest ... zumindest deinem code zu folge ... ich finde daher deine anmerkung eigentlich genau falsch rum ... da du dir diese lieber selbst stellen solltest : "warum tust du das nicht ?"
 

fidibus

Mitglied
@fidibus:
Übrigens, warum erstellst du die Klasse nochmal?
Code:
Chapter_4_Exercise_1 ce =new Chapter_4_Exercise_1();
Nur exemplarisch, als Beispiel?

Wie irgendjemand schon gesagt hat arbeite ich nicht im static-context und muss daher meine Klasse instanziieren, damit ich an die Methoden und Attribute der Klassen herrankomme. Das heißt ich rufe zunächst den Konstruktor der Klasse auf, welcher in diesem Fall der Default-Konstruktor ohne Parameter ist.

Würde man alle Methoden und Attribute einer Klasse statisch vereinbaren und keinen Konstuktoraufruf machen, hätte das zur Folge, das man kein Objekt einer Klasse hat. Dies wiederum ist natürlich nicht sinnvoll für eine Programme bei den du zum mehrere Objekte eines Typs brauchst.

Stell dir vor cdu willst einen Fuhrpark programmieren, dann benötigst du natürlich mehrere Instanzen der Klasse Auto, da du ja mehrere Autos in deinem Fuhrpark verwaltest.

Des weiteren haben static definierte Variablen eine Lebensdauer, welche sich über die gesammte Ausführung des Programms erstreckt, das heißt, sie belegen dementspreched Speicher, auch wenn sie gar nicht mehr benötigt werden.

Grüße
 

Medhusalem

Mitglied
@AquaBall

Ich habe das nur hervorgehoben, damit das in meinem Post nicht untergeht.
Anschreien ist schon recht schwierig beim Schreiben und ich war der Meinung Capslock würde den Job übernehmen.

Danke auf jeden Fall für die Hilfe.

Bei meinem ersten Code im Post hatte ich überhaupt keine Proble sum war initialisiert und der Compiler hat nicht gemeckert aber im nächsten habe ich so viel rumprobiert, der wollte die variable sum einfach nicht initialisieren.

Also ich versuch mich dann mal an dein Beispiel zu halten wenn ich weiter programmiere und dem Prrogramm Struktur bringen möchte.
Wird für mich wohl noch ein etwas längerer Weg werden das mit den ganzen Calls zu verstehen, vor allem da ich weniger Probleme habe, wenn ich den ganzen Code direkt in Main packe, aber wenn ich das ordnen soll gibts bei mir dann Probleme.
 

AquaBall

Top Contributor
Wie irgendjemand schon gesagt hat arbeite ich nicht im static-context und muss daher meine Klasse instanziieren, damit ich an die Methoden und Attribute der Klassen herrankomme. Das heißt ich rufe zunächst den Konstruktor der Klasse auf, welcher in diesem Fall der Default-Konstruktor ohne Parameter ist.

Würde man alle Methoden und Attribute einer Klasse statisch vereinbaren und keinen Konstuktoraufruf machen, hätte das zur Folge, das man kein Objekt einer Klasse hat. Dies wiederum ist natürlich nicht sinnvoll für eine Programme bei den du zum mehrere Objekte eines Typs brauchst.

Stell dir vor cdu willst einen Fuhrpark programmieren, dann benötigst du natürlich mehrere Instanzen der Klasse Auto, da du ja mehrere Autos in deinem Fuhrpark verwaltest.

Des weiteren haben static definierte Variablen eine Lebensdauer, welche sich über die gesammte Ausführung des Programms erstreckt, das heißt, sie belegen dementspreched Speicher, auch wenn sie gar nicht mehr benötigt werden.

Grüße

WAS du machst ist mir schon klar, aber WARUM du's machst leuchtet mir nicht ein.
Was würde sich an Speicherbedarf, Laufzeiten, Logik, Lebensdauer, ... ändern , wenn die letzten 2 Zeilen einfach hießen:
Java:
            // Instanz der Klasse erstellen 
            // weglassen; Chapter_4_Exercise_1 ce =new Chapter_4_Exercise_1();
            
            //verschachjtelter Methodenaufruf
            printResault(input, calculate(input))
;
Das würde an der Lebensdauer der Klasse Chapter_4_Exercise_1, die ja schon durch den Programmstart instanziiert, wurde überhaupt nichts ändern.
Ich verstehe nicht was der Vorteil deiner Variante sein würde. Lebensdauer bleibt genau gleich, und in Gegenteil brauchst du zusätzlichen Speicher und Laufzeit.
Und "speicherbelastende Attribute" existieren hier nicht. Das einzige Attribut, das (wir beide) verwenden ist "int input", das wir beide in main "verstecken".

Dein Beispiel mit Fuhrpark unterscheidet sich in der "Tiefe".
Dass ich in eimen Fuhrpark mehrere Autos instanziiere ist klar, aber ich werden in einem Fuhrpark nicht mehrere Fuhrparke instanziieren.

Analog für die Aufgabenstellung hier:
In einer Klasse Chapter4Exercise1 brauch ich zwar später mehrere Klassen (für SummenFunktion, IntegralFunktion, ReihenFunktion, ...) die ich auch evtl. mehrfach brauche, aber ich werde nie mehrere Instanzen von Chapter4Exercise1 brauchen.

Ich würde deinen Argumenten zustimmen, wenn du die Summe als Klasse realisiert hättest.
Java:
public class Chapter_4_Exercise_1 {
    
    class Summe {        //   <<---- Das da machst du aber nicht!
        public double calculate( int n)
        {
            for ... //Calculates
        }
        public void printResault(int input, double result)
        {
            println...
        }
    }
    
     public static void main(String[] args){
            
            //Introduction to the program
            //Prompts the user for input
            ... 

            // Instanz der SUMMEN-Klasse erstellen 
            Summe ce =new Summe();
            
            //verschachjtelter Methodenaufruf
            ce.printResault(input, ce.calculate(input));
        }
    }
}
Aber ich lasse mich gerne belehren, falls ich irgendetwas nicht durchblickt habe.
 

fidibus

Mitglied
@Aqua: Das ich keine statics in diesm Fall benutze hat eigenlich nur was mit Stil zu tun. Man kann in diesem Fall wirklich alles mit static methods schreiben. Aber wenn man größere Programme schreibt geht das eben nicht mehr so.

-> Also gewöhnt man sich dirket vernünftigen Stil an.
Versuch mal mein Programm zu starten ohne die Instanzierung der Klasse.., du wirst sehn das es nicht
funktioniert. Du kommst eben nicht an die beiden Membermethoden ran.

Das liegt einfach daran das die static main nicht zu einem Objekt zugeordnet ist sondern der Klasse, während die beiden Membermethoden direkt dem Objekt derKlasse zugeordnet sind.

Achso man kann auch eine Innere Klasse erzeugen, wie du es gemcht hast muss ich aber nicht. Und um das mehrfache Instanziieren von Klassen zu verhindern gibt es das Singelton-Pattern.
 
Zuletzt bearbeitet:

fidibus

Mitglied
Hallo Medhusalem,

dir würde ich zunächst erstmal empfehlen. dich erstmal weiter mit Methodendekleration und den Grundlagen in Java zu beschäftigen. Das heißt:
1. wie deklariere ich Methoden und wie rufw ich sie auf.
2. Datentypen, Benutzung von Arrays in Zusammenhang mit Schleifen. Also sortieren und sowas.

Wenn die Grundlagen sitzen kannst du mit OOP anfangen. Also schreib zunächst deine Methoden, wie gehbt als statische Methoden.
Wenn du fragen hast kannst du diese gerne stellen.

@AqhaBall

kleiner Nachtrag zur Objektorientierung:

1. die Variable input ist kein Attribut der Klasse sondern nur eine lokale Variable, welche nur in der main gueltig ist.
2. beim Programmstart wird eben keine Instanz der Klasse erzeugt. Wie schon gesagt ist die main keine Objektmethode sondern eine Klassenmethode.
 

AquaBall

Top Contributor
1. Das liegt einfach daran das die static main nicht zu einem Objekt zugeordnet ist sondern der Klasse, während die beiden Membermethoden direkt dem Objekt derKlasse zugeordnet sind.
2. die Variable input ist kein Attribut der Klasse sondern nur eine lokale Variable

1) Unter diesem Aspekt hab ich die main() noch nie betrachtet.
Wieder was gelernt (Was ich eigentlich bei den Klassen schon immer kenne und verwende), Danke.
2) Ist mir schon klar, deshalb hab ich es auch unter '"' geschrieben. Aber das wäre ein typischer Kandidat für ein Attribut einer Klasse und wir "verstecken" es halt in der main.

@Medhusalem
Hallo Medhusalem,
dir würde ich zunächst erstmal empfehlen dich erstmal weiter mit den Grundlagen in Java zu beschäftigen.

Die Diskussion die wie hier führen hat sich nur nebenbei ergeben, sie hat nichts mit deinem Problem zu tun.
DU musst sie (noch) nicht verstehen.
 

Medhusalem

Mitglied
Super vielen Dank euch allen.

Dann werde ich mich intensiver mit der Grundlagen zum Deklatieren und Aufrufen von Methoden beschäftigen, bevor ich in meinem Buch weiter im Stoff vorranschreite.
Habt mir sehr geholfen, sehr schönes Forum, mit freundlichen Benutzern.

Liebe Grüße

PS: werde mich der Googlesuche bedienen um entsprechend dazu guten Lehrstoff zu finden, wenn jemand jedoch eine favourisierte Seite oder ein Tutorial dazu hat und es gerne mit mir teilen möchte, bin ich dessen natürlich nicht abgeneigt ;).
 

Oben