Задача №3 - Больше или меньше предыдущего

Задачи №3 из этого списка:

Условие задачи:

Вывести на экран N случайных чисел (каждое с новой строки). Для каждого числа, начиная со второго, рядом выводить - больше ли оно предыдущего или меньше

Мое решение:

<?php
$a = rand(8, 15);
for ($i=0; $i<$a; $i++){
    if ($i==0){
        echo $random1 = rand(-25, 35) . '<br>';
    } elseif ($i>0) {
        echo $random2 = rand(-25, 35);
            if ($random2 > $random1) {
                echo ' больше ' . $random1;
            } elseif ($random2 < $random1) {
                echo ' меньше ' . $random1;
            } elseif ($random2 == $random1) {
                echo ' равно ' . $random1;
            }
            $random2 = $random1;
    }
}
melisa's picture

  1. echo $random2 = rand(-25, 35);
        if ($random2 > $random1) {
            echo ' больше ' . $random1;
        } elseif ($random2 < $random1) {
            echo ' меньше ' . $random1;
        } elseif ($random2 == $random1) {
            echo ' равно ' . $random1;
        }

    Здесь ошибка в оформлении: лишний отступ

  2. elseif ($i>0)

    Здесь оператор elseif() излишен, т.к. условие только одно. elseif следует применять когда есть разные варианты развития событий после if, а ещё лучше воспользоваться в таких случаях конструкцией switch.

  3. Запустите код. У Вас сравнение происходит всегда с первым числом, а не с предыдущим.

По п.1:
Это отступ в первом if, я правильно понял? Вроде исправил!

По п.2:
Принял, спасибо, учту на будущее!

По п.3:
Да, запустил, увидел свой косяк, сорри за невнимательность!
Исправил:

<?php
$a = rand(8, 15);
for ($i=0; $i<$a; $i++){
    if ($i==0){
        $random1 = rand(-25, 35);
        echo $random1 . '<br>';
        $noRandom = $random1;
    } else {
        $random2 = rand(-25, 35);
        switch ($random2-$noRandom){
            case ($random2-$noRandom>0):
                echo $random2 . ' больше ' . $noRandom . '<br>';
                break;
            case ($random2-$noRandom<0):
                echo $random2 . ' меньше ' . $noRandom . '<br>';
                break;
            case 0:
                echo $random2 . ' равно ' . $noRandom . '<br>';
                break;
        }
        $noRandom = $random2;
    }
}

НО почему-то у меня такое впечатление складывается, что в swith у меня получились "костыли". Почему-то не получается в case загнать только условие (>0,

melisa's picture

  1. switch сравнивает выражение в скобках после первого оператора и выражения после case. В случае равенства, выполняется тело case. Т.к. в нашем случае требуется не равенство, а разные условия каждый раз, elseif подойдёт лучше.
  2. $noRandom - непонятное название. "Неслучайная" переменная - "это бжжж неспроста")) Если по-английски, то можно $notRandom, но информативности такое название не несёт, тогда уж можно просто $b.

    Но если уж называть, постарайтесь, чтобы по названию можно было понять что хранит в себе переменная. Например, $current - общепринятое название для текущего элемента. А следующий элемент может называться $next. Так будет даже без русских комментариев понятно, что делает код, да и Вам удобнее разрабатывать.

  3. $noRandom = $random1;

    Это лишняя строка, без неё будет работать.

У Вам очень хорошее чувство юмора! Очень приятно общаться с умными людьми с классным чувством юмора!!!

Мне кажется я понял, что Вы пытались до меня донести, в т.ч. фразой из мультика про Винни Пуха (кстати я его очень люблю, недавно с огромным удовольствием посмотрел фильм Кристофер Робин)

Проверьте...

<?php
$a = rand(8, 15);
for ($i=0; $i<$a; $i++){
    switch ($i){
        case 0:
            $current = rand(-25, 35);
            echo $current . '<br>';
        case ($i!=0):
            $next = rand(-25, 35);
            if ($next > $current){
                echo $next . ' больше ' . $current . '<br>';
            } elseif ($next < $current){
                echo $next . ' меньше ' . $current . '<br>';
            } elseif ($next == $current){
                echo $next . ' равно ' . $current . '<br>';
            }
    }
    $current = $next;
}

P.S. и Вы были правы... действительно проще обзывать переменные $current и $next. В голове проще выстроить из таких названий логические цепочки что за чем последует. Спасибо!

melisa's picture

ну что Вы, спасибо :))) А мне приятно проверять, когда Вы заинтересованы в результате, то ли ещё будет)

кстати я его очень люблю, недавно с огромным удовольствием посмотрел фильм Кристофер Робин

