Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hi!

Ich möchte auf meiner Homepage eine Art "Witz des Tages" realisieren. Wie kann man das mit PHP umsetzen? Das Skript soll aus einer Sammlung von Texten jeden Tag einen anderen auf meiner Seite anzeigen.

Hat jemand eine Idee oder gibt es da schon was fertiges?

Gruß

Lenzibaer

Geschrieben

@ dr.disk poste mal den Zweizeiler, meißtens kann man es schnell in PHP umschreiben, PHP hat ja schliesslich (meiner Meinung nach) eine ähnliche Syntax wie Perl.

Zumindest fiel mir bis jetzt die Übersetzung von Perl nach PHP und umgekehrt nicht schwer ;)

Geschrieben

Ok, hier ist er.

Als Beispiel wird die Fortune-Datei genommen, bei der sind die einzelnen Sprüche durch ein einzelnes % in einer Zeile getrennt. Damit's auch funktioniert ist noch etwas 'Beiwerk' ausenrum, die zwei Zeilen die ich meinte ist die zweite und die dritte.


open FH, "< /usr/share/fortune/fortunes";

$/ = "%\n";

rand($.) < 1 && chomp($text = $_) while <FH>;

close FH;

print $text;

Diese Lösung ist auch fair, d.h. jeder Spruch wird mit der gleichen Wahrscheinlichkeit genommen. Für weitere Erklärungen bin ich erreichbar.

Wenn Du es schaffst den Code nach PHP zu übersetzen poste hier bitte den Code. Würd mich mal interessieren wie er dort aussieht.

Geschrieben

...und leider auch falsch. Dein Beispiel geht der Annahme, daß ein Fortune-Spruch nur eine Zeile groß ist. Das ist aber nicht der Fall. So ein Spruch/Witz kann über mehrere Zeilen gehen, getrennt werden die beiden durch ein einzelnes % Zeichen.

kleines Beispiel:


A day without sunshine is like night.

%

A diplomat is a man who can convince his wife she'd look stout in a fur

coat.

%

A diplomat is someone who can tell you to go to hell in such a way that

you will look forward to the trip.

Geschrieben

ah so.. na gut.

dann halt


$inhalt=implode("",file("/usr/local/fortune/fortunes"));
$eintraege=explode("\n%\n",$inhalt);
echo $eintraege[rand(0,sizeof($eintraege))];
[/PHP]

Geschrieben

Hier nochmals der Code:

2: $/ = "%\n";

3: rand($.) < 1 && chomp($text = $_) while <FH>;

zu Zeile 2:

man kann ja aus einer Datei genau eine Zeile lesen. Woher weiß aber der lesen-Befehl, daß die Zeile am Ende ist? Bei den meisten Sprachen wird der Annahme gegangen, daß ein '\n' am Zeilenende steht. Bei Perl kann man dieses Wert selbst ändern, er steht in der Variable $/. Ich hab damit also gesagt, daß eine Zeile nicht wie sonst mit einem '\n' sondern mit einem '%\n' endet. Genau die Fortune Bedingung. Ein Spruch ist durch ein einzelnes % in einer Zeile von dem nächsten getrennt. Deswegen kann ein Spruch auch über mehrere Zeilen gehen.

zu Zeile 3:

Zeile 3 könnte man auch so schreiben:

while <FH> {

... tu was...

}

Um sich die Klammern zu sparen kann man die Schleife an das Ende des ...tu was... setzen, <FH> liest genaue eine Zeile aus der Datei ein. Also läuft die Schleife über alle Zeilen aus der Datei. Soweit war's leicht.

Als nächstes betrachten wir rand($.). In $. steht die aktuelle Zeilennummer drin, bei uns also die Nummer des Spruches. rand($.) erzeugt eine Zufallszahl x für die gilt 0 < x < $. Sobald x < 1 ist, ist dieser Ausdruck wahr und der Teil hinter dem logischen und (&&) wird ausgeführt. Ist die Bedingung nicht wahr wird abgebrochen und mit dem nächsten Schleifendurchgang weitergemacht.

In $_ steht die gelesene Zeile drin, chomp entfernt von dieser Zeile das Zeilenende, bei uns war das $/ = '%\n' - das will ich ja beim Ausgeben des Spruches nicht sehen. Das war's.

zum Thema 'Fairness':

auf den ersten Blick vielleicht nicht ersichtlich, dieser Algorithmus ist wirklich fair, d.h. alle Sätze werden mit der gleichen Wahrscheinlichkeit gewählt und es ist meines Wissens nach auch die schnellste Möglichkeit aus einer Datei mit unbekannter Satzanzahl einen zufällig zu wählen.

Gehen wir es mal an einem Beispiel durch:

aktuelle Satznummer n = 1:

rand(1) < 1 laut Definition von rand immer wahr, d.h. der Satz wird in $text kopiert

n = 2

rand(2) < 1 - die Wahrscheinlichkeit liegt bei 50% das diese Bedingung wahr ist. Nochmals zu rand: eine Zahl zwischen 0 und 2. Eins ist mittendrin, die Wahrscheinlichkeit, daß die Zahl kleiner 1 ist beträgt also 50%, genau die Hälfte. Ist dies der Fall wird der erste Satz durch den zweiten ersetzt. Bei 50% Wahrscheinlichkeit, daß der Zweite Satz jetzt drin steht ist der Algorithmus bis jetzt fair.

n = 3

rand(3) < 1 - rand liefert also x für das gilt 0 < x < 3. Das x < 1 liegt bei 33% Wahrscheinlichkeit, bei 3 Sätzen wieder fair.

n = 4

analog zu obigen...

Puh, wahnsinnige Menge Text für nur zwei Zeilen Code - irgendwie habe ich das Gefühl das Leute die sowas programmieren irgendwie was an der Klatsche haben :P, dennoch viel Spaß beim nachvollziehen!

Geschrieben

Wow, ich bin beeindruckt. Nicht schlecht muss ich sagen :)

Hab mich mit Perl bisher noch nicht sonderlich beschaeftigt, daher hab ich mich auch dafuer interessiert.

Danke fuer die Muehe :)

Michael

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...