Entwickler-Ecke

Algorithmen, Optimierung und Assembler - Zufällige Rechenoperation


Brina* - Fr 05.09.08 17:00
Titel: Zufällige Rechenoperation
Hallo Allerseits,

ich sags mal gleich vorweg, ich bin ziemlich schwach in Informatik und Programmierung, also ich hoffe, dass meine Frage/n nicht allzu dumm sind/ werden...:( ;)

Also und zwar geht es um Folgendes:

Wir haben ein Rechenprogramm erstellt, wo wir schlichtweg ein Label haben, welches uns zufällig zwei Zahlen a und b, vorgibt mit der Rechenoperation "plus". Der Quelltext für den "Startbutton", welche die zufällige Ausgabe der Rechenaufgabe erzeugt sieht dann so aus:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
begin
randomize
a:=random(100)+1;
b:=random(100)+1;
label1.caption:= IntToStr(a)+'+'+IntToStr(b)+'=';
end;


Nun ist unsere Aufgabe zusätzliche eine zufällige Ausgabe der Rechenoperation, also anstelle von "+" zu erzeugen...Kann mir da Jemand helfen, wie das geht?

Hoffe, ihr versteht, was ich meine... :/

Liebe Grüße,
Brina*

Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt


Bergmann89 - Fr 05.09.08 17:08

Hi,

weiß so richtig was du meinst, vlt so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TForm1.FormCreate(Sender: TObject);
begin
  randomnize;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  a:=random(100)+1;
  b:=random(100)+1;
  label1.caption:= IntToStr(a)+'*'+IntToStr(b)+'=';
end;


MfG Bergmann.

p.s: Randomize sollte man nur einmal aufrufen, alos steht es im FormCreate-Ereignis...


Gausi - Fr 05.09.08 17:31

Hallo und :welcome: in der Entwickler-Ecke,

Bei sowas kommen gleich bestimmt die Optimierer, wie man das am geschicktesten lösen kann, ich probiers mal einfach. ;-)

Es gibt ja vier verschiedene Grundrechenarten, +, #, *, :. Also macht man ein Random(4) dazu und wählt dann entsprechend das Zeichen aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var c: Char;
    tmp: Integer;
begin
  tmp := Random(4);
  case tmp of
    0: c := '+';
    1: c := '-';
    2: c := '*';
    else c := ':';
  end;
  // ...
end;
Und das c musst du dann nur in den String einbauen. Aber alles wird hier nicht vorgerechnet. :zwinker:


BenBE - Fr 05.09.08 17:44

user profile iconGausi hat folgendes geschrieben:
Bei sowas kommen gleich bestimmt die Optimierer, wie man das am geschicktesten lösen kann, ich probiers mal einfach. ;-)



Delphi-Quelltext
1:
2:
3:
4:
5:
const
  op = '+-*/';
begin
  Label1.Caption := Format('Berechne: %d %s %d = ?', [Random(100), op[Random(4)+1], Random(100)]);
end;


Die Angabe '+-*/'[Random(4)] wird ja leider vom Compiler nicht angenommen :mrgreen:


Brina* - Fr 05.09.08 17:54

Hallo ihr beiden und ersteinmal vielen Dank für eure Antworten!!!

Also BenBE ich muss sagen, dass ich glaube ich vieeel zu dümmlich bin, um hinter deinen Quelltext zu steigen :(:(:(
Ich könnte deinen Quelltext nicht erklären, also was was bedeutet und für welche Funktion steht..oh man, sorry ich bin echt ziemlich...unwissend... :(

@Gausi

Also da steig ich wenigstens ein bisschen durch nur ein par Fragen hätte ich:

1. Was bdeutet tmp - Also ist das einfach eine variabel, die du festgelegt hast oder ist es eine bestimmte Funktion?

2. Was bedeutet "case tmp of" ? Dass er aus 0,1,2 oder ":" auswählen soll?
Wenn ja, warum ist randomize mit 4 Ziffern angegeben und es stehen schlussendlich nur 0,1,2 da?

Mhh komme mir echt blöd vor, aber ich will ja auch irgendwie dahinter steigen... :/

liebe Grüße und Danke nochmals,
Brina*


Tilman - Fr 05.09.08 17:59

Dass du den Beitrag von BenBe nicht verstanden hast macht nix, den darfst du getrost nicht verstehen ;)

tmp ist eine Abkürzung für "Temporary" bzw. "Temporär", also vorrübegrehend, und wird gerne mal als "Hilfsvariable" benutzt. Natürlich hätte Gausi hier auch jeden anderen namen vergeben können, z.B. "Hilfsvariable" oder so.

Case unterscheidet wie von dir richtig geraten Fälle - und zwar kann Random(4) 4 Fälle erzeugen: 0,1,2,3 - wobei der letzte Fall in der Case-Fallunterscheidung durch das "Else" abgebildet wird (wenn tmp weder 0 noch 1 noch 2 ist - dann muss es eben 3 sein. Hätte man auch anders schreiben können).

Grüße,
Tilman


Gausi - Fr 05.09.08 18:04

Zur weiteren Erklärung, warum ich da "else" statt "3:" geschrieben habe: Als Mensch sieht man, dass tmp nur die Werte 0 bis 3 annehmen kann, der Compiler wahrscheinlich nicht. Der wird wahrscheinlich annehmen, dass möglicherweise keine der 4 Fälle auftritt, was dann dazu führen würde, dass der Variable c kein Wert zugewiesen wird. Und genau das würde der Compiler als Warnung ausspucken - daher else, was hier gleichbedeutend dazu ist.

Aber das kann dir auch der Lehrer erklären. Zumindest dann, wenn er BenBE's Lösung auf Anhieb durchblickt. :lol:


BenBE - Fr 05.09.08 18:04

user profile iconBrina* hat folgendes geschrieben:
Hallo ihr beiden und ersteinmal vielen Dank für eure Antworten!!!

Also BenBE ich muss sagen, dass ich glaube ich vieeel zu dümmlich bin, um hinter deinen Quelltext zu steigen :(:(:(
Ich könnte deinen Quelltext nicht erklären, also was was bedeutet und für welche Funktion steht..oh man, sorry ich bin echt ziemlich...unwissend... :(

Die Funktion Format erzeugt basierend auf einem vorgebenem Muster mit Platzhaltern und den dazugehörigen, einzusetzenden Werten, eine Zeichenkette. Ich weiß, das sieht mehr als kryptisch aus, und war hauptsächlich als Antwort auf Gausi's Ruf nach den Optimierern ;-) gedacht.

user profile iconBrina* hat folgendes geschrieben:
@Gausi

Also da steig ich wenigstens ein bisschen durch nur ein par Fragen hätte ich:

1. Was bdeutet tmp - Also ist das einfach eine variabel, die du festgelegt hast oder ist es eine bestimmte Funktion?

Tmp steht für temporary, also temporär\zeitlich begrenzt. Ähnlich wie das Temp-Verzeichnis von Windows als Zwischenablage für Dateien zu verstehen ist, ist das einfach ein (gebräuchlicher) Name für eine Variable, die ein Zwischenergebnis enthält.

user profile iconBrina* hat folgendes geschrieben:
Mhh komme mir echt blöd vor, aber ich will ja auch irgendwie dahinter steigen... :/

liebe Grüße und Danke nochmals,
Brina*

Einfach Fragen, wo es klämmt, wir helfen schon ;-)

Den Rest hat Tilman ja schon erklärt, obwohl ...
user profile iconTilman hat folgendes geschrieben:
Dass du den Beitrag von BenBe nicht verstanden hast macht nix, den darfst du getrost nicht verstehen ;)

@Tilman: Wie darf man das jetzt verstehen :mrgreen:


Brina* - Fr 05.09.08 18:10

Puhhh, ich bin ja froh, dass ich nicht gleich als hoffnungsloser Fall angesehen werde ;)
Ich bemühe mich echt hinter all das zu steigen, aber es fällt mir unwahrscheinlich schwer...

Ähm mal eine Frage, wo stellt ihr das beim schreiben hier ein, dass als DelphiQuelltext so anzeigt?

Liebe Grüße,
Brina*


BenBE - Fr 05.09.08 18:12

Ganz einfach <span class="inlineSyntax"><span class="codecomment">{PROTECTTAG95fe2f4470385c3b55d7d96c2882dc38}</span></span> um deinen Code herum platzieren ;-)


Tilman - Fr 05.09.08 18:15

user profile iconBenBE hat folgendes geschrieben:

user profile iconTilman hat folgendes geschrieben:
Dass du den Beitrag von BenBe nicht verstanden hast macht nix, den darfst du getrost nicht verstehen ;)

@Tilman: Wie darf man das jetzt verstehen :mrgreen:


:P Wollte damit bloß zum Ausdruck bringen dass ich es relativ normal finde, als Anfänger so eine Zeile nicht gleich zu durchblicken ^^

// brina: gibt oben am editor auch so knöpfe dafür, für die Code-Darstellung ist "Bereiche" zuständig.


Brina* - Fr 05.09.08 18:20

Dankeschöön :9

Also, ich gehe jetzt davon aus, dass dies der korrekte Quelltext wäre, mit zufälliger Rechenoperation und zufälligen Zahlen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
...
var
c:char;
tmp:Integer;

begin
randomize
a:=random(100)+1;
b:=randoom(100)+1;
tmp:=random(4);
case tmp of
0:c:='+';
1:c:='-';
2:c:='*';
else c:=':';

label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';

end;
...


(var a und b habe ich bereits global deklariert!)

*vorsichtigGuck*

liebe Grüße,
Brina*


Bergmann89 - Fr 05.09.08 18:22

@Gausi:
habs grad ausprobiert, die einzige warnung die kommt ist:

Quelltext
1:
[Warnung] Unit1.pas(29): Variable 'i' ist möglicherweise nicht initialisiert worden                    


also waäre für einen anfänger das vlt besser zu verstehen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var Operator: Char;
    TMP: Integer;
begin
  TMP := random(4);
  case TMP of
    0: Operator := '+';
    1: Operator := '-';
    2: Operator := '*';
    3: Operator := '/';
    else ShowMessage('Fehler beim zufälligen ermitteln des Operators.'); //wenn's denn unbedingt sein muss^^
  end;
end;


@Brina*: nich ganz. TMP ist bloß ne Zahl und nich der Operator. Der Operator wird ja oben mit dem Case-of ermittlet und dann in Operator (bzw. c) gespeichert, also musst du Operator (bzw. c) in den String einbauen.


MfG Bergmann.


Gausi - Fr 05.09.08 18:25


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
case tmp of 
0:c:='+'
1:c:='-'
2:c:='*'
else c:=':'
end;

label1.caption:= InToStr(a)+c+IntToStr(b)+'=';


Das Case hat ein verstecktes begin - da muss immer ein end dazu. Und in das Label kommt das Zeichen c. ;-)


Marc. - Fr 05.09.08 18:27

Neben diversen anderen Rechtschreibfehlern, ist auch das randomize Fehl am Platz. Sollte nur einmal beim Programmstart aufgerufen werden.

Grüße,
Marc.


BenBE - Fr 05.09.08 18:28

user profile iconBrina* hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
...
var
c:char;
tmp:Integer;

begin
randomize
a:=random(100)+1;
b:=randoom(100)+1;
tmp:=random(4);
case tmp of
0:c:='+';
1:c:='-';
2:c:='*';
else c:=':';

label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';

end;
...


Benutze mal bitte, wie auch die anderen es hier im Forum tun, eine gewisse Einrückung für deinen Source, damit wird das ganze nicht nur übersichtlicher, sondern es hebt auch Fehler mit Unter hervor:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  case tmp of
  0:
    c:='+';
  1:
    c:='-';
  2:
    c:='*';
  else
    c:=':';

    label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';
  end;


Fällt Dir was auf???

Ich denk, du meintest:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  case tmp of
  0:
    c:='+';
  1:
    c:='-';
  2:
    c:='*';
  else
    c:=':';
  end;

  label1.caption:= InToStr(a)+c+IntToStr(b)+'=';


Stimmt's???


Brina* - Fr 05.09.08 18:29

Achso okay! Vielen, vielan Dank euch allen! Hab mir den Quelltext + Erläuterungen jetzt aufgeschrieben, mal sehen, was meine Lehrerin dann dazu sagt und was sie uns vorgeschlagen hätte.

Ich hoffe ja, dass ich mich in das ganze Delphi noch hereinfitzel und irgendwann selbst auf solche Ideen komme.Meistens sitze ich vor den Aufgaben und habe keinen Plan, auch wenn ich es andersherum - also Quodes lesen, eigentlich kann, also das, was wir im Unterricht machen.

Liebe Grüße,
Brina*

EDIT: @ BenBE , ja, das mit dem end davor wusste ich nicht ;) Oder besser, ich wusste nicht, dass mit dem case of ein begin verbunden ist. Ich dachte, dass ich nur das end für die gesamte procedure des Buttons schreiben müsste ;)
Aber jetzt bin ich schlauer diesbezüglich ;9 Danke nochmals!


Tilman - Fr 05.09.08 18:31

Und wenn man mit den begins und ends durcheinanderkommt ist es guter Stil diese mit Kommentaren zu versehen, als fortgeschrittener sowieso, aber als Anfänger auch sehr zu empfehlen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure irgendwas;
begin
  if bla then
    begin
      case tmp of
        0: machwas;
        1: machwasandres;
        else
          sonstwas;
      end// case tmp
    end// if bla
end// procedure irgendwas


elundril - Fr 05.09.08 18:31

user profile iconBenBE hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  case tmp of
  0:
    c:='+';
  1:
    c:='-';
  2:
    c:='*';
  else
    c:=':';
  end;

  label1.caption:=  InToStr(a)+tmp+IntToStr(b)+'=';


Stimmt's???


ich weiß ja nicht welche delphiversion ihr habt aber bei meiner schreibt man inttostr noch immer mit zwei T.


Marc. - Fr 05.09.08 18:32

user profile iconBenBE hat folgendes geschrieben:


Delphi-Quelltext
1:
    label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';                    

Ich denk, du meintest:


Delphi-Quelltext
1:
2:
...
  label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';


Stimmt's???

Nö!
Ich denk, du meintest:

Delphi-Quelltext
1:
label1.caption:= IntToStr(a)+c+IntToStr(b)+'=';                    


Brina* - Fr 05.09.08 18:34

Das IntToStr mit einem "t" war nur ein Tippfehler, sorry!


BenBE - Fr 05.09.08 18:49

user profile iconMarc. hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:


Delphi-Quelltext
1:
    label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';                    

Ich denk, du meintest:


Delphi-Quelltext
1:
2:
...
  label1.caption:= InToStr(a)+tmp+IntToStr(b)+'=';


Stimmt's???

Nö!
Ich denk, du meintest:

Delphi-Quelltext
1:
label1.caption:= IntToStr(a)+c+IntToStr(b)+'=';                    

Hab mich in meinem Beispiel hauptsächlich auf den Case\End-Fehler bezogen. Dn Schreibfehler hab ich übersehen ...

user profile iconTilman hat folgendes geschrieben:
Und wenn man mit den begins und ends durcheinanderkommt ist es guter Stil diese mit Kommentaren zu versehen, als fortgeschrittener sowieso, aber als Anfänger auch sehr zu empfehlen:


Dann sollte man das aber korrekt tun ;-)
user profile iconTilman hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure irgendwas;
begin
  if bla then
  begin
    case tmp of
      0: machwas;
      1: machwasandres;
      else
        sonstwas;
    end// case tmp
  end// if bla
end// procedure irgendwas


Case else hat nur ein End, wenn man explizit mit else begin einen Block anfängt. Dann gehört dieses End aber nicht zum Case else, sondern zum expliziten begin dieses Blockes ;-)


Gausi - Fr 05.09.08 18:56

user profile iconBenBE hat folgendes geschrieben:
Case else hat nur ein End, wenn man explizit mit else begin einen Block anfängt. Dann gehört dieses End aber nicht zum Case else, sondern zum expliziten begin dieses Blockes ;-)


Nein. Case endet immer mit einem end.

Delphi-Hilfe hat folgendes geschrieben:
Die Syntax einer case-Anweisung lautet


Delphi-Quelltext
1:
2:
3:
4:
5:
case SelektorAusdruck of
  caseList1: Anweisung1;
  ...
  caseListn: Anweisungn;
end


BenBE - Fr 05.09.08 19:05

user profile iconGausi hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:
Case else hat nur ein End, wenn man explizit mit else begin einen Block anfängt. Dann gehört dieses End aber nicht zum Case else, sondern zum expliziten begin dieses Blockes ;-)


Nein. Case endet immer mit einem end.

Delphi-Hilfe hat folgendes geschrieben:
Die Syntax einer case-Anweisung lautet


Delphi-Quelltext
1:
2:
3:
4:
5:
case SelektorAusdruck of
  caseList1: Anweisung1;
  ...
  caseListn: Anweisungn;
end

Das ist klar. Es ging aber um das von Tilman in Zeile 10 in seinem Quelltext überflüssig eingefügte end// else.


Tilman - Fr 05.09.08 19:14

Oh ja stimmt hast recht :-) hatte vorher sogar noch ein überflüssiges begin drinne, werde das end natürlich auch noch rausnehmen :roll: (irgendwie kam mir der code eh komisch vor ^^) weiß auch net was das heute ist ^^

P.S. da seht's ihr mal wie wichtig das kommentieren ist!!! *gg


BenBE - Fr 05.09.08 20:28

user profile iconTilman hat folgendes geschrieben:
P.S. da seht's ihr mal wie wichtig das kommentieren ist!!! *gg

GANZ WICHTIG!!! :mrgreen: [http://geekandpoke.typepad.com/geekandpoke/2008/07/good-comments.html]