Под "open source" он имеет в виду архитектуру в целом - дизайн, спеки, чертежи, фирмварь. Фраза "ноутбук с открытым исходным кодом" звучит довольно бессмысленно. Ну, если ты не редактор Хабра, конечно. Тогда всё тип-топ.
Боюсь, сначала надо научиться программировать. Если вы напишете про это статью, у неё будет самый низкий рейтинг за всё время существования этого хаба.
Возможно, эти рассуждения и внутренне логичны, но совершенно нерелевантны. Если фича не взлетела - значит она не взлетела. И без всяких живущих под корягой пользователей. В ней изначально не было никакого смысла. Поэтому и оказалась невостребованной. А не потому что про неё не добили каждый день, раздражая немногих оставшихся активных пользователей.
Важно познакомить с генераторами и посеять зерно о том что не стоит бездумно наполнять память
К сожалению, вы здесь повторяете ошибку, которая, как я надеялся, подробно объяснена в комментарии выше. Давайте я попробую ещё раз. Только вы не раздражайтесь и не обижайтесь. Возможно, дело исключительно в формулировках, но в текущем виде они доносят неверную мысль.
Вышеприведённая цитата буквально вбивает в головы ваших учеников мысль о том, что генераторы экономят память, и являются чуть ли не панацеей. Повторюсь - возможно, вы не имели этого в виду. Но в такой формулировке она звучит именно так. И это тонкий момент, который надо увидеть. Смотрите. Вот вы пишете,
Есть масса проектов, где разработчик выбирает из базы все значения и обходит их в цикле.
Совершенно верно. И ниже вы сразу говорите про генераторы. При том, что
Во-первых, есть гораздо более простое и очевидное решение. Не получать из базы сразу все значения. Но вы его не упоминаете.
А во-вторых, в основе "экономии памяти" генератором лежит именно оно. Вы берёте код, который вместо получения всех значений разом, берет их по одному, и помещаете его в генератор.
Но вашей формулировкой вы сбиваете фокус с этого очевидного решения на генератор. И это представляется мне большой ошибкой.
Ответ на вопрос, как экономить память - это "не получать все значения разом, а получать и обрабатывать по одному". Очень простой, очевидный и универсальный.
А "использовать генератор" - это всего лишь частный случай применения этого подхода. К сожалению, многие студенты, воспитанные на этом утверждении, умудряются писать код, в котором внутрь генератора помещают то же самое получение всех значений разом. И их логика при этом безупречна: "Генератор же экономит память"!
Понимаете, о чём я?
Вы в своих объяснениях пропускаете ключевой момент: тот самый подход, "получать по одному, а не скопом", который на самом деле экономит память.
И не даже не упоминаете условие, при котором генератор действительно может "сэкономить память". При том, что это условие надо наоборот, подчеркивать специально: "если надо обработать большой поток данных, но функция-обработчик ожидает массив".
При такой вводной - когда функция-обработчик данных ожидает на вход массив, который она будет перебирать через foreach - решением для экономии памяти действительно является генератор. В основе которого, тем не менее, будет лежать универсальный подход "получать по одному".
Извините, а можно уточнить, откуда такой пиетет перед Отусом? Есть какой-то источник объективной оценки? Так-то их курсы я не видел, но если судить по их статьям на Хабре, то там всё очень плохо.
А можно не извращаться, а всего лишь использовать змеиный регистр, и читать без малейших затруднений, is_least_relevant_multiple_of_next_larger_prime_factor
Но увы, поезд уже ушёл, и верблюжий стал незыблемым стандартом. При том что длинные строки объективно читать легче в змеином.
С этой точки зрения для приближения к реальности задачу стоило бы развернуть наоборот: функция не отдаёт массив, а принимает. Скажем, у нас есть уже существующая функция, которая принимает на вход массив. Но при большом объеме обрабатываемых данных тратится много памяти. При этом данные поступают из какого-либо потока - файла или например базы данных. Вот в этом случае в функцию имеет смысл передавать вместо массива генератор.
В итоге нам не придётся для экономии памяти переписывать код, обрабатывающий массив, помещая его в функцию, которая вызывается внутри цикла получения данных - как это пришлось бы делать до появления генераторов. А всего лишь надо будет немного переписать код, получающий эти данные - не в массив, а в генератор.
Если честно, мне ужасно не хочется выглядеть занудой. Но ещё я ужасно не люблю недопонимания :)
В общем, я имел в виду пример не для статьи, а для курса. То, что он в статье - это как раз нормально. А вот в курсе он как раз довольно слабый. Просто в реальной жизни очень редко, практически никогда нельзя заменить массив генератором. Даже для "случайных" чисел, которые чаще всего используются в примерах про "экономящие память" генераторы, скорее всего требуются не просто случайные, а случайные уникальные. То есть, уже выданные номера надо где-то хранить. И никакой экономии не будет. Не говоря уже о каких-то реальных данных.
Достоинство генератора не в том, что он "экономит память", а в том, что он может превратить цикл в массив. То есть взять любой цикл получения данных, и подать на вход функции, которая ждёт массив. И в итоге не функцию вызывать внутри цикла, а наоборот - внутрь функции передать цикл. Это часто позволяет написать более удобный или универсальный код.
А память он экономит только на таких вот вырожденных и не имеющих практического смысла примерах.
Я так и подумал, но тут есть нюанс: генераторы не имеют отношения к потреблению памяти. Собственно, данный пример это как раз прекрасно и иллюстрирует: память экономит написание осмысленного кода (вызывать функцию не 1 раз, а 80000), а не генератор.
Я просто надеялся, что поскольку курс делают практикующие специалисты, то и примеры они будут брать из практики, а не про кошечек и собачек. Но, в общем, это было наивное ожидание: разумеется, не на всякий аспект языка можно найти пример из непосредственной практики. И всё же я бы порадовался примеру, в котором генератор используется по своему назначению: для написания более удобного кода.
Интересно, где в реальном коде можно применить функцию, которая отдаёт 80000 рандомных значений. А точнее, почему вместо неё нельзя применить функцию, которая отдаёт одно рандомное значение, вызвав её 80000 раз.
Самое неприятное, что элемента с индексом 0 может и не быть, то есть сначала надо проверить, что он есть, а потом уже читать дальше
Это не совсем так. "Сначала" проверять ничего не надо, эта строка вполне рабочая. Если индекса нет, то мы просто получим значение после ??
элемент "formatted" может внезапно оказаться с типом bool вместо string.
А вот тут уже спорный вопрос, что делать в этом случае. По моим представлениям, в таком случае пришедшие данные скорее не стоит обрабатывать вообще, чем как-то подрихтовывать, только чтобы они пролезли в нужное отверстие, пусть и с пустым значением.
И в любом случае, эта проблема решается тем же (string). Куда интереснее вопрос, что делать, если тип boolean окажется у элемента Address, а не formatted. И в этом смысле мне интереснее была бы библиотека с встроенной валидацией по схеме. Ну то есть такое переизобретение SOAP для JSON. Вот такое я бы действительно назвал типобезопасным. А предложенный вариант скорее типоигнорирующим.
Что вы имеете в виду под словом "проходимец"?
Увы, на вас одного здесь десятки неравнодушных пользователей, вдумчиво беседующих с рекламной брошюрой.
Под "open source" он имеет в виду архитектуру в целом - дизайн, спеки, чертежи, фирмварь. Фраза "ноутбук с открытым исходным кодом" звучит довольно бессмысленно. Ну, если ты не редактор Хабра, конечно. Тогда всё тип-топ.
Но кто-то же
написал 4 миллиона доносовнаставил плюсов этой помойке, да так, что она оказалась аж в сайдбаре.Интересно, кто-нибудь обратил внимание на статью, которую опубликовал автор всего 4 дня назад? А как кардинально поменялись его взгляды!
Вообще, конечно, удивительно, кто нагнал этому скаму трафик и голоса.
Боюсь, сначала надо научиться программировать. Если вы напишете про это статью, у неё будет самый низкий рейтинг за всё время существования этого хаба.
Да-да, надои начали более лучше колоситься по сравнению с 1913 годом. Осталось только посмотреть, сколько в этих красивых цифрах ИИ-шлака.
Возможно, эти рассуждения и внутренне логичны, но совершенно нерелевантны. Если фича не взлетела - значит она не взлетела. И без всяких живущих под корягой пользователей. В ней изначально не было никакого смысла. Поэтому и оказалась невостребованной. А не потому что про неё не добили каждый день, раздражая немногих оставшихся активных пользователей.
...написал супер-вовлечённый пользователь, активность которого составила, в среднем, 0 комментариев за 10 лет. Очень, очень релевантное мнение.
К сожалению, вы здесь повторяете ошибку, которая, как я надеялся, подробно объяснена в комментарии выше. Давайте я попробую ещё раз. Только вы не раздражайтесь и не обижайтесь. Возможно, дело исключительно в формулировках, но в текущем виде они доносят неверную мысль.
Вышеприведённая цитата буквально вбивает в головы ваших учеников мысль о том, что генераторы экономят память, и являются чуть ли не панацеей. Повторюсь - возможно, вы не имели этого в виду. Но в такой формулировке она звучит именно так. И это тонкий момент, который надо увидеть. Смотрите. Вот вы пишете,
Совершенно верно. И ниже вы сразу говорите про генераторы. При том, что
Во-первых, есть гораздо более простое и очевидное решение. Не получать из базы сразу все значения. Но вы его не упоминаете.
А во-вторых, в основе "экономии памяти" генератором лежит именно оно. Вы берёте код, который вместо получения всех значений разом, берет их по одному, и помещаете его в генератор.
Но вашей формулировкой вы сбиваете фокус с этого очевидного решения на генератор. И это представляется мне большой ошибкой.
Ответ на вопрос, как экономить память - это "не получать все значения разом, а получать и обрабатывать по одному". Очень простой, очевидный и универсальный.
А "использовать генератор" - это всего лишь частный случай применения этого подхода. К сожалению, многие студенты, воспитанные на этом утверждении, умудряются писать код, в котором внутрь генератора помещают то же самое получение всех значений разом. И их логика при этом безупречна: "Генератор же экономит память"!
Понимаете, о чём я?
Вы в своих объяснениях пропускаете ключевой момент: тот самый подход, "получать по одному, а не скопом", который на самом деле экономит память.
И не даже не упоминаете условие, при котором генератор действительно может "сэкономить память". При том, что это условие надо наоборот, подчеркивать специально: "если надо обработать большой поток данных, но функция-обработчик ожидает массив".
При такой вводной - когда функция-обработчик данных ожидает на вход массив, который она будет перебирать через foreach - решением для экономии памяти действительно является генератор. В основе которого, тем не менее, будет лежать универсальный подход "получать по одному".
Ну то есть это ваше личное мнение, под которое вы подписали всё РНР коммюнити?
Извините, а можно уточнить, откуда такой пиетет перед Отусом? Есть какой-то источник объективной оценки? Так-то их курсы я не видел, но если судить по их статьям на Хабре, то там всё очень плохо.
Зато на пиар вот не поскупились.
А можно не извращаться, а всего лишь использовать змеиный регистр, и читать без малейших затруднений,
is_least_relevant_multiple_of_next_larger_prime_factor
Но увы, поезд уже ушёл, и верблюжий стал незыблемым стандартом. При том что длинные строки объективно читать легче в змеином.
С этой точки зрения для приближения к реальности задачу стоило бы развернуть наоборот: функция не отдаёт массив, а принимает. Скажем, у нас есть уже существующая функция, которая принимает на вход массив. Но при большом объеме обрабатываемых данных тратится много памяти. При этом данные поступают из какого-либо потока - файла или например базы данных. Вот в этом случае в функцию имеет смысл передавать вместо массива генератор.
В итоге нам не придётся для экономии памяти переписывать код, обрабатывающий массив, помещая его в функцию, которая вызывается внутри цикла получения данных - как это пришлось бы делать до появления генераторов. А всего лишь надо будет немного переписать код, получающий эти данные - не в массив, а в генератор.
Если честно, мне ужасно не хочется выглядеть занудой. Но ещё я ужасно не люблю недопонимания :)
В общем, я имел в виду пример не для статьи, а для курса. То, что он в статье - это как раз нормально. А вот в курсе он как раз довольно слабый. Просто в реальной жизни очень редко, практически никогда нельзя заменить массив генератором. Даже для "случайных" чисел, которые чаще всего используются в примерах про "экономящие память" генераторы, скорее всего требуются не просто случайные, а случайные уникальные. То есть, уже выданные номера надо где-то хранить. И никакой экономии не будет. Не говоря уже о каких-то реальных данных.
Достоинство генератора не в том, что он "экономит память", а в том, что он может превратить цикл в массив. То есть взять любой цикл получения данных, и подать на вход функции, которая ждёт массив. И в итоге не функцию вызывать внутри цикла, а наоборот - внутрь функции передать цикл. Это часто позволяет написать более удобный или универсальный код.
А память он экономит только на таких вот вырожденных и не имеющих практического смысла примерах.
Так вроде практически вся последующая статья как раз подробно все вузы и описывает?
Я так и подумал, но тут есть нюанс: генераторы не имеют отношения к потреблению памяти. Собственно, данный пример это как раз прекрасно и иллюстрирует: память экономит написание осмысленного кода (вызывать функцию не 1 раз, а 80000), а не генератор.
Я просто надеялся, что поскольку курс делают практикующие специалисты, то и примеры они будут брать из практики, а не про кошечек и собачек. Но, в общем, это было наивное ожидание: разумеется, не на всякий аспект языка можно найти пример из непосредственной практики. И всё же я бы порадовался примеру, в котором генератор используется по своему назначению: для написания более удобного кода.
Интересно, где в реальном коде можно применить функцию, которая отдаёт 80000 рандомных значений. А точнее, почему вместо неё нельзя применить функцию, которая отдаёт одно рандомное значение, вызвав её 80000 раз.
Небольшая поправка
Это не совсем так. "Сначала" проверять ничего не надо, эта строка вполне рабочая. Если индекса нет, то мы просто получим значение после ??
А вот тут уже спорный вопрос, что делать в этом случае. По моим представлениям, в таком случае пришедшие данные скорее не стоит обрабатывать вообще, чем как-то подрихтовывать, только чтобы они пролезли в нужное отверстие, пусть и с пустым значением.
И в любом случае, эта проблема решается тем же (string). Куда интереснее вопрос, что делать, если тип boolean окажется у элемента Address, а не formatted. И в этом смысле мне интереснее была бы библиотека с встроенной валидацией по схеме. Ну то есть такое переизобретение SOAP для JSON. Вот такое я бы действительно назвал типобезопасным. А предложенный вариант скорее типоигнорирующим.