Využij akce až 80 % zdarma při nákupu e-learningu. Více informací.
Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu
discount week 80
Avatar
Mirek Matějka:9.4.2020 11:31

Mám podivný problém s trapně jednoduchou úlohou v OOP. Úloha je úplně zakletá. Už zkouším i s pomocí znalejšího přítele několikátou úpravu skriptu, která mi všude jinde bez problému běhá s jakýmkoliv číslem, jen zde to nikdy neprojde testy a po otestování se to tváří, jako že žádné hodnoty nebyly zadány. Případně při odevzdání úlohy jsou výsledky posunuty o jeden a tudíž nesedí. Kde je problém? Co mi uniká? Poradí mi někdo? Zde je skript:

<?php

class Kalkulacka
{

    public $cislo_1;
    public $cislo_2;

    public function __construct($cislo_1, $cislo_2)
    {

        $this->cislo_1 = $cislo_1;
        $this->cislo_2 = $cislo_2;
    }

    public function soucet($cislo_1, $cislo_2)
    {
        $soucet = $cislo_1 + $cislo_2;
        return $soucet;
    }

    public function rozdil($cislo_1, $cislo_2)
    {
        $rozdil = $cislo_1 - $cislo_2;
        return $rozdil;
    }

    public function soucin($cislo_1, $cislo_2)
    {
        $soucin = $cislo_1 * $cislo_2;
        return $soucin;
    }

    public function podil($cislo_1, $cislo_2)
    {
        if ($cislo_2 == 0)
        {
            echo('Nulou nelze dělit!');
        }
        else
        {
            $podil = $cislo_1 / $cislo_2;
            return $podil;
        }
    }

}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Objektová kalkulačka</title>
    </head>
    <div><body>
        <h1>Objektová kalkulačka</h1>
        <form method='POST'>
            1. číslo<br>
            <input type='float' name='cislo_1' /><br>
            2. číslo<br>
            <input type='float' name='cislo_2' /><br>
            <input type='submit' name='Odeslat' /><br>
        </form>
        <?php
        mb_internal_encoding('UTF-8');
        if (isset($_POST['cislo_1']) && $_POST['cislo_1'] &&
                (isset($_POST['cislo_2']) && $_POST['cislo_2']))
                {
            $cislo_1 = $_POST['cislo_1'];
            $cislo_2 = $_POST['cislo_2'];
            require_once('tridy/Kalkulacka.php');
            $kalkulacka = new Kalkulacka($cislo_1,$cislo_2);
            echo('<h2>Vysledky</h2><br>');
            echo ('Součet je: ' . $kalkulacka->soucet($cislo_1, $cislo_2) . '<br>');
            echo ('Rozdíl je: ' . $kalkulacka->rozdil($cislo_1, $cislo_2) . '<br>');
            echo ('Součin je: ' . $kalkulacka->soucin($cislo_1, $cislo_2) . '<br>');
            echo ('Podíl je: ' . $kalkulacka->podil($cislo_1, $cislo_2) . '<br>');
        }
        ?>
    </body>
</html></div>

Zkusil jsem: Už jsem zkusil i variantu s v if ($_SERVER['RE­QUEST_METHOD'] == 'POST') , nicméně tu testovací skript neakceptoval. Zkoušel jsem variantu s konstruktorem i bez něj, s $_POST v rozličných pozicích apod.

Editováno 9.4.2020 11:31
 
Odpovědět
9.4.2020 11:31
Avatar
albertpatera
Redaktor
Avatar
Odpovídá na Mirek Matějka
albertpatera:11.4.2020 23:27

ahoj,

  • u formuláře se musí definovat atribut action a jako parametr index.php (určuje, kde a s jakým skriptem se má pracovat)
  • elementy se definují až za tagy body (ty tam máš jeden div, kterým obaluješ body, což je špatně).
  • jestli se ti nezobrazují chybové hlášky, tak si zapni error_reporting.
  • třídy bych definoval před odesláním formuláře (a ne až po odeslání (tzn. při kliku na klacitko "Odeslat "))
 
Nahoru Odpovědět
11.4.2020 23:27
Avatar
Odpovídá na albertpatera
Mirek Matějka:12.4.2020 0:05

Ahoj. děkuji za podněty, jsem vděčný, že se někdo ozval. Pokusil jsem se udělat všechny doporučené kroky, ale situace se nezměnila.Nejsem si jist, zda vím, kde se zapíná Error_reporting. Na stránce ITnetwork mi hlášení chyb funguje. Ale ta hláška je nicneříkající, protože mi tvrdí, že nebyly zadány vstupy, ("zadané vstupy: "), což není pravda. Z nějakého důvodu se vstupy z formuláře nepřenesou do skriptu. Pro jistotu znovu přikládám upravený skript z indexu.php (učili mne, že když nezadám action, tak se posílá do téhož skriptu, což je právě index.php:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Objektová kalkulačka</title>
    </head>
    <body>
        <h1>Objektová kalkulačka</h1>
        <?php
        mb_internal_encoding('UTF-8');
        require_once('tridy/Kalkulacka.php');
        if (isset($_POST['cislo_1']) && $_POST['cislo_1'] &&
                (isset($_POST['cislo_2']) && $_POST['cislo_2']))
        {
            $cislo_1 = $_POST['cislo_1'];
            $cislo_2 = $_POST['cislo_2'];
            $kalkulacka = new Kalkulacka();
            echo('<h2>Vysledky</h2><br>');
            echo ('Součet je: ' . $kalkulacka->soucet($cislo_1, $cislo_2) . '<br>');
            echo ('Rozdíl je: ' . $kalkulacka->rozdil($cislo_1, $cislo_2) . '<br>');
            echo ('Součin je: ' . $kalkulacka->soucin($cislo_1, $cislo_2) . '<br>');
            echo ('Podíl je: ' . $kalkulacka->podil($cislo_1, $cislo_2) . '<br>');
        }
        ?>
        <form method='POST' action='index.php'>
            1. číslo<br>
            <input type='float' name='cislo_1' /><br>
            2. číslo<br>
            <input type='float' name='cislo_2' /><br>
            <input type='submit' name='Odeslat' /><br>
        </form>
    </body>
</html>
 
Nahoru Odpovědět
12.4.2020 0:05
Avatar
albertpatera
Redaktor
Avatar
Odpovídá na Mirek Matějka
albertpatera:12.4.2020 1:18

input type="float" taky neexistuje. (to je poze datový typ )

http://37.205.10.181:88/tests (zde je funkční řešení)
podmínka by se dala zjednodušit, protože ty se dvakrát ověřuješ to samé.
Takže stačí pouze:

if(isset($_POST['cislo1']) && isset($_POST['cislo2']))
{
      $cislo_1 = $_POST['cislo1'];
            $cislo_2 = $_POST['cislo2'];
            ///require_once('tridy/Kalkulacka.php');
            $kalkulacka = new Kalkulacka($_POST['cislo1'],$_POST['cislo2']);
            echo('<h2>Vysledky</h2><br>');
            echo ('Součet je: ' . $kalkulacka->soucet($cislo_1, $cislo_2) . '<br>');
            echo ('Rozdíl je: ' . $kalkulacka->rozdil($cislo_1, $cislo_2) . '<br>');
            echo ('Součin je: ' . $kalkulacka->soucin($cislo_1, $cislo_2) . '<br>');
            echo ('Podíl je: ' . $kalkulacka->podil($cislo_1, $cislo_2) . '<br>');
                var_dump($_POST);

....

}

Osobně bych ty echa nepsal jako funkci, i když tohle je v tutoriálu zde, ale tenhle zápis je zdlouhavý. typ můžeš napsat jenom.

echo "test";

pak je ještě jedna donbrá praktika. Když nevíš, zda se ti správně vstupojí hodnoty, tak si obsah POSTU můžeš ověřit:

print_r($_POST)

echo v tomto přípaě ne, protože z ti z toho vyleze pole

 
Nahoru Odpovědět
12.4.2020 1:18
Avatar
Odpovídá na albertpatera
Mirek Matějka:12.4.2020 11:15

Ano, vložení odkazu na formulář přímo do new kalkulacka zabralo a hodnoty se skutečně vkládají. Místo float jsem tedy dal text, protože number tam být nemůže kvůli desetinnému číslu v zadání. Jenže ani tak to testy neprojde! Když na stránce spustím kód, je to v pořádku a běhá to dle očekávání, jenže když to odevzdám k testování, vyskočí níže uvedené. Nechápu, proč testy očekávají tři proměnné?? a proč je vyžaduji při vstupu?? A jak to, že testy nevidí input, když jej níže samy vypisují?

Celkové hodnocení: Selhalo (0 %)
Počet testů: 3, Prošlo: 0, Selhalo: 3
Doba běhu: 155 ms

Následující testy selhaly:

Nahlášení chyby - try to enter 1st input:
Řádek: 4
Očekáváno: Součet: 39.1
Nalezeno:   Součet je: 39.1
Řádek: 5
Očekáváno: Rozdíl: -8.3
Nalezeno:   Rozdíl je: -8.3
Řádek: 6
Očekáváno: Součin: 364.98
Nalezeno:   Součin je: 364.98
Řádek: 7
Očekáváno: Podíl: 0.64978902953587
Nalezeno:   Podíl je: 0.64978902953587
- try to enter 2nd input
- try to enter 3rd input
Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.
 
Nahoru Odpovědět
12.4.2020 11:15
Avatar

Člen
Avatar
:12.4.2020 12:43

Neviem presne čo tu ide, ale nie je vhodnejšie mať takéto metódy statické? Keď tie dve členské premenné si beztak ani raz nepoužil? Čiže napríklad takto?

<?php
  class Kalkulacka {
    public static function soucet($cislo_1, $cislo_2) {
      return $cislo_1 + $cislo_2;
    }

    public static function rozdil($cislo_1, $cislo_2) {
      return $cislo_1 - $cislo_2;
    }

    public static function soucin($cislo_1, $cislo_2) {
      return $cislo_1 * $cislo_2;
    }

    public static function podil($cislo_1, $cislo_2) {
      if ($cislo_2 === 0) return 'Nulou nelze dělit!';
      return $cislo_1 / $cislo_2;
    }
  }

  $cislo_1 = $_POST['cislo_1'] ?? 0;
  $cislo_2 = $_POST['cislo_2'] ?? 0;
?>

<!DOCTYPE html>
<html lang="cs">
  <meta charset="utf-8">
  <title>Objektová kalkulačka</title>

  <h1>Objektová kalkulačka</h1>

  <form action="" method="POST">
    1. číslo<br>
    <input name="cislo_1" value=0><br>
    2. číslo<br>
    <input name="cislo_2" value=0><br>
    <input type="submit" value="Odeslat">
  </form>

  <h2>Vysledky</h2>

  <p>
    Součet je: <?php echo Kalkulacka::soucet($cislo_1, $cislo_2) ?><br>
    Rozdíl je: <?php echo Kalkulacka::rozdil($cislo_1, $cislo_2) ?><br>
    Součin je: <?php echo Kalkulacka::soucin($cislo_1, $cislo_2) ?><br>
    Podíl je: <?php echo Kalkulacka::podil($cislo_1, $cislo_2) ?>
  </p>
</html>
 
Nahoru Odpovědět
12.4.2020 12:43
Avatar
Odpovídá na
Mirek Matějka:12.4.2020 15:50

Děkuji, Vladislave za podnět, nicméně zdá se, že toto řešení nefunguje, protože zápis s dvěma otazníky u čísel 1 a 2 mi web neakceptuje a když vše udělám, jak navrhuješ nedojde k dosazení proměnných a test končí chybou. Nerozumím také, proč je do formuláře vkládána výchozí hodnota 0. Jde tu o OOP, s nadefinovaným objektem "tridy/Kalkulac­ka.php", který definuje základní početní operace, do kterých předávám data z formuláře v "index.php". Obávám se, že statické nastavení proměnných neřeší meritum úlohy.

 
Nahoru Odpovědět
12.4.2020 15:50
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 16:01
  1. Tie dva otázniky, to je funkčné od PHP 7. Takže zjavne používaš zastaralú verziu PHP.
  2. Že používam východzie hodnoty vo formulári, to nemá na nič vplyv.
  3. Či máš triedu definovanú v externom súbore, alebo nie, tí nemá na nič vplyv.
  4. Statické metódy sú stále OOP a stále je to riešenie úlohy. Navyše tie dynamické aj tak používaš ako statické.
Editováno 12.4.2020 16:04
 
Nahoru Odpovědět
12.4.2020 16:01
Avatar

Člen
Avatar
Odpovídá na
:12.4.2020 16:05

Napíš mi aké testy viac vec riešiš. Nech viem o čom je reč.

 
Nahoru Odpovědět
12.4.2020 16:05
Avatar
Odpovídá na
Mirek Matějka:12.4.2020 16:09

Děkuji za vysvětlení, nicméně mně to nefunguje v testu úloh k 1-3 lekci OOP na stránkách ITNetwork. Překvapilo by mne, pokud tyto stránky jsou zastaralé. Na localhost v Netbeans IDE 11.2 mi úloha od počátku funguje bez potíží a bez chybových hlášení. To jen zde se nejsem schopen probojovat přes testy, ačkoli jsem už zkusil 4 různé funkční konfigurace.

 
Nahoru Odpovědět
12.4.2020 16:09
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 16:17

Stále neviem o čom hovoríš. Môžeš sem vložiť konkrétne linky?

 
Nahoru Odpovědět
12.4.2020 16:17
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 16:59

Potrebujem kód tých testov. Moje riešenie je totiž v poriadku, aj má väčšiu logiku, len ešte vieš ešte málo na to, aby si to chápal.

A áno, keďže ti nefunguje null coalesce operátor, tak je to tým, že itnetwork zjavne používa dnes už neodporúčanú, nepodporovanú päťkovú verziu PHP, miesto sedmičkovej. A to je dosť trapas, a žiaľ nie ojedinelý.

 
Nahoru Odpovědět
12.4.2020 16:59
Avatar
Odpovídá na
Mirek Matějka:12.4.2020 19:55

Nahradil jsem Null coalescing operator ternárním výrazem a to již prošlo, jenže, když zkusím "Spustit kód" dá mi to po zadání proměnných tuto chybovou hlášku:

Parse error: syntax error, unexpected 'echo' (T_ECHO), expecting ',' or ';' in /home/jailphp/test_project5e9354d9ed39f/index.php on line 9

Line 9 je ovšem poslední řádek formuláře, když jsem ale zkoušel řádky posouvat, byla to pořád line 9, takže je to nějaká nesmyslná hláška. To, co tu řeším, je první úloha z https://www.itnetwork.cz/…ibuty-metody. Mé kódy najdeš výše ve vláknu. Zkouším ale teď to, cos mi poslal, takže není třeba je hledat. V Netbeans na lokálním serveru mi to funguje, nicméně zde na itnetwork to hlásí tu hlášku.

 
Nahoru Odpovědět
12.4.2020 19:55
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 21:15

Ak ti tvoj či môj kód funguje lokálne, tak je to všetko, čo potrebuješ. To, že to nefunguje s nejakým divným a zastaralým systémom na itnetwork, to predsa nie je podstatné, na tom nezáleží.

 
Nahoru Odpovědět
12.4.2020 21:15
Avatar
Odpovídá na
Mirek Matějka:12.4.2020 22:11

Ano, pro mé uspokojení by to jistě stačilo. Já ale chci odevzdat kód, který obstojí i na tom testovacím skriptu itnetwork, abych se naučil splnit úlohu způsobem, který obstojí i na zastaralých serverech. Už mi asi chybí jen nějaká maličkost. Na níže uvedené úpravě tebou zaslaného skriptu, rozdělené index a třídu, mi to i na lokálním serveru hází hlášení, že nebyla nalezena třída Kalkulacka, tj. ten řádek 19-22 (Součet, rozdíl, součin, podíl). Je tedy nějaký zádrhel na propojení obou skriptů. Zde je poslední verze kódu:

<!DOCTYPE html>
<html lang="cs">
  <meta charset="utf-8">
  <title>Objektová kalkulačka</title>

  <h1>Objektová kalkulačka</h1>

  <form action="tridy/Kalkulacka.php" method="POST">
    1. číslo<br>
    <input name="cislo_1" type="text"><br>
    2. číslo<br>
    <input name="cislo_2" type="text"><br>
    <input type="submit" value="Odeslat">
  </form>

  <h2>Vysledky</h2>

  <p>
      Součet je: <?php echo Kalkulacka::soucet($cislo_1, $cislo_2); ?><br>
      Rozdíl je: <?php echo Kalkulacka::rozdil($cislo_1, $cislo_2); ?><br>
      Součin je: <?php echo Kalkulacka::soucin($cislo_1, $cislo_2); ?><br>
      Podíl je: <?php echo Kalkulacka::podil($cislo_1, $cislo_2); ?>
  </p>
</html>

A zde je kód objektu:

<?php

class Kalkulacka
{

    public static function soucet($cislo_1, $cislo_2)
    {
        return $cislo_1 + $cislo_2;
    }

    public static function rozdil($cislo_1, $cislo_2)
    {
        return $cislo_1 - $cislo_2;
    }

    public static function soucin($cislo_1, $cislo_2)
    {
        return $cislo_1 * $cislo_2;
    }

    public static function podil($cislo_1, $cislo_2)
    {
        if ($cislo_2 === 0)
        {
            return 'Nulou nelze dělit!';
        }
            else
            {
                return $cislo_1 / $cislo_2;
            }

    }

}

$cislo_1 = isset($_POST['cislo_1']) ? $_POST['cislo_1'] : 0;
$cislo_2 = isset($_POST['cislo_2']) ? $_POST['cislo_2'] : 0;

Velmi si vážím tvé ochoty se tím zabývat. Snad tě napadne, kde jsem udělal chybu při převodu kódu. Díky

 
Nahoru Odpovědět
12.4.2020 22:11
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 22:26

Nenájde ti tú triedu, lebo ja som môj kód myslel ako jeden súbor. Ty ti však máš podelené na dva. A tej môj si nesprávne upravil. Oprav ho takto:

<?php
  require_once("tridy/Kalkulacka.php");

  $cislo_1 = isset($_POST['cislo_1']) ? $_POST['cislo_1'] : 0;
  $cislo_2 = isset($_POST['cislo_2']) ? $_POST['cislo_2'] : 0;
?>

<!DOCTYPE html>
<html lang="cs">
  <meta charset="utf-8">
  <title>Objektová kalkulačka</title>

  <h1>Objektová kalkulačka</h1>

  <form action="" method="POST">
    1. číslo<br>
    <input name="cislo_1" type="text"><br>
    2. číslo<br>
    <input name="cislo_2" type="text"><br>
    <input type="submit" value="Odeslat">
  </form>

  <h2>Vysledky</h2>

  <p>
      Součet je: <?php echo Kalkulacka::soucet($cislo_1, $cislo_2); ?><br>
      Rozdíl je: <?php echo Kalkulacka::rozdil($cislo_1, $cislo_2); ?><br>
      Součin je: <?php echo Kalkulacka::soucin($cislo_1, $cislo_2); ?><br>
      Podíl je: <?php echo Kalkulacka::podil($cislo_1, $cislo_2); ?>
  </p>
</html>
Editováno 12.4.2020 22:29
 
Nahoru Odpovědět
12.4.2020 22:26
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:12.4.2020 22:35

A z definície triedy tie dva riadky s premennými číslo 1 a 2 vymaž. V súbore s definíciou triedy nemá byť okrem triedy ani riadok navyše:

<?php
class Kalkulacka
{

    public static function soucet($cislo_1, $cislo_2)
    {
        return $cislo_1 + $cislo_2;
    }

    public static function rozdil($cislo_1, $cislo_2)
    {
        return $cislo_1 - $cislo_2;
    }

    public static function soucin($cislo_1, $cislo_2)
    {
        return $cislo_1 * $cislo_2;
    }

    public static function podil($cislo_1, $cislo_2)
    {
        if ($cislo_2 === 0)
        {
            return 'Nulou nelze dělit!';
        }
            else
            {
                return $cislo_1 / $cislo_2;
            }

    }

}
?>
Editováno 12.4.2020 22:36
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět
12.4.2020 22:35
Avatar
Odpovídá na
Mirek Matějka:13.4.2020 7:41

No ovšem, ta má chyba je jasná, na lokální serveru mi to běhá bez potíží, jenže na tom pitomém testu itnetwork jsem se zase dostal na začátek. Opět to píše:

Celkové hodnocení: Selhalo (0 %)
Počet testů: 3, Prošlo: 0, Selhalo: 3
Doba běhu: 183 ms

Následující testy selhaly:

Nahlášení chyby - try to enter 1st input:
Řádek: 3
Očekáváno: Výsledky
Nalezeno:   39.1-8.3364.980.64978902953587
Řádek: 4
Očekáváno: Součet: 39.1
Nalezeno:
Řádek: 5
Očekáváno: Rozdíl: -8.3
Nalezeno:
Řádek: 6
Očekáváno: Součin: 364.98
Nalezeno:
Řádek: 7
Očekáváno: Podíl: 0.64978902953587
Nalezeno:
- try to enter 2nd input
- try to enter 3rd input

Já už jsem z toho vážně trotl. Zase to nenačítá ty proměnné.

 
Nahoru Odpovědět
13.4.2020 7:41
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:13.4.2020 11:17

Rád by som pomohol, ale nemám sa ako pozrieť na tie testy, lebo nemám zaplatený ten kurz.

 
Nahoru Odpovědět
13.4.2020 11:17
Avatar
Odpovídá na
Mirek Matějka:13.4.2020 22:14

Děkuji ti, Vladislave, za dosavadní pomoc, i když jsme ten hloupý testovací skript zatím neporazili. Myslím, že i kdybys tu jednu lekci cvičení měl předplacenou, nic by to nepomohlo, kód testů je skrytý. Dál už to budu muset nějak dotáhnout sám. Snad na to časem přijdu. V každém případě díky za cenné postřehy.

 
Nahoru Odpovědět
13.4.2020 22:14
Avatar

Člen
Avatar
Odpovídá na Mirek Matějka
:13.4.2020 22:26

Ešte raz niet za čo. A na tie testy sa fakt vybodni. Sú to obyčajné unit testy, ktoré však zjavne očakávajú konkrétny formát riešenia. A že si ten očakávaný formár nedodržal, to ešte neznamená, že to máš zle.

 
Nahoru Odpovědět
13.4.2020 22:26
Avatar
Odpovídá na
Mirek Matějka:14.4.2020 9:53

Tak se mi to dnes nečekaně podařilo vyřešit. Hlavní problém byl v neuvěřitelné banalitě. Místo "Součet:" jsem měl napsáno "Součet je:" apod. Teď už to těmi testy prošlo.

 
Nahoru Odpovědět
14.4.2020 9:53
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 22 zpráv z 22.