Новый, 2018го? Советуете?

  1. switch ($i){
        case 0:
            $current = rand(-25, 35);
            echo $current . '<br>';
        case ($i!=0):
            $next = rand(-25, 35);
            if ($next > $current){
                echo $next . ' больше ' . $current . '<br>';
            } elseif ($next < $current){
                echo $next . ' меньше ' . $current . '<br>';
            } elseif ($next == $current){
                echo $next . ' равно ' . $current . '<br>';
            }
     }

    Я Вас наверное запутала упоминанием switch. В данном случае он тоже не совсем уместен. В этой задаче его вообще не нужно использовать.
    Во-первых, потому что варианта (case) всего 2. Всё-таки назначение switch в динных переборах. Не нужно усложнять то, что можно написать с помощью простого if, else, как у Вас и было раньше.
    Во-вторых, потому что во втором случае не проверка равенства $i, а снова целое условие. Это лишнее. Чем проще, тем лучше.

  2. Ну а раз уж Вы использовали switch, то где оператор break?
    Т.к. break отсутствует, в первой итерации цикла for выполняются оба case. Это приводит к тому, что выводится на экран не $a чисел, а $a+1. Можете убедиться в этом, задав $a значение 1 для отладки.

    Отладьте этот вариант для упражнения (кстати, если break поставить на место, появится другая ошибка). Запостите этот вариант сюда.

    Но в этой задаче всё-таки лучше использовать if и else. И этот вариант тоже опубликуйте.

Новый, 2018го? Советуете?

Да, советую, Винни Пух там такие простые и очевидные вещи говорит, что в жизни ты даже как-то не задумываешься, а посмотрел этот фильм и подумал... а ведь так оно и есть.

В общем рекомендую!

Я переделал код в соответствии с рекомендациями, постарался его сделать меньше

Вот он:

<?php
$a = rand(8, 15);
for ($i=0; $i<$a; $i++){
    if ($i==0){
        echo $current = rand(-25, 35) . '<br>';
    } else {
        echo $next = rand(-25, 35);
        if ($next > $current){
            echo ' больше ' . $current . '<br>';
        } elseif ($next < $current){
            echo ' меньше ' . $current . '<br>';
        } elseif ($next == $current){
            echo ' равно ' . $current . '<br>';
        }
        $current = $next;
    }
}

Но есть проблема, после второй итерации, появляется дополнительный перенос каретки... посмотрел в браузере через F12 код HTML, да, там прям нагло торчит откуда-то взявшийся br.

Я не могу понять откуда он взялся. I need help!

melisa's picture

echo $current = rand(-25, 35) . '<br>';

Посмотрите внимательно на эту строку. В ней одновременно происходит и присвоение значения, и печать. Так к чему Вы хотели приконкатенировать
?

Я обратил внимание на эту строчку, немного передал, заработало!

Вот обновленный код:

<?php
$a = rand(8, 15);
for ($i=0; $i<$a; $i++){
    if ($i==0){
        $current = rand(-25, 35);
        echo $current . '<br>';
    } else {
        echo $next = rand(-25, 35);
        if ($next > $current){
            echo ' больше ' . $current . '<br>';
        } elseif ($next < $current){
            echo ' меньше ' . $current . '<br>';
        } elseif ($next == $current){
            echo ' равно ' . $current . '<br>';
        }
        $current = $next;
    }
}

... но я не понял почему так происходит... неужели при присвоении значения переменной каретка автоматом переносится на новую строку? И что также мне не понятно... по сути это строка печатает первое значение переменной, однако дополнительные перенос был после первого определения "больше/меньше" (т.е. условно в конце второй строки) ... как так? Где магия? )))

melisa's picture

  1. но я не понял почему так происходит...

    Так происходит потому, что Вы присваиваете переменной $current не "7", а "7 br", к примеру(скобки тега опустила намеренно, иначе строку переносит))). Т.к. в php типизация не строгая, то тип $current при конкатенации числа со строкой спокойно преобразуется в строку "7 br".

    В первой строке перенос, как Вы и оживаете 1, буквально строка выглядит так:

    "7 br"

    А вторая строка выглядит так (если опустить if):

    $next . 'больше' .  $current . '<br>'

    Но т.к. $current = "7 br", буквально получится:

    "8 больше 7 br br"

    После второй строки происходит переприсвоение значения $current, и из него удаляется br:

    $current = $next;

    Справедливость восстановлена.

  2. Как отлаживать.
    Если Вы видите в совей программе ошибку, но не можете понять, в чём она, отлаживайте код построчно. Строго делайте die(); после каждой строки. Как только ошибка появилась - значит, Вы нашли строку, в которой она скрывается. Дальше, чтобы понять, что не так, выводите значения переменных, используемых в данной строке на экран.

    Здесь важна дотошность: каждую строку. И внимательность: следите, куда идёт программа, как она работает. Обычно помогает :)

    Вот есть статья про отладку, там некоторые простые вещи описаны. Если что-то изобретёте своё, напишите, будем дополнять.

Спасибо за подробный ответ!

Оказывается нет ни какой магии... я прям даже расстроился )))

Я так понимаю задача принята?

melisa's picture

да, принято

В предыдущем комментарии я пытался переменные current и next правильно отобразить... у меня не получилось... Подскажите, как Вы это делаете...

melisa's picture

Есть статья о том, как оформлять статьи на сайте fkn.ktu10.com.
А про теги конкретно смотрите в видео. Ссылка на него также есть в статье.