Autor Zpráva
Contador
Profil
Ahoj muzete mi nekdo poradit? Zacinam se ucit PHP a delam kalkulacku. Jednoduchou se strema inputa zvladnu ale zkousim tezsi a proste to nezvladam...budu rad za kazdou informaci nebo radu...dekuji.

http://www.interista.borec.cz//PHP/Calc/index.php
Marschmallow
Profil
Contador:
A s čím přesně potřebuješ poradit? Dodáš nám Tvůj PHP kód?
Contador
Profil
Marschmallow:
proste to potrebuji rozchodit... na vystupu mam jednu promenou napr. "25+5" nebo "3*3"...a nevim jak s tim dal pracovat. Zkousel jsem expolede ale to jsem dostal akorat dve cisla bez znamenka a muj php kod snad ani nestoji za rec ale dam ho sem teda :)
Ale nechci to udelat spis poradit a ukazat smer
<?php
$result = $_POST["result"];

?>
janbarasek
Profil
Contador:
Hodně hloupé řešení je například Eval, sice funguje, ale je nebezpečné. Nicméně pro přibližnou představu je asi dostačující (jako učební materiál).

Moderátor Joker: Varování: Jak je uvedeno, příklad níže je hloupé a nebezpečné řešení. Na ostrém serveru přístupném uživatelům by se příkaz eval nikdy neměl používat, zejména ne začínajícími programátory.
Příklad:
<?php
$q = '5+3*2';
eval('$q = ('.$q.');');
echo $q;
?>

Pár poznámek:
- Měl by jsi si hlídat vstupní řetězec, ať ti tam někdo nedostane kus kódu, co ti naboří server.
- Běžné kalkulačky používají něco jako binární stromy, je to ale dost věda. Já je studuji už přes rok a pořád v tom mám trochu zmatky a hodí se k tomu trochu znalost vysokoškolské matematiky a trochu proniknout do teorie tvorby algoritmů.
Jan Tvrdík
Profil
janbarasek:
přibližnou představu je asi dostačující (jako učební materiál)
To není rozhodně dostatečné ani jako učební materiál. Je lepší, než když mu to nebude fungovat vůbec, než když mu to bude fungovat extrémně špatně a nebezpečně. Když už na to chcete vytáhnout eval, tak je minimálně nezbytné výrazně omezit povolené znaky.

Pro představu, jak to řešit pořádně, se podívejte třeba na github.com/symfony/expression-language.
janbarasek
Profil
Jan Tvrdík:
Podle původního příspěvku hádám, že tazatel je v programování ještě začátečník, proto by se mu měla přizpůsobit rada. Mohl jsem mu poslat také odkaz na nějaké již hotové řešení, ale povedlo by to akorát k tomu, že jej nebude umět přečíst a pochopit a bude se ptát zbytečně dál. Nejdříve bychom mu měli vůbec ukázat nějaký úvod do problematiky, jak se úkoly tohoto typu řeší (a že to není vůbec sranda).
Jan Tvrdík
Profil
janbarasek:
Je lepší, když to hned nepochopí než mu dát do ruky odjištěnou nukleární hlavici a říct mu, až si hraje.
janbarasek
Profil
Jan Tvrdík:
Ideální přístup k tomu, aby s programováním při prvním větším problému hned praštil, fakt. Zkus se někdy vcítit do jeho situace a poradit mu "jeho mluvou", místo použití arogantního odmítnutí.
Marschmallow
Profil
Contador:
Tady přikládám hotové řešení kalkulačky za pomoci inputů:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>PHP kalkulačka</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<form>
Zadej hodnoty:<br>
1 číslo:<input type="text" name="a"><br>
2 číslo:<input type="text" name="b"><br>
<input type="submit" value="Sečti!">
</form>
<?
$a=$_GET["a"] ;
$b=$_GET["b"] ;
if($a&&$b){
$soucet=$a+$b;
echo "Výsledek: $soucet ";
echo "Celý zápis: $a + $b = $soucet ";
}
?>
</body>
</html>
Jan Tvrdík
Profil
janbarasek:
Možná sis nevšiml, ale já jsem se zatím s Contador vůbec nebavil. On nic špatně neudělal, to ty radíš blbosti.

Contador:
Napsat rozumně kalkulačku tak, aby vyhodnocovala výrazy vůbec není jednoduché. Anglicky je to popsané třeba na www.cs.umb.edu/~marc/cs470/evarix.htm. Základem je pochopit, že výraz (mnohočlen, anglicky expression) se skládá z jednotlivých členů (anglicky term) a jednotlivé členy se skládají z činitelů (anglicky factor). Je tam k tomu i obrázek.

Na začátku rozložíš výraz na tzv. tokeny, tj. nejmenší logické číslo. V případě jednoduchých výrazů jsou to čísla a operátory. V PHP lze tento rozklad nejsnáze provést pomocí regulárních výrazů s využitím funkce preg_split.

$tokens = preg_split('#([0-9]+)|([*/+-])#', $expression, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

Hotové tokeny pak proběhneš postupně od začátku do konce a budeš si přitom průběžně počítat výsledek. Je tam k tomu celá powerpointová prezentace.
Joker
Profil
janbarasek:
Podle původního příspěvku hádám, že tazatel je v programování ještě začátečník, proto by se mu měla přizpůsobit rada.
Ano. A rada začátečníkovi by nikdy neměla obsahovat eval.
Navíc, co se z toho naučí? Leda existenci příkazu, který by nikdy v životě neměl použít. Jinak mu to k ničemu nebude, nedá se to nijak rozvíjet. Funguje to pro pár základních operátorů, jakmile zkusí přidat něco dalšího, zjistí, že to je slepá ulička.

Do [#4] přidám varování.
Jan Tvrdík
Profil
Marschmallow:
Uvedený skript závisí na konfigurační direktivě short_open_tag, obsahuje chybu E_NOTICE při prvním načtení, nebude fungovat, když jako jedno z čísel uvedeš nulu, obsahuje závažnou XSS zranitelnost, selže když jeden z parametrů bude pole. Mám pokračovat?
Fisir
Profil
Proboha, tohle jsou vážně dost chatrná řešení. Doporučuji knihovnu php-math-parser.
Marschmallow
Profil
Jan Tvrdík:
Ne, pokračovat nemusíš. Je to jedna z nejlehčích variant. Jen, aby Contador pochopil, jak to funguje.
Jan Tvrdík
Profil
Marschmallow:
Jen, aby Contador pochopil, jak to funguje
Vzhledem k tomu, že na začátku píše „Jednoduchou se strema inputa zvladnu“, tak se domnívám, že ukázku toho, jak to udělat špatně zrovna potřeboval.
Alphard
Profil
Všichni tady uvádíte převážně hned ukázky kódů, ze kterých hádám začátečník moc modrý nebude. U problémů tohoto typu podle mě nejde přeskočit teorii a je třeba začít jednoduššími věcmi. Odkázat (byť kvalitní) kód rozdělený do hromady souborů mu nepomůže (ale chápu, že to byla reakce spíš na janbarasek :-)).
V rychlosti jsem našel slidy z přednášky Výpočet hodnoty aritmetického výrazu. Jestli pochopí princip, může v rozumném čase napsat tu svoji kalkulačku.
Contador
Profil
hosi dekuji vsem za snahu a nehadejte se

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: