Autor Beitrag
Marco D.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 17:19 
Hallo,

ich schreibe derzeit an einem Zensuren-Analyse-Programm. Dazu muss ich einige Male das arithmetische Mittel aus z.B. '1,2,3,,4,5,6' berechnen. Dazu habe ich mir folgende Funktion geschrieben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TForm1.ArithMittel(str:string) : integer;
var i:integer; temp:string;
begin
  if Length(str)>0 then
  begin
    temp:='';
    for i := 1 to length(str) do
    begin
      if not (str[i]=','then temp:=temp+str[i];
    end;
    result:=0;
    for i := 1 to Length(temp) do
    begin
      result:=result+strtoint(temp[i]);
    end;
    result:=result div length(temp);
  end;
end;

Jedoch scheinen manchmal falsche Zahlwerte rauszukommen. Kann man diese Funktion vereinfachen und nebenbei dafür sorgen, dass sie alles richtig macht?

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
der Berliner
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 417

Win Xp Home
delphi 2005
BeitragVerfasst: Mo 01.05.06 18:29 
Hallo, Also ich hab die Function mal Ausprobiert.
Die scheint doch aber richtig zu rechenen.

(1+2+3+4+5+6) DIV 6 = 3

ganz richtig währe narürlich 3,5
das liegt aber wohl am Div

gruß

_________________
[b]Ich weiß nicht immer, wovon ich rede. Aber ich weiß, dass ich recht habe.[b]
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 18:33 
Ja, eigentlich habe ich das Problem schon selber behoben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function TForm1.ArithMittel(str:string) : extended;
var i:integer; temp:string;
begin
  if Length(str)>0 then
  begin
    temp:='';
    for i := 1 to length(str) do
    begin
      if not (str[i]=','then temp:=temp+str[i];
    end;
    result:=0;
    for i := 1 to Length(temp) do
    begin
      result:=result+strtoint(temp[i]);
    end;
    result:=result / length(temp);
  end;
end;

Manchmal kommen bei der Zensuren-Analyse aber immer noch total sinnlose Ergebnisse heraus. Aber der Fehler liegt wohl woanders :-(

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
aim65
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 312

Win 9x, Win XP
Delphi 3pro, 7PE
BeitragVerfasst: Mo 01.05.06 18:39 
Auch wenn die Ausgangsziffern vom Typ Integer sind, kann das Ergebnis ja einen Dezimalbruch darstellen. Daher mußt Du "result" als Floating Point deklarieren und in Zeile 16 folgendes korrigieren:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function TForm1.ArithMittel(str:string) : double;  
.
.
    result:=result / length(temp);

Dann müssten Die Ergebnisse ok sein.
Man könnte z.B. die Source-Länge verkürzen, indem man jeden gefundenen Zahlenstring sofort in ein Integer umwandelt, aufaddiert, und dann durch Zahl der gefundenen Zifern teilt.
der Berliner
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 417

Win Xp Home
delphi 2005
BeitragVerfasst: Mo 01.05.06 18:41 
Hat er doch gemacht :D
siehe oben :D
gruß

_________________
[b]Ich weiß nicht immer, wovon ich rede. Aber ich weiß, dass ich recht habe.[b]
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 18:44 
user profile iconaim65 hat folgendes geschrieben:
Auch wenn die Ausgangsziffern vom Typ Integer sind, kann das Ergebnis ja einen Dezimalbruch darstellen. Daher mußt Du "result" als Floating Point deklarieren und in Zeile 16 folgendes korrigieren:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function TForm1.ArithMittel(str:string) : double;  
.
.
    result:=result / length(temp);

Dann müssten Die Ergebnisse ok sein.

Was meinst du mit Ausgangsziffern? Habe ich nicht verstanden, was du mir damit sagen willst.
user profile iconaim65 hat folgendes geschrieben:
Man könnte z.B. die Source-Länge verkürzen, indem man jeden gefundenen Zahlenstring sofort in ein Integer umwandelt, aufaddiert, und dann durch Zahl der gefundenen Zifern teilt.

Gute Idee :zustimm: Das nehme ich in die To-Do-Liste mit auf, aber jetzt will ich erstmal an dem richtigen Berechnen der Ergebnisse arbeite.

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
aim65
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 312

Win 9x, Win XP
Delphi 3pro, 7PE
BeitragVerfasst: Mo 01.05.06 18:53 
@ der Berliner
Hat sich einfach überschnitten :shock:

@ Marco D.
Mit Ausgangsziffern meinte ich Deine Zensuren im String:"1,4,2,3,..." usw.
Kann es sein, daß Du im Zensurenstring evtl. mal ein Komma vergessen hast und dann so was entstand: "1,3,44,,5,222..."? Dann käme natürlich Käse heraus. :wink:
Hab jedenfalls bisher nix Falsches in Deiner Funktion gefunden.
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 18:58 
Ich schreibe mir erstmal eine Funktion, die überprüft, ob die Zensuren richtig eingegeben wurden (X,X,X,X).

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
aim65
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 312

Win 9x, Win XP
Delphi 3pro, 7PE
BeitragVerfasst: Mo 01.05.06 19:03 
Hatte ich noch vergessen:
Ich würde auf gültige Zahlen testen. Das würde sicherstellen, daß auch ein Nicht-Kommazeichen unterdrückt wird.
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 19:06 
Einfache vom ersten Zeichen an jedes zweite durchgehen, und prüfen ob es eine Zahl ist (wie könnte man das machen?)

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 19:16 
Geht das auch einfacher als so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function IsValidMark (C:char) : boolean;
begin
  result:=false;
  if C='1' then result:=true
  else if C='2' then result:=true
  else if C='3' then result:=true
  else if C='4' then result:=true
  else if C='5' then result:=true
  else if C='6' then result:=true
  else result:=false;
end;

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 01.05.06 19:25 
ausblenden Delphi-Quelltext
1:
Result := C in ['1'..'6'];					
aim65
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 312

Win 9x, Win XP
Delphi 3pro, 7PE
BeitragVerfasst: Mo 01.05.06 19:28 
Nee, das wäre zu unsicher (z.B., wenn aus Versehen zwei Kommas kommen). Deine Rouitne ist schon ok. Hab jetzt kein Delphi offen, daher PseudoCode:

for n := 1 to length(str)
if not str[n] in ['1'..'6'] then Schmeiß-Raus
else ZahlenChar in Integer umwandeln, Counter erhöhen, Zahl aufaddieren

Ich weiß, sieht grausam aus, aber Du kriegst den Sinn wohl raus.
Kannst die Abfrage auch positiv machen, dann if und else-Inhalt vertauschen.
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Mo 01.05.06 19:41 
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
function calcAvg(S: String): Extended;
var
 I, Sum: Integer;
begin
 with TStringList.Create do
  try
   Delimiter := ',';
   DelimitedText := S;
   Sum := 0;
   for I := 0 to Count-1 do
    inc(Sum, StrToInt(Strings[I]));
   if Count = 0 then
    raise EInvalidOp.Create('Cannot calculate mean of an empty set.');
   Result := Sum/Count;
  finally
   Free;
  end;
end;

procedure TForm1.ButtonClick(Sender: TObject);
var
 Input: String;
begin
 Input := '1, 2, 3';
 try
  ShowMessage(Format('Der Mittelwert lautet %.1f',[calcAvg(Input)]));
 except
  on E:Exception do
    MessageDlg('Fehlerhafte Eingabe.', mtError, [mbOk], 0);
 end;
end;


Zuletzt bearbeitet von delfiphan am Mo 01.05.06 19:42, insgesamt 1-mal bearbeitet
Marco D. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Mo 01.05.06 19:41 
Danke! Das klappt erstmal :zustimm:

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot