Problem beim Programmieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
hansjürgen
User
Beiträge: 16
Registriert: Samstag 8. Juli 2017, 14:44

Hallo,
Ich habe angefangen mir das Programmieren in Python beizubringen.
Doch Ich habe ein Problem bei einer Aufgabe.
Die Aufgabe lautet: Schreibe ein Programm welches eine beliebige Anzahl Noten vom Benutzer einliest und ihn nach seinem Wunschdurchschnitt fragt.
Berechne nun welche Note der Benutzer schreiben muss um seinen Wunschdurchschnitt zu bekommen.
Ich habe auch angefangen dieses Programm zu schreiben

Code: Alles auswählen

s = float(input("Wunschdurcchschnitt "))
n = int(input("Wie  viele Klausuren haben sie geschrieben: "))
n = n+1
for n in range(1, n):
    x = float(input("Note in der Klausur "))
    x = [x]
    y = sum(x)
    # Problem Werte die man bei x eingegeben hat werden nicht in der Liste gespeichert und somit auch nicht summiert
    Note = (y/n-s)/-n
print(Note)
Doch das Problem ist dass die Vaiabel y nicht die Werte der Variabel x in einer Liste speichert und summiert sondern nur einen Wert zur Berechnung der
Variabel Note nimmt. Dadurch kommt ein falsches Ergebnis zustande wie man hier sehen kann:
Wunschdurcchschnitt 2.3
Wie viele Klausuren haben sie geschrieben: 3
Note in der Klausur 2.1
Note in der Klausur 2.5
Note in der Klausur 2.1
0.5333333333333332
Meine Frage ist nun: Wie kann Ich erreichen dass in der Variabel y alle Werte von x gespeichert und summiert werden
Zuletzt geändert von Anonymous am Samstag 8. Juli 2017, 18:22, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

in deinem code erkennt man leider keine Einrückungen, was bei der for schleife schon von vorteil wäre :D

Aber ich geh mal davon aus, dass x = [x] dein Fehler ist und dies in der for schleife mit drin steht.
Falls das nun keine Schreibweise ist die mir unbekannt ist (was durchaus möglich ist), ersetzt du x mit einer Liste die nur x enthält.
Was du aber sicherlich machen solltest, ist das eingegebene x einer Liste hinzuzufügen und es nicht ersetzen.

Am besten gibst du der liste auch nen anderen namen, also zb:

Code: Alles auswählen

l = []
for n in range(1, n):
  x = float(input("Note in der Klausur "))
  l.append(x)
mit .append() fügst du der Liste l nun das neue x hinzu. Am ende ist l also eine Liste die alle eingetragenen x enthält.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@hansjürgen: Variablen sollten mehr als einen Buchstaben haben, damit man auch weiß, was darin gespeichert wird. Nennt man »n« »anzahl_klausuren« dann macht die Zeile »anzahl_klausuren = anzahl_klausuren + 1« logisch gesehen keinen Sinn. Genauswenig die Zeile »for anzahl_klausuren in range(1, anzahl_klausuren):« Wenn Du »x« »note« nennst, dann ist auch schnell klar, das Dir etwas fehlt, wo Du alle Noten speichern kannst, also eine Liste »noten«.

Was Du dann mit der Zeile »Note = (sum(noten) / anzahl_klausuren - wunsch_durchschnitt) / (-anzahl_klausuren)« ausrechnen willst, ist mir dann aber völlig unklar.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Du solltest auch noch sinnvolle Namen für deine Bezeichner vergeben. Programmcode wird deutlich häufiger gelesen als geschrieben und da ist es von Vorteil, wenn man sich sofort orientieren kann. n, s, x und y sind in diesem Kontext definitiv keine sinnvollen Namen.
hansjürgen
User
Beiträge: 16
Registriert: Samstag 8. Juli 2017, 14:44

Erstmal Vielen Dank für die aufschlussreiche Hilfe
Ich habe Ihre verbesserungsvorschläge nun übernommen.
Das Programm sieht nun wie folgt aus:

Code: Alles auswählen

Zeugnis = []
Wunschdurchschnitt = float(input("Wunschdurcchschnitt "))
Klausurenanzahl = int(input("Wie  viele Klausuren haben sie geschrieben: "))
Klausurenanzahl = Klausurenanzahl+1
for n in range(1, Klausurenanzahl):
    Klausurnote = float(input("Note in der Klausur "))
    Zeugnis.append(Klausurnote)
    Zeugnis = sum([Zeugnis])
    # Hier zeigt mir die Konsole einen Fehler an. Laut der Konsole dürfen Listen nicht den + Operator benutzen
    #
    letzte_Klausur = (Zeugnis/Klausurenanzahl-Wunschdurchschnitt)/-Klausurenanzahl
    # damit möchte Ich berechnen welche Note der Benutzer in der letzten Klausur erreichen muss um  seinen Wunschdurchschnitt zu erreichen
    # Das Problem ist jedoch, dass die Variabel Zeugnis den Datentyp Liste hat und somit wird mir auch hier ein Fehler angezeigt
    print(letzte_Klausur)
Die Fehler die die Konsole anzeigt stehen hier:
[codebox=text file=Unbenannt.txt]Wunschdurcchschnitt 2.3
Wie viele Klausuren haben sie geschrieben: 3
Note in der Klausur 1.7
Traceback (most recent call last):
File "C:/Users/erdogan seref/Programmieren/Semester bestehen 3.py", line 8, in <module>
Zeugnis = sum([Zeugnis])
TypeError: unsupported operand type(s) for +: 'int' and 'list'[/code]
Meine Frage ist lautet: Wie kann man meine Probleme, welche in den Kommentaren beschrieben sind lösen ?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@hansjürgen: jetzt ist das Programm schon viel lesbarer. Jetzt ist klar, dass es immer noch keinen Sinn macht, erst die Anzahl der Klausuren abzufragen und dann 1 drauf zu addieren. Außerdem wird klar, dass die Formel zum Berechnen der letzten Klausurnote falsch ist.
»sum« erwartet eine Liste mit Zahlen und keine Liste von Listen. Schau Dir auch nochmal die Einrückungen an und überlege Dir, ob die richtig sind.
BlackJack

@hansjürgen: Die `sum()`-Funktion erwartet hier eine Liste mit Zahlen, das wird aber nicht übergeben. Eine Liste mit Zahlen wäre `Zeugnis` selbst schon. Zumindest bevor Du die Summe an den Namen binden würdest. Womit dann ja das `Zeugnis.append()` im nächsten Schleifendurchlauf nicht mehr funktioniert, denn Zahlen haben keine `append()`-Methode. Du versuchst hier den einen Namen in der selben Schleife für zwei sehr unterschiedliche Werte zu verwenden.

In der Schleife passiert auch zu viel. Da stehen Sachen die für jede Klausur wiederholt werden, die *nach* der Eingabe der Noten passieren müssen, denn nur wenn man alle Noten eingegeben hat, macht es Sinn die fehlende Note zu berechnen.

Wie hast Du die Formel dafür eigentlich hergeleitet?

Brauchst Du eine Liste mit den Noten überhaupt?
BlackJack

@hansjürgen: Am besten teilst Du das Programm in die drei Abschnitte Dateneingabe, Berechnung, und Ausgabe ein und entwickelst das Programm in diesen drei Schritten. Also erst einmal nur den Teil der die Daten erfasst. Und zur Kontrolle danach einfach nur die Eingaben wieder ausgibt.

Wenn das funktioniert, musst Du Dir Gedanken über die Berechnung machen und die umsetzen. Und das Ergebnis zur Kontrolle einfach ausgeben.

Jetzt könnte man sagen damit ist der dritte Abschnitt auch fertig, aber damit überlässt man dem Benutzer die Interpretation des Ergebnisses. Es gibt da ja Zahlen die keinen ”Sinn” ergeben, weil es keine gültigen Noten sind. Und auch dabei gibt es zwei Fälle die man unterscheiden kann.

Zur Berechnung: Das ist letztlich eine normale Matheaufgabe bei der Du überlegen musst was Du an Grössen kennst/hast, welche Formeln es dazu gibt die den Durchschnitt ausrechnen, wie Du da Deine Unbekannte hinzuformulieren kannst, und dann nach dieser Unbekannten die Formel umstellen musst.
hansjürgen
User
Beiträge: 16
Registriert: Samstag 8. Juli 2017, 14:44

Erstmal vielen dank für die schnellen und guten antworten
Ich habe das Programm nun umgeschrieben und es sieht wie folgt aus:

Code: Alles auswählen

Zeugnis = []
Wunschdurchschnitt = float(input("Wunschdurcchschnitt "))
Klausurenanzahl = int(input("Wie  viele Klausuren haben sie geschrieben: "))
Klausurenanzahl = Klausurenanzahl+1
for n in range(1, Klausurenanzahl):
    Klausurnote = float(input("Note in der Klausur "))
    Zeugnis.append(Klausurnote)
Zeugnis = sum(Zeugnis)
# Zeile acht habe Ich eingerückt und die eckigen Klammern entfernt
letzte_Klausur = Wunschdurchschnitt*Klausurenanzahl-Zeugnis
# Ich habe die Formel nun richtig umgestellt
print(letzte_Klausur)
# Zeile 12 hab Ich eingerückt
Das Programm funktioniert nun wie man anhand der Konsolenausgabe erkennen kann:
Wunschdurcchschnitt 2.3
Wie viele Klausuren haben sie geschrieben: 3
Note in der Klausur 2.1
Note in der Klausur 2.5
Note in der Klausur 2.3
2.3
Vielen Dank für die Hilfe und die aufschlussreichen Kommentare
Zuletzt geändert von Anonymous am Montag 10. Juli 2017, 20:28, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@hansjürgen: Wie schon gesagt würde ich da noch Code zum interpretieren des Ergebnisses schreiben, denn die Ausgaben sind nicht immer sinnvoll. Wenn man beispielsweise als Wunschdurchschnitt 4 angibt und dann zwei Klausuren mit 1 und 2, dann kommt als Ergebnis das man eine 9 schreiben müsste, was technisch nicht geht. Umgekehrt wenn man eine 1 haben möchte und zwei Klausuren mit 5 und 6 angibt, kommt als Ergebnis man müsste eine -8 schreiben, was auch nicht möglich ist.
bergen123
User
Beiträge: 13
Registriert: Mittwoch 29. März 2017, 16:31

Mit meine einfacher Python und Mathe kenntnisse ich kann nicht vorstellen Rechner Wunschdurchschnitt zusammen mit Klausurenzahlt , weil zwei verschiedenen Sache sind , das wie ich denke.....
Sicher das Ergebnisse die du bekommst , ist nicht die durchschnitt für deinen Klausurezahlt......
BlackJack

Da das nach einer typischen Informatikunterricht-Aufgabe klingt, und ich so etwas damals in Pascal machen musste, hier mal spasseshalber eine Lösung in Pascal — mit Interpretation des Ergebnisses und Prüfung der Benutzereingaben:
[codebox=delphi file=Unbenannt.pas]program MarkForWantedAverage;

const
MIN_MARK = 0.5; { 1+ }
MAX_MARK = 6.5; { 6- }

var
wantedAverage: Real;
examCount: Byte;
marksTotal: Real;
neededMark: Real;

function IsValidMark(mark: Real): Boolean;
begin
IsValidMark := (mark >= MIN_MARK) and (mark <= MAX_MARK);
end;

function ReadMark(const prompt: String): Real;
var
line: String;
error: Integer;
begin
error := -1;
while error <> 0 do
begin
Write(prompt);
ReadLn(line);
Val(line, ReadMark, error);
if (error = 0) and (not IsValidMark(ReadMark)) then
begin
error := -1;
WriteLn('Note muss zwischen ', MIN_MARK:0:1, ' und ', MAX_MARK:0:1,
' liegen.');
end;
end;
end;

function ReadCount(const prompt: String): Byte;
var
line: String;
error: Integer;
begin
error := -1;
while error <> 0 do
begin
Write(prompt);
ReadLn(line);
Val(line, ReadCount, error);
end;
end;

function ReadMarksTotal(count: Byte): Real;
var
mark: Real;
i: Byte;
tmp: String;
begin
ReadMarksTotal := 0;
for i := 1 to count do
begin
Str(i, tmp);
mark := ReadMark('Note der ' + tmp + '. Klausur: ');
ReadMarksTotal := ReadMarksTotal + mark;
end;
end;

begin
WriteLn(
'Nach Eingabe des Wunschdurchschnitts und der Anzahl der bereits geschriebenen',
#13#10,
'Klausuren, berechnet dieses Programm die Mindestnote für die letzte Klausur.',
#13#10,
'Die Noten sind zwischen 0.5 (1+) und 6.5 (6-) einzugeben.');

wantedAverage := ReadMark('Wunschdurchschnitt: ');
examCount := ReadCount('Anzahl der geschriebenen Klausuren: ');
marksTotal := ReadMarksTotal(examCount);

neededMark := wantedAverage * (examCount + 1) - marksTotal;

if neededMark < MIN_MARK then
WriteLn('Nicht möglich!')
else if neededMark >= MAX_MARK then
WriteLn('Note ist egal!')
else
WriteLn('Benötigte Mindestnote: ', neededMark:0:1);
end.[/code]
Antworten