Страницы

Поиск по вопросам

Показаны сообщения с ярлыком while. Показать все сообщения
Показаны сообщения с ярлыком while. Показать все сообщения

вторник, 31 марта 2020 г.

Зацикливание while при вводе строки через prompt

#javascript #while


Есть две переменные, в которые записываются данные:

let finance = +prompt('Ваш бюджет?');
while (finance === "" || isNaN(finance) || finance === null) {
    let finance = prompt('Ваш бюджет?');
}
let name = prompt('Название вашего магазина?');
while (name == "" || name == null) {
    let name = prompt('Название вашего магазина?');
}


При вводе в первую переменную все записывается без проблем. Во вторую тоже, но если
при вводе во вторую переменную сначала нажать "Отмена" или "Ок" и потом ввести без
ошибок, то она зацикливается и скрипт не идет дальше, хотя первая переменная работает
нормально. В чем проблема?
    


Ответы

Ответ 1



Проблема в лишнем let. Так как с использованием этого ключевого слова область видимости ограничена блоком, а не функцией - значение введенное внутри цикла никак не совпадает с тем, что проверяется в условии. Почему не зацикливается в первом случае? Так как используется унарный оператор + - результат prompt сразу приводится к числу. Приведение к числу работает согласно таблице в которой отмечено, что в случае null результатом будет +0, пустая строка, либо строка только из пробелов будет приведена к 0. Поэтому при нажатии отмены или вводе пустой строки ни одно из условий не выполняется. Стоит отметить, что при вводе строки, которую невозможно привести к числу в первом случае так же будет зацикливание, так как результат приведения в этом случае будет NaN.

вторник, 17 марта 2020 г.

Скрипт вывода товаров, очень долго грузится

#mysqli #while #php #foreach


Функции выборки товаров из базы:
function result_to_array($result) {
    $res_array = array();
    $count = 0;
    while( $row = $result->fetch_assoc() ) {
        $res_array[$count] = $row;
        $count++;
    }
    return $res_array;
}

function get_product() {
    connect_db();
    global $mysqli;
    $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC");
    $result = result_to_array($result);
    return $result;
}

На самой странице все товары выводятся циклом foreach:
$products = get_product();



html код



Проблема в том, что страница с товарами открывается ну очень долго, раньше просто
на этой же самой странице делал запрос и выводил все через while, по скорости было
ощутимо быстрее. 
Подскажите, что я делаю не так и почему так медленно работает скрипт?    


Ответы

Ответ 1



А много ли товаров? И можно оптимизировать конструкцию, убрав $count: while( $row = $result->fetch_assoc() ) { $res_array[] = $row; } Перед выполнением кода и после выполнения добавьте microtime(): function result_to_array($result) { $ra_start = microtime(); $res_array = array(); $count = 0; while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; } $ra_end = microtime(); echo $ra_end - $ra_start; return $res_array; } function get_product() { $gp_start = microtime(); connect_db(); global $mysqli; $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); $result = result_to_array($result); $gp_end = microtime(); echo $gp_end - $gp_start; return $result; } На самой странице все товары выводятся циклом foreach: $products = get_product(); html код: По результатам сможете увидеть, какой кусок у Вас долго выполняется.

Ответ 2



Идите поэтапно: 1) Смотрим, а не тупит ли mysql: $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); exit(); $result = result_to_array($result); 2) Как быстр while: while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; } exit(); return $res_array; 3) Как быстр вызов $products = get_product(); $products = get_product(); exit(); 4) Убираем и смотрим, как работает без него. Если долго выполняеться этап 1, оптимизируем mysql запрос (табличка возможно очень большая). Если долго выполняеться этап 2, используем ответ выше. Если долго выполняеться этап 3 (без двух предыдущих ) - что-то очень странное. Если долго выполняеться этап 4, то используем for вместо foreach (https://stackoverflow.com/questions/3430194/performance-of-for-vs-foreach-in-php). Если ничего не помогает и вызовы повторяються, то пихаем все в мемкэш (вплоть до html).

суббота, 8 февраля 2020 г.

Остановка выполнения цикла while

#comet #while #php #sleep #long_poll


Всем привет! Интересует вопрос - как можно правильно остановить выполнение while
цикла со sleep внутри. 
Дело в том, что я реализовываю "long poll" для быстрого обновления информации на
сайте (оповещения, другая информация).
СУТЬ РАБОТЫ СКРИПТА 
1. Мы отправляем GET-запрос на PHP-страницу в которой расположен скрипт.
2. Скрипт запускает цикл while.
3. В данном цикле существует 2 условия и sleep(1) в конце, который приостанавливает
выполнение цикла.
- Если если цикл работает больше 30 секунд - останавливаем выполнение цикла, соответственно
и скрипта. 
- Если на сайте появилась новая информация, скажем "оповещение" - выводим результат
пользователю и останавливаем цикл.
ПРОБЛЕМА 
Если пользователь закроет окно браузера, или же перезагрузит страницу - выполнится
новый запрос на данный скрипт, который запустит цикл повторно. Но при этом, предыдущие
выполнение  цикла while не остановятся, пока не сработает хотя бы одно условие внутри
него. Если же пользователь отошлет много запросов на страницу - память сервера начинает
сильно грузится и в результате все висит, пока все while не остановят свое выполнение.
ВОПРОС 
Как остановить выполнение цикла и скрипта в целом при повторном выполнении или же
перезагрузке страницы клиентом? 
Пока на данный момент я сделал следующее.
При выполнении скрипта мы генерируем рандомное число, которое записываем в переменную
и так же с сессию. Далее внутри while делаю условие, в котором данная переменная должна
равняться значению сессии. Если false - останавливаем цикл. 
Если мы запускаем скрипт по новой - значение сессии меняется и соответственно все
предыдущие выполнения while останавливаются. 
Можно ли использовать такой вариант? И на сколько он безопасен?
UPDATE.PHP
 // инициализируем сессию пользователя
 $session = Session::instance();

        $rand = rand();
        $session->set('user_update_key', $rand);
        $key = $rand;

        $limit = 20;
        $seconds = 0;

        set_time_limit($limit + 1);

        while (TRUE) {
            if (Session::instance()->get('user_update_key') == $key) {

                if (есть ли обновления. если есть - выводим) {
                    echo 'информация обновлений';
                    flush();
                    exit;
                }
                if ($seconds == $limit) { // завершаем выполнение цикла по истечению
времени.
                    echo 'Close';
                    flush();
                    exit;
                }
                $seconds++;
            } else {
                unset($session, $rand, $key, $notice, $mysession, $last_notice, $limit,
$notise_return, $seconds);
                flush();
                exit;
            }
            session_write_close();
            sleep(1);
            session_start();

}    


Ответы

Ответ 1



Похоже, вас интересует двусторонняя коммуникация пользователя с долгоиграющим процессом на PHP, и процессов PHP между собой во время их исполнения. PHP под это не заточен, как уже писали, но есть расширения, которые могут оказаться полезными. Без дополнительных примочек подходит механизм сессий, или же похожий собственный, задействующий, например, БД как "общую память". В первом приближении, я бы сделал точно то же, что и вы. Почему вы хотите именно long polling, а не новый разовый запрос раз в секунду? VK виджеты для комментариев, скажем, именно так работают. Если веб сервер настроен не закрывать мгновенно каждое соединение, то цепочка таких запросов не станет тормозить. (См. настройку KeepAlive для Apache) Наконец, можно посомтреть в сторону других технологий и протоколов, напр. Flash и RTMP: маленькая флешка в веб странице, которая по RTMP связывается с сервером RED5, и получает/отправляет инфу через JS коммуникацию с флешкой - настоящий риалтайм!

Ответ 2



Поищите другие варианты - как раз недавно на Хабре была статья о природе и ограничениях PHP. В комментариях предлагаются и другие варианты. Например, в этом и в этом.

Ответ 3



Ну как вариант, записать время в куки , и недавать юзеру выполнять следующий запрос пока тот не выполнится......

вторник, 31 декабря 2019 г.

В цикле while на c# не запускается Console.WriteLine

#c_sharp #while


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CyclesDoWhile
{
    class Program
    {
        static void Main(string[] args)
        {
            //Количество конфет в пачке
            int candies = 200;

            //Съедено конфет 
            int candiesEaten = 0;

            while(candiesEaten != 0)
            {
                candies--;
                candiesEaten++;
                Console.WriteLine("Конфет съедено. Осталось: " + candies + " Конфет
съедено" + candiesEaten);
            }




            Console.ReadKey();
        }
    }
}


Этот код работал. Запускался, как положено. Сегодня решил повторить этот урок, все
стер. Написал заново. Запускает пустое консольное окно. В чем ошибка?
    


Ответы

Ответ 1



У вас ошибка в условии цикла //Количество конфет в пачке int candies = 200; //Съедено конфет int candiesEaten = 0; while(candiesEaten != 0) ^^^^^^^^^^^^ Данный цикл ни разу не выполнится. Я думаю вы имеете в виду //Количество конфет в пачке int candies = 200; //Съедено конфет int candiesEaten = 0; while(candies != 0) ^^^^^^^

воскресенье, 29 декабря 2019 г.

В чем разница между loop и while true?

#while #rust


В чем разница между loop и while true в rust?


  В документации написано что:

loop {}

  
  Интерпретируется по другому компилятором чем:

 while true {}

  
  Хотел бы понять в чем эта разница и на сколько плохо использовать не loop, а while true


версия вопроса на Английском от @aij
    


Ответы

Ответ 1



На такой вопрос был дан ответ в Reddit. Разница заключается в том, что в случае while true все переменные должны быть инициализированы до цикла, а в случае loop это не обязательно: Пример с loop let x; loop { x = 1; break; } println!("{}", x) этот код отлично работает, однако следующий let x; while true { x = 1; break; } println!("{}", x); покажет ошибку компиляции "use of possibly uninitialised variable" с указанием на x в println. Во втором случае компилятор не определяет, что тело цикла всегда выполнится хотя бы один раз. перевод ответа @telotortium

Ответ 2



Сейчас есть еще одно отличие - из loop можно вернуть значение: let x; let y = loop { x = 1; break 42;}; println!("x={} y={}", x, y); Returning from loops

Выход из цикла while

#cpp #while


У меня есть конструкция 

while(true){
   for(;;) {}
}


Как мне выйти из бесконечного цикла while внутри цикла for?
    


Ответы

Ответ 1



К сожалению, в отличие от Джавы, C и C++ не поддерживают механизм вроде break label, поэтому самый чистый вариант — использовать goto: int main() { while (true) { for (;;) { goto breakAll; } } breakAll: puts("I'm out!"); } Также можно использовать флаг: int main() { bool running = true; // bool определен в stdbool.h while (running) { for (;;) { running = false; break; } } puts("I'm out!"); } Большой разницы между этими вариантами нет. Помимо этого случая, goto также используется в хорошем стиле C для обработки ошибок: bars_t foo() { bar_t *bar1 = malloc(sizeof(*bar1)); if (!bar1) { goto cleanupNothing; } bar_t *bar2 = malloc(sizeof(*bar2)); if (!bar2) { goto cleanupBar1; } // ... return (bars_t) { .one = bar1, .two = bar2 }; // в обратном порядке определения cleanupBar2: free(bar2); cleanupBar1: free(bar1); cleanupNothing: return (bars_t){0}; } В C++ подобное не нужно, т.к. есть RAII, но из циклов по-прежнему выходят через goto.

Ответ 2



Ещё добавлю пару способов. Указанный код выносится в отдельную функцию. И теперь можно выходить по обычному return. Способ два - нужно прост создать переменную флаг. И проверять ее. Где то так bool go = true; while(go){ for(;;) { if (...) { go = false; break;} } Но это плохой способ.

Ответ 3



try { while (true) { for (;;) { throw 1; } } } catch (int) { //вышли из двух вечных циклов одновременно }

Ответ 4



{ while(1) { for(;;) { if(...) goto AWAY; } } AWAY: ; }

Ответ 5



inline bool func(){ bool exit,only_break; for(;;){ if(exit){ return 1; } if(only_break){ break; } } return 0; } int main(){ while(1){ if(func()){ break; } } }

воскресенье, 22 декабря 2019 г.

Повторный запрос prompt, при введении неподходящего значения

#javascript #циклы #while


Предположим задана переменная:

var variable1 = prompt ('Write "2", please');


Нужно чтобы, если пользователь вводит другое значение, нежели "2", появлялось сообщение
об ошибке. Сделать это можно при помощи if. 

Вопрос - как сделать так, чтобы после сообщения об ошибке, каждый раз (циклично)
снова появлялся prompt с тем же вопросом, и чтобы чтобы введенное в него значение отдавалось
переменной variable1? 
    


Ответы

Ответ 1



Заключите prompt, например, в цикл while while ( true ) { var variable1 = prompt ('Write "2", please'); if ( variable1 == 2 ) break; alert( "Error. Invalid value" ); }

понедельник, 8 июля 2019 г.

Java - чистый код на примере простого цикла

Сразу скажу - в java начинающий, как сделать цикл более "грамотным" и "логичным"?
public void scanner(EnigmaService enigma, String cypher_mode){
//enigma - обьект, который имеет метод enchiper i deschiper // cypher_mode - "-е" или "-d"
Scanner scan = new Scanner(System.in);
while(scan.hasNextLine()){
if(cypher_mode.equals("-e")){ System.out.println(enigma.encipher(scan.nextLine())); } else{ if(cypher_mode.equals("-d")){ System.out.println(enigma.decipher(scan.nextLine())); } } }


Ответ

Поскольку строковые значения -d и -e имеют отношение к параметрам командной строки, т.е. к по сути к пользовательскому интерфейсу, а не непосредственно к логике программы, можно завести enum.
public enum CipherMode { ENCIPHER, DECIPHER; }
Где-то у вас будет код вида:
CipherMode mode = null; if (args.contains("-d")) { mode = DECIPHER } if (args.contains("-e")) { mode = ENCIPHER; } ... if (mode == null) { System.out.println("Не указан режим работы шифра."); return; }
Дальше уже используйте этот enum:
public void scanner(EnigmaService enigma, CypherMode cipherMode){ Scanner scan = new Scanner(System.in); while(scan.hasNextLine()){ String line = scan.nextLine(); switch(cipherMode) { case ENCIPHER: enigma.encipher(line); break; case DECIPHER: enigma.decipher(line); break; } }
PS. Подчеркивания в именах в Java не приняты.

четверг, 6 июня 2019 г.

Скрипт вывода товаров, очень долго грузится

Функции выборки товаров из базы: function result_to_array($result) { $res_array = array(); $count = 0; while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; } return $res_array; }
function get_product() { connect_db(); global $mysqli; $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); $result = result_to_array($result); return $result; } На самой странице все товары выводятся циклом foreach: $products = get_product();

html код
Проблема в том, что страница с товарами открывается ну очень долго, раньше просто на этой же самой странице делал запрос и выводил все через while, по скорости было ощутимо быстрее. Подскажите, что я делаю не так и почему так медленно работает скрипт?


Ответ

А много ли товаров? И можно оптимизировать конструкцию, убрав $count while( $row = $result->fetch_assoc() ) { $res_array[] = $row; } Перед выполнением кода и после выполнения добавьте microtime() function result_to_array($result) { $ra_start = microtime();
$res_array = array(); $count = 0; while( $row = $result->fetch_assoc() ) { $res_array[$count] = $row; $count++; }
$ra_end = microtime(); echo $ra_end - $ra_start; return $res_array; }
function get_product() { $gp_start = microtime();
connect_db(); global $mysqli; $result = $mysqli->query("SELECT *FROM `product` ORDER by `id` DESC"); $result = result_to_array($result);
$gp_end = microtime(); echo $gp_end - $gp_start; return $result; } На самой странице все товары выводятся циклом foreach: $products = get_product();
html код: По результатам сможете увидеть, какой кусок у Вас долго выполняется.

суббота, 29 декабря 2018 г.

В цикле while на c# не запускается Console.WriteLine

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;
namespace CyclesDoWhile { class Program { static void Main(string[] args) { //Количество конфет в пачке int candies = 200;
//Съедено конфет int candiesEaten = 0;
while(candiesEaten != 0) { candies--; candiesEaten++; Console.WriteLine("Конфет съедено. Осталось: " + candies + " Конфет съедено" + candiesEaten); }

Console.ReadKey(); } } }
Этот код работал. Запускался, как положено. Сегодня решил повторить этот урок, все стер. Написал заново. Запускает пустое консольное окно. В чем ошибка?


Ответ

У вас ошибка в условии цикла
//Количество конфет в пачке int candies = 200;
//Съедено конфет int candiesEaten = 0;
while(candiesEaten != 0) ^^^^^^^^^^^^
Данный цикл ни разу не выполнится.
Я думаю вы имеете в виду
//Количество конфет в пачке int candies = 200; //Съедено конфет int candiesEaten = 0;
while(candies != 0) ^^^^^^^

среда, 12 декабря 2018 г.

В чем разница между loop и while true?

В чем разница между loop и while true в rust?
В документации написано что:
loop {} Интерпретируется по другому компилятором чем:
while true {} Хотел бы понять в чем эта разница и на сколько плохо использовать не loop, а while true
версия вопроса на Английском от @aij


Ответ

На такой вопрос был дан ответ в Reddit.
Разница заключается в том, что в случае while true все переменные должны быть инициализированы до цикла, а в случае loop это не обязательно:
Пример с loop
let x; loop { x = 1; break; } println!("{}", x) этот код отлично работает, однако следующий
let x; while true { x = 1; break; } println!("{}", x); покажет ошибку компиляции "use of possibly uninitialised variable" с указанием на x в println. Во втором случае компилятор не определяет, что тело цикла всегда выполнится хотя бы один раз.
перевод ответа @telotortium

вторник, 13 ноября 2018 г.

Повторный запрос prompt, при введении неподходящего значения

Предположим задана переменная:
var variable1 = prompt ('Write "2", please');
Нужно чтобы, если пользователь вводит другое значение, нежели "2", появлялось сообщение об ошибке. Сделать это можно при помощи if.
Вопрос - как сделать так, чтобы после сообщения об ошибке, каждый раз (циклично) снова появлялся prompt с тем же вопросом, и чтобы чтобы введенное в него значение отдавалось переменной variable1?


Ответ

Заключите prompt, например, в цикл while
while ( true ) { var variable1 = prompt ('Write "2", please');
if ( variable1 == 2 ) break;
alert( "Error. Invalid value" ); }