<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Savichhh</title><generator>teletype.in</generator><description><![CDATA[Savichhh]]></description><image><url>https://img3.teletype.in/files/6f/50/6f505a42-2eed-41be-9433-13c234f71c90.png</url><title>Savichhh</title><link>https://teletype.in/@it_guru</link></image><link>https://teletype.in/@it_guru?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/it_guru?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/it_guru?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Wed, 29 Apr 2026 16:46:13 GMT</pubDate><lastBuildDate>Wed, 29 Apr 2026 16:46:13 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@it_guru/yhzyUj7AeDZ</guid><link>https://teletype.in/@it_guru/yhzyUj7AeDZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/yhzyUj7AeDZ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>Как составить резюме IT-специалисту, которое точно запомнится</title><pubDate>Sun, 04 Jun 2023 13:47:36 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/4d/c3/4dc3982f-5915-46b0-823a-31fa3b18aa6d.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2023/05/76f1703b-458f-4a9f-b3c7-62bd0f29adb3.jpg"></img>Резюме помогает составить первое впечатление тем, кто нанимает вас как специалиста. Рекрутеры и HR просматривают сотни анкет, поэтому хорошее резюме — залог того, что кандидата заметят и предложат работу.]]></description><content:encoded><![CDATA[
  <figure id="PUcg" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/76f1703b-458f-4a9f-b3c7-62bd0f29adb3.jpg" width="890" />
  </figure>
  <p id="Fhl7">Резюме помогает составить первое впечатление тем, кто нанимает вас как специалиста. Рекрутеры и HR просматривают сотни анкет, поэтому хорошее резюме — залог того, что кандидата заметят и предложат работу.</p>
  <p id="Cu0z">В статье рассмотрим, как составить резюме, что стоит выделить, а на чем не заострять внимание. Еще вы узнаете о видеорезюме как оригинальном способе рассказать о себе.</p>
  <h2 id="HDBf">Основные правила хорошего резюме в IT</h2>
  <p id="RUf6">Резюме — это краткая информация о специалисте. Оно должно быть емким и отражать ваши умения и опыт.</p>
  <p id="GOxI">На что работодатель смотрит в первую очередь:</p>
  <ul id="moCE">
    <li id="C8Rc">Компании, с которыми вы сотрудничали. Важно раскрыть, чем вы занимались и какие задачи решали. Простого упоминания крупных и известных компаний недостаточно.</li>
    <li id="lMhM">Перечень навыков и умений. Укажите, какими программами вы владеете и на каком уровне. В технических вакансиях особое внимание уделяют перечню технологий и программ, которые специалист должен знать. Имеет смысл при новом отклике эти навыки выделять отдельно.</li>
    <li id="2A8k">Достижения. Напишите, чем вы гордитесь и что делаете лучше всего. Данный пункт отражает, что вам важно, что происходит в компании. Например: «Я представил систему оценки, которая все еще используется всем подразделением».</li>
  </ul>
  <p id="sxho">Выделим моменты, которые необходимо учитывать перед составлением резюме.</p>
  <h3 id="0zKb">Объем</h3>
  <p id="zB4t">У рекрутеров нет времени, чтобы детально изучать каждое резюме. Они закроют документ, составленный на три-четыре страницы, и перейдут к следующему кандидату. Оптимальный объем резюме — одна-две страницы. Иногда HR могут просматривать и пять-шесть страниц при условии, что указана важная информация о кандидате.</p>
  <h3 id="zQSz">Форматирование</h3>
  <p id="p9gz">Весь текст необходимо разбивать на смысловые блоки — это позволит рекрутеру быстро изучить резюме и «выудить» самое важное. Используйте не более двух цветов и не слишком много шрифтов. Не забудьте про подзаголовки и выделение перечней списками. Контакты обычно размещают отдельным блоком.</p>
  <h3 id="YnPo">Сопроводительное письмо</h3>
  <p id="NB7a">Письмо направляют вместе с резюме. Сообщение не должно быть шаблонным — это не вызывает доверия, а лишь отталкивает.</p>
  <p id="8WbJ">Необходимо представиться и указать на какую вакансию вы откликаетесь. Далее добавьте краткое описание опыта и навыков. Однако это не пересказ резюме: пишите с учетом требований к должности, на которую претендуете. Цель сопроводительного письма — обратить на себя внимание и указать, почему вы подходите на данную должность.</p>
  <figure id="Oiea" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/15da0c29-6341-4758-86ce-8755c7bd6688.jpg" width="1004" />
  </figure>
  <h2 id="77Jh">Структура резюме IT-специалиста</h2>
  <p id="CXy7">Остановимся на важных составляющих.</p>
  <h2 id="nVo0">Образование</h2>
  <p id="yDah">Указывайте любое образование, даже не профильное и не соответствующее вакансии. Дополнительно пропишите пройденные курсы.</p>
  <figure id="jsii" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/15252378-7577-407c-86c8-5de2178ca328.jpg" width="522" />
  </figure>
  <h2 id="G3NY">Опыт</h2>
  <p id="qtCo">Соблюдайте хронологию и четкость при описании предыдущих мест работы. Можно начинать с раннего опыта, заканчивая последним местом работы. Но хронологию выстраивают и в обратном порядке. Если у специалиста богатый опыт, то рассказывать подробно про каждое место работы не обязательно: о самых ранних этапах можно написать кратко и объединить информацию в один абзац.</p>
  <p id="TMjA">Стандартно пишут так: период работы (месяц и год) — название компании — наименование должности — перечень обязанностей.</p>
  <p id="2k23">Последний пункт можно раскрывать подробнее и писать развернуто. Выберите показательные проекты, которыми вы гордитесь.</p>
  <figure id="jsv0" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/eb1b6ab1-449c-42fa-b9a9-b0ccea8bd34a.jpg" width="560" />
  </figure>
  <h2 id="IWeP">Ключевые навыки</h2>
  <p id="i2yU">К этому блоку можно подойти формально и не расписывать подробно. Уровень владения ПО или языком программирования часто указывают схематично. Выделяйте ключевые навыки одним блоком, чтобы рекрутер мог одним взглядом оценить ваши профессиональные умения.</p>
  <figure id="cdUb" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/29ebe14d-52d5-4cca-b0cc-de0d5d6ae8c9.jpg" width="600" />
  </figure>
  <p id="rW8d">Как может выглядеть список навыков</p>
  <h2 id="QBbk">Личные качества</h2>
  <p id="4vJQ">Обычный перечень качеств, который можно взять в интернете, не добавляет плюсов к резюме. Но если оформить их грамотно, то можно смотреться выигрышно на фоне других кандидатов. Лучший способ — к описываемым качествам добавлять примеры из профессиональной сферы. Если говорите о своей внимательности, то покажите это примером. Например, «три года работал ретушером — это деятельность, требующая высокой скрупулезности».</p>
  <p id="Q47u">К «Личным качествам» можно отнести еще хобби и дополнительные умения. Идеально, если они косвенно связаны с будущей деятельностью. Допустим, вы — заядлый любитель компьютерных игр и устраиваетесь в компанию, которая разрабатывает курсы на основе Minecraft. Об этом стоит упомянуть.</p>
  <p id="ruft">Структуру можно менять на своё усмотрение. Например, кандидаты иногда заменяют пункт про личные качества на абзац «О себе».</p>
  <figure id="WMhw" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/62821365-65ba-4e5e-8322-52581c4f1639.jpg" width="556" />
  </figure>
  <h2 id="GyJI">Фотография</h2>
  <p id="tToa">Фотография специалиста не влияет на принятие решения о найме человека. Но она персонализирует резюме. Выбирайте сдержанный снимок, где хорошо видно лицо. Если удачных кадров не найти, можно устроить фотосессию или вовсе не добавлять фотографию.</p>
  <figure id="dP6x" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/23e3825a-2fa8-4e78-8e79-ebc84bc5bf68.jpg" width="1000" />
  </figure>
  <p id="jmM9">Разница в резюме при наличии и отсутствии фотографии</p>
  <p id="4YZQ">Резюме можно дополнить контактами лиц, которые готовы подтвердить вашу квалификацию — руководителя с прошлого места работы или бывших коллег.</p>
  <h2 id="p11T">Видеорезюме как оригинальный способ проявить себя IT-специалисту</h2>
  <p id="y4Bp">Помимо традиционного резюме в электронном виде, крупные компании зачастую просят прислать видеовизитку. Это помогает HR-специалисту быстрее принять решение, приглашать ли кандидата на следующий этап отбора. Еще видеорезюме показывает, насколько грамотная у кандидата речь, приятный и коммуникабельный ли человек, какая манера общения и поведения.</p>
  <p id="q8mM">Рекомендации для проведения съемки:</p>
  <ul id="GtB7">
    <li id="sZtY">выбирайте нейтральный или однотонный фон;</li>
    <li id="mIv2">во время записи не должно быть постороннего и отвлекающего шума;</li>
    <li id="9P67">продумайте одежду и прическу — лучше выбирать деловой или нейтральный стиль;</li>
    <li id="OLvM">перед съемкой составьте сценарий;</li>
    <li id="Yo4j">устанавливайте камеру на уровне глаз и не снимайте слишком близко (лучше, когда человека видно по пояс).</li>
  </ul>
  <p id="yyDL">Оптимальная длина видео — не более двух минут. Необязательно покупать петличку или микрофон, используйте обычные наушники с микрофоном.</p>
  <p id="m3fa">Сначала представьтесь и расскажите о релевантном опыте работы. Ответьте на вопрос, почему вы откликнулись на вакансию и компания должна выбрать вас. В конце видео попрощайтесь.</p>
  <p id="w7CC"><strong>Посмотрите, как может выглядеть видеорезюме:</strong></p>
  <p id="SOwh"><a href="https://www.youtube.com/watch?v=KUzxA57-PV4&t=24s" target="_blank">Видеорезюме</a></p>
  <p id="ntbz">При наличии опыта в монтаже видеороликов можно выбирать продвинутые видеоредакторы. Часто они имеют платные подписки, зато перечень функционала впечатляет.</p>
  <p id="QOQb">Однако для съемки видеовизитки не нужны спецэффекты. В редакторе должна быть возможность отрегулировать громкость речи и убрать неудачные эпизоды. Например, программа ВидеоМОНТАЖ — <a href="https://video-editor.su/prostoy-videoredaktor.php" target="_blank">самый простой видеоредактор</a>, в котором пользователи быстро разбираются.</p>
  <p id="RX5i">На примере ВидеоМОНТАЖа рассмотрим, как составить видеорезюме:</p>
  <p id="8xJG">1. Скачайте программу с официального сайта и следуйте подсказкам установщика.</p>
  <p id="PJ4E">2. Запустите видеоредактор и щелкните «Новый проект» → «Проект с нуля».</p>
  <figure id="meyp" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/09081d1f-cd1b-4202-9303-fbd138e0886d.jpg" width="1243" />
  </figure>
  <p id="mh4c">3. Добавьте записанное видео на монтажный стол. Чтобы облегчить редактирование видеоряда, разделите его на фрагменты. Используйте инструмент «Разделить».</p>
  <figure id="UqSq" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/adfd3656-3a11-4053-a244-fba3403eff94.jpg" width="1245" />
  </figure>
  <p id="Qw9L">4. Для обрезки выделите эпизод и нажмите иконку с ножницами. Чтобы сократить видеоряд по краям, можно действовать по старинке: наведите курсором на границы выделенного эпизода и сдвигайте влево или вправо.</p>
  <figure id="Ehju" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/d22c402b-bd6b-4d40-9e6e-f6d205f9a1fb.jpg" width="1244" />
  </figure>
  <p id="yObv">5. Для плавной склейки фрагментов задействуйте переходы или оставьте смену кадров более резкой.</p>
  <figure id="mJHq" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/c2822d30-a176-4830-9c17-0a6f47db2af5.jpg" width="1244" />
  </figure>
  <p id="kLyU">6. Вы можете добавить текст в любую часть экрана, отрегулировать яркость и насыщенность видео. Есть возможность записать звук с микрофона. Пригодится, если какой-то фрагмент не получился, а записывать себя заново не хочется.</p>
  <p id="PwZe">7. Сохраните видеовизитку в подходящем формате. Можно настроить качество видео и размер кадра.</p>
  <figure id="SudP" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/56da297b-6459-40cf-b407-1885f16fbc04.jpg" width="694" />
  </figure>
  <h2 id="SXj7">Чек-лист запоминающегося резюме IT-специалиста</h2>
  <p id="0jK6">Резюме — это страницы с информацией, в которых описано, чему вы научились к сегодняшнему моменту. Но важно превратить их в свою визитную карточку.</p>
  <p id="4DJI">Что указать:</p>
  <ul id="3AH8">
    <li id="gzOo">данные о себе — Ф.И.О., возраст и контактную информацию (номер телефона и электронная почта);</li>
    <li id="0pMA">образование;</li>
    <li id="R1Qz">описание опыта работы и достижений (с перечнем весомых рабочих проектов);</li>
    <li id="ThLh">личные и профессиональные качества.</li>
  </ul>
  <figure id="Zm6N" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/84b0c8c5-476e-4db6-8122-39eda45cabe7.jpg" width="1600" />
  </figure>
  <p id="6XIl">Примеры оформления резюме</p>
  <h2 id="8YMv">Заключение</h2>
  <p id="ADeW">С нашими рекомендациями вы сможете доработать или улучшить резюме. Информация о себе должна быть релевантна вакансии, на которую откликаетесь. Поэтому к резюме периодически придется возвращаться.</p>
  <p id="4hGj">Представляйте себя на месте рекрутера и проанализируйте, какая информация поможет принять решение в вашу пользу, а какая представит в невыгодном свете. Наравне с классическим резюме, задумайтесь над созданием видеорезюме. Это новый и интересный способ рассказать о себе и заинтересовать компанию своей кандидатурой.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/ecC7NfK5qPk</guid><link>https://teletype.in/@it_guru/ecC7NfK5qPk?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/ecC7NfK5qPk?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>10 инструментов для CSS: анимация, сетки и дизайн</title><pubDate>Sun, 04 Jun 2023 13:44:22 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/c5/06/c50601b3-da5e-4851-9f1b-ef09b6067d2d.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2023/06/9c19bb35-f0b9-4ae7-95b3-e6a076e0b421.png"></img>Веб-разработчику может быть сложно идти в ногу с новейшими технологиями и трендами веб-дизайна.]]></description><content:encoded><![CDATA[
  <p id="GcNL">Веб-разработчику может быть сложно идти в ногу с новейшими технологиями и трендами веб-дизайна.</p>
  <p id="q0hs">Однако, поскольку CSS является фундаментальной частью интерфейсной веб-разработки, доступ к нужным инструментам CSS может существенно повлиять на производительность и креативность разработчика.</p>
  <p id="yorP">В этой статье мы рассмотрим некоторые из самых популярных инструментов CSS, которые помогут вам идти в ногу со временем и вывести свои навыки CSS на новый уровень.</p>
  <h2 id="qDqI">Неоморфизм</h2>
  <p id="WElC"><a href="https://neumorphism.io/#e0e0e0" target="_blank">Neumorphism.io</a> — это веб-сайт, на котором можно сгенерировать блоки в стиле неоморфизма. Это мягкий пользовательский интерфейс, который также называют неоскевоморфизмом.</p>
  <p id="6LSP">Сайт генерирует стили CSS с программным интерфейсом, используя тени.</p>
  <figure id="xseM" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/9c19bb35-f0b9-4ae7-95b3-e6a076e0b421.png" width="1904" />
  </figure>
  <h2 id="YqON">Animista</h2>
  <p id="9G2G"><a href="https://animista.net/play" target="_blank">Animista</a> — это коллекция анимаций CSS и пресетов, которые можно легко настроить и применить к веб-элементам.</p>
  <figure id="saKs" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/257a4bb6-2eca-4cb8-84ed-032f3d06a3ab.png" width="1904" />
  </figure>
  <h2 id="ZjWl">Анимированный фон</h2>
  <p id="616H"><a href="https://wweb.dev/resources/animated-css-background-generator" target="_blank">Wweb.dev</a> — генератор анимированных фонов CSS. Он позволяет создавать и настраивать анимированные фоны для своих веб-проектов.</p>
  <figure id="dYP9" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/513cf5a7-1fbf-46b2-a03e-3d6673494782.png" width="1904" />
  </figure>
  <h2 id="o4bb">Spin Kit</h2>
  <p id="eXrz"><a href="https://tobiasahlin.com/spinkit/" target="_blank">Spin Kit</a> — это коллекция анимаций загрузки на CSS, созданная Тобиасом Ахлином.</p>
  <p id="8qM4">На сайте есть простые и настраиваемые анимации, которые можно легко интегрировать в веб-проекты.</p>
  <figure id="wyBl" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/7db7c061-d221-4f9b-a626-6b86d47e2117.png" width="1904" />
  </figure>
  <h2 id="MtlJ">Flexplorer</h2>
  <p id="9S2O"><a href="https://bennettfeely.com/flexplorer/" target="_blank">Flexplorer</a> — это онлайн-инструмент веб-разработчика Беннета Фили, который помогает разработчикам изучать и экспериментировать с макетами CSS flexbox. Flexbox позволяет быстро создавать гибкие и адаптивные макеты.</p>
  <figure id="4XFx" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/873d9b60-1d60-46eb-bb06-524c203d5c1c.png" width="1904" />
  </figure>
  <h2 id="ynOy">Генератор сетки</h2>
  <p id="Rgfd"><a href="https://cssgrid-generator.netlify.app/" target="_blank">CSS Grid Generator</a> — это веб-инструмент, который помогает разработчикам создавать сложные макеты сетки с помощью CSS Grid. Это мощный способ создания гибких и адаптивных дизайнов веб-страниц.</p>
  <figure id="dKv2" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/af967ad6-8453-40a3-bab0-49bf2a18e268.png" width="1904" />
  </figure>
  <h2 id="smW1">Генератор макетов</h2>
  <p id="lCjl"><a href="https://layout.bradwoods.io/" target="_blank">CSS Layout Generator</a> — это веб-инструмент, который позволяет разработчикам создавать стили макетов CSS и экспериментировать с ними. Он предоставляет визуальный интерфейс для разработки и настройки компонентов макета.</p>
  <figure id="qMIW" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/7ebd8c00-623c-4600-a9c6-c86baeb0c43a.png" width="1904" />
  </figure>
  <h2 id="UKOw">Shadows Brumm</h2>
  <p id="wKl9"><a href="https://shadows.brumm.af/" target="_blank">Shadows Brumm</a> — это веб-инструмент для создания CSS-эффектов теней. У сайта простой интерфейс, который позволяет создавать сложные и красивые тени, используя множество параметров и опций.</p>
  <figure id="iJ5d" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/144893d9-ff10-4633-9f94-e3de7397fc09.png" width="1904" />
  </figure>
  <h2 id="sfb2">Глассморфизм</h2>
  <p id="SUSb"><a href="https://hype4.academy/tools/glassmorphism-generator" target="_blank">Glassmorphism</a> — это направление в дизайне, в котором используются прозрачные и размытые «стеклянные» фоны.</p>
  <figure id="8jjp" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/af9caa69-8d51-46ce-a4d9-a7ef1ef75d2f.png" width="1904" />
  </figure>
  <h2 id="K2w3">Cubic-Bezier</h2>
  <p id="KQ1a"><a href="https://cubic-bezier.com/#.17,.67,.83,.67" target="_blank">Cubic-Bezier </a>— это веб-инструмент, который позволяет пользователям создавать собственные кривые для плавных анимаций и переходов.</p>
  <figure id="gXjV" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/06/5c076e9f-b8dd-491a-8c1f-e0480710aa8d.png" width="1904" />
  </figure>
  <h2 id="UEpj">Заключение</h2>
  <p id="NuOf">Инструменты CSS нужны разработчикам, которые хотят создавать визуально привлекательные и отзывчивые веб-сайты. Правильный набор инструментов сильно повышает производительность разработчиков и экономит время.</p>
  <p id="uVYv">Не забывайте экспериментировать и находить решения, которые подходят для ваших проектов: правильные инструменты CSS помогут вам выйти на новый уровень.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/H9npGOaqMRm</guid><link>https://teletype.in/@it_guru/H9npGOaqMRm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/H9npGOaqMRm?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>Bose — фреймворк для создания веб-ботов, который проще Selenium</title><pubDate>Sun, 04 Jun 2023 13:31:43 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/05/01/05018561-d3e1-478a-b1da-e653f7735bcf.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2023/05/e771a3e1-4faa-41c9-9242-1e29aa37be30.png"></img>Разработка ботов — это сложно.]]></description><content:encoded><![CDATA[
  <p id="FeBB">Разработка ботов — это сложно.</p>
  <p id="7tBG">Детекторы ботов вроде Cloudflare готовы защищать сайты от наших ботов. Настройка Selenium с помощью ChromeOptions слишком громоздкая, а на Windows становится совсем кошмарной. Отладка ботов через журналы — тоже слишком сложно.</p>
  <p id="DF0H">Как решить эти боли, не жертвуя скоростью и удобством разработки? Попробуйте Bose.</p>
  <p id="vPOE">Bose, как уверяют разработчики фреймворка, — это первая среда разработки ботов, которая максимально упрощает разработку ботов. Фреймворк основан на на Selenium и предлагает ряд функций, упрощающих разработку.</p>
  <p id="tsct">GitHub — omkarcloud/bose: The Ultimate Web Scraping Framework</p>
  <p id="zMbA">github.com</p>
  <h2 id="4IQd">Настраиваем Bose</h2>
  <p id="mPCO">Первым делом, скопируем изначальный шаблон.</p>
  <pre id="rP2o">git clone https://github.com/omkarcloud/bose-starter my-bose-project</pre>
  <p id="YCxD">Затем перейдите в скачанный каталог, установите зависимости и запустите проект:</p>
  <pre id="Ct7m">cd my-bose-project
python -m pip install -r requirements.txt
python main.py</pre>
  <p id="NHAJ">Первый запуск займет некоторое время. Всё потому, что он загружает исполняемый файл драйвера Chrome. Следующие запуски будут гораздо быстрее.</p>
  <h2 id="BKQu">Основные особенности Bose Framework</h2>
  <p id="Wqah">Добавляет мощные методы, чтобы сделать работу с Selenium намного проще.</p>
  <p id="okwc">Применяет лучшие практики, чтобы избежать обнаружения ботов Cloudflare и PerimeterX.</p>
  <p id="FPJc">Сохраняет HTML, снимок экрана и сведения о выполнении для каждой задачи, что упрощает отладку.</p>
  <p id="MMCb">Вспомогательные компоненты для записи очищенных данных в виде файлов JSON, CSV и Excel.</p>
  <p id="Gcn9">Автоматически загружает и инициализирует правильный драйвер Chrome.</p>
  <p id="dawV">Быстро и удобно для разработчиков.</p>
  <h2 id="g5La">Работаем с Bose</h2>
  <p id="lA2U">Допустим, вы хотите начать парсинг веб-сайта. Если бы вы использовали Selenium, вам пришлось бы обрабатывать задачи по открытию и закрытию драйвера следующим образом:</p>
  <pre id="AfcC">from selenium import webdriver

driver_path = &#x27;path/to/chromedriver&#x27;

driver = webdriver.Chrome(executable_path=driver_path)

driver.get(&#x27;https://www.example.com&#x27;)

driver.quit()</pre>
  <p id="A4Lj">Однако Bose Framework использует декларативный и структурированный подход. Вам нужно только написать код ниже, а драйвер Bose сам создаст драйвер, передаст его методу run и закроет работу.</p>
  <pre id="L78c">from bose import *

class Task(BaseTask):
    def run(self, driver):
        driver.get(&#x27;https://www.example.com&#x27;)</pre>
  <h2 id="UCLe">Конфигурация Bose</h2>
  <p id="qGNY">В Selenium, если вы захотите настроить параметры вроде профиля, пользовательского агента или размера окна, нужно будет написать много кода:</p>
  <pre id="6R67">from selenium.webdriver.chrome.options import Options
from selenium import webdriver

driver_path = &#x27;path/to/chromedriver.exe&#x27;

options = Options()

profile_path = &#x27;1&#x27;

options.add_argument(f&#x27;--user-data-dir={profile_path}&#x27;)

user_agent = &#x27;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.37&quot;)&#x27;
options.add_argument(f&#x27;--user-agent={user_agent}&#x27;)

window_width = 1200
window_height = 720
options.add_argument(f&#x27;--window-size={window_width},{window_height}&#x27;)

driver = webdriver.Chrome(executable_path=driver_path, options=options)</pre>
  <p id="0vlW">Bose Framework упрощает конфигурацию, инкапсулируя её в свойстве <code>BrowserConfig</code>:</p>
  <pre id="iikC">from bose import BaseTask, BrowserConfig, UserAgent, WindowSize

class Task(BaseTask):
    browser_config = BrowserConfig(user_agent=UserAgent.user_agent_106, window_size=WindowSize.window_size_1280_720, profile=1)</pre>
  <h2 id="30SX">Обработка исключений</h2>
  <p id="tCe9">Исключения — это боль при работе с Selenium.</p>
  <p id="APwW">В Selenium, если возникает исключение, драйвер автоматически закрывается, оставляя вам только журналы для отладки.</p>
  <p id="cLKb">В Bose, когда в задаче парсинга возникает исключение, браузер остается открытым. Вы можете отслеживать состояние браузера в момент возникновения исключения, что очень помогает при отладке.</p>
  <figure id="gpzV" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/e771a3e1-4faa-41c9-9242-1e29aa37be30.png" width="1920" />
  </figure>
  <h2 id="SCcf">Отладка в Bose Framework</h2>
  <p id="5KvV">При веб-скрапинге часто возникают ошибки вроде неправильных селекторов или страниц, которые не загружаются. При отладке в Selenium вам, возможно, придется отсматривать журналы, чтобы найти, какая возникла проблема.</p>
  <p id="XjQZ">Bose упрощает отладку, сохраняя информацию о каждом запуске.</p>
  <p id="HxRo">После каждого запуска в задачах создается каталог, содержащий три файла, перечисленных ниже:</p>
  <pre id="g58d">task_info.json</pre>
  <p id="NTKk">Файл содержит информацию о выполнении задачи: продолжительность выполнения задачи, IP-адрес задачи, пользовательский агент, размер окна и профиль, который использовался для выполнения задачи.</p>
  <pre id="QDmd">final.png</pre>
  <p id="9YVB">Это снимок экрана, сделанный до закрытия драйвера.</p>
  <pre id="glVL">page.html</pre>
  <p id="MC0a">Это исходный HTML-код, полученный до закрытия драйвера. Код страницы полезно знать, если селекторам не удалось выбрать элементы.</p>
  <pre id="t0mg">error.log</pre>
  <p id="YHQX">В случае, если ваша задача рухнула из-за исключения, Bose сохраняет <code>error.log</code> с ошибкой, из-за которой задача рухнула.</p>
  <h2 id="yN1b">Вывод данных</h2>
  <p id="8s3m">После выполнения парсинга веб-страниц нужно сохранить данные в формате JSON или CSV. Как правило, этот процесс подразумевает написание огромного объёма императивного кода:</p>
  <pre id="o4YQ">import csv
import json

def write_json(data, filename):
    with open(filename, &#x27;w&#x27;) as fp:
        json.dump(data, fp, indent=4)

def write_csv(data, filename):
    with open(filename, &#x27;w&#x27;, newline=&#x27;&#x27;, encoding=&#x27;utf-8&#x27;) as csvfile:
        fieldnames = data[0].keys()  # get the fieldnames from the first dictionary
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writeheader()  # write the header row
        writer.writerows(data)  # write each row of data

data = [
    {
        &quot;text&quot;: &quot;\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d&quot;,
        &quot;author&quot;: &quot;Albert Einstein&quot;
    },
    {
        &quot;text&quot;: &quot;\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d&quot;,
        &quot;author&quot;: &quot;J.K. Rowling&quot;
    }
]

write_json(data, &quot;data.json&quot;)
write_csv(data, &quot;data.csv&quot;)</pre>
  <p id="IWlH">Bose упрощает процесс, инкапсулируя данные в модуль вывода для чтения и записи данных. Просто метод <code>write</code> для файла, который вы хотите сохранить.</p>
  <p id="IQBS">Все данные будут сохранены в папке <code>output/</code>:</p>
  <pre id="Yn1W">from bose import Output

data = [
    {
        &quot;text&quot;: &quot;\u201cThe world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.\u201d&quot;,
        &quot;author&quot;: &quot;Albert Einstein&quot;
    },
    {
        &quot;text&quot;: &quot;\u201cIt is our choices, Harry, that show what we truly are, far more than our abilities.\u201d&quot;,
        &quot;author&quot;: &quot;J.K. Rowling&quot;
    }
]

Output.write_json(data, &quot;data.json&quot;)
Output.write_csv(data, &quot;data.csv&quot;)</pre>
  <h2 id="13dF">Локальное хранилище</h2>
  <p id="tQGt">В современных браузерах есть локальный модуль хранения, и Bose перенял эту концепцию.</p>
  <p id="yKSJ">Вы можете импортировать объект <code>LocalStorage</code> из Bose, чтобы сохранять данные при запуске браузера, что чрезвычайно полезно при очистке больших объемов данных.</p>
  <p id="DCtB">Данные хранятся в файле <code>local_storage.json</code> в корневом каталоге проекта. Вот как можно его использовать:</p>
  <pre id="xr3W">from bose import LocalStorage

LocalStorage.set_item(&quot;pages&quot;, 5)
print(LocalStorage.get_item(&quot;pages&quot;))</pre>
  <h2 id="4OJY">Другие возможности</h2>
  <p id="eZQW">Драйвер, полученный при запуске задачи — это расширенная версия Selenium, в которую добавлены мощные методы, упрощающие работу.</p>
  <p id="dtQv">Вот некоторые из популярных методов, добавленных в драйвер:</p>
  <figure id="LO7v" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/8a32df2f-06fa-4e94-a2a9-33640be6fccd.png" width="842" />
  </figure>
  <h2 id="0AzF">Заключение</h2>
  <p id="6nKL">Bose — отличный фреймворк, упрощающий скучные части Selenium и парсинга веб-страниц.</p>
  <p id="OVCw">Желаем вам удачи и счастливой разработки ботов с помощью Bose Framework!</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/uH7n-CLNULK</guid><link>https://teletype.in/@it_guru/uH7n-CLNULK?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/uH7n-CLNULK?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>Решаем задачи, которые многих ставят в тупик</title><pubDate>Tue, 30 May 2023 13:11:49 GMT</pubDate><description><![CDATA[Перед нами 2 комнаты, в которых низкие потолки. В комнате под номером 1 висит три лампочки накаливания, а во второй комнате имеется три переключателя.]]></description><content:encoded><![CDATA[
  <h2 id="PL3l">№1. Включаем лампочки</h2>
  <p id="NFnh">Перед нами 2 комнаты, в которых низкие потолки. В комнате под номером 1 висит три лампочки накаливания, а во второй комнате имеется три переключателя.</p>
  <p id="AEH2"><strong>Вопрос</strong></p>
  <p id="zf3g">Как понять, к какому именно переключателю подведена каждая лампочка, если в первую комнату позволяется войти всего один раз, но переключатели можно нажимать сколько захочется?</p>
  <h2 id="LW7j">№2. Сколько лет мальчику?</h2>
  <p id="hXXR">Во время обилечивания пассажира кондуктор спросил, сколько лет его сыну. Но мужчина ответил следующее:</p>
  <p id="7xSa">– Мой сын в 5 раз старше моей дочери и младше моей жены в 5 раз. Моя жена в 2 раза младше меня, а бабушке моих детей сегодня исполнился 81 год – это столько лет, сколько мне, дочке, сыну и моей жене всего вместе.</p>
  <p id="Qj6X"><strong>Вопрос:</strong> Сколько мальчику лет?</p>
  <h2 id="6Ao5">№3. Как найти нужную баночку?</h2>
  <p id="sRRF">Всего имеется 20 баночек с таблетками. Во всех, кроме единственной, каждая таблетка весит по 1 гр, но в одной – по 1,1 гр. Мы имеем кухонные весы, которые способны просчитать все до грамма.</p>
  <p id="GjT9"><strong>Вопрос:</strong> Как найти ту самую баночку, где каждая таблетка весит по 1,1 гр, если взвесить разрешено лишь 1 раз?</p>
  <h2 id="r70s">№4. Набираем воду</h2>
  <p id="n95N">Есть 2 ведра – одно на 5 л, а второе – на 9 л. Из реки требуется набрать 3 литра воды.</p>
  <p id="2r8m"><strong>Вопрос:</strong> Как это можно сделать, если мы можем воспользоваться только этими двумя ведрами.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/JJgrVeQw8PM</guid><link>https://teletype.in/@it_guru/JJgrVeQw8PM?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/JJgrVeQw8PM?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>Какую программу выбрать для создания игры?  </title><pubDate>Tue, 30 May 2023 12:43:18 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/99/35/9935de07-780a-4d03-95ad-5d0ec393f27b.png"></media:content><description><![CDATA[<img src="https://img2.teletype.in/files/98/9e/989ea820-9cfc-44c2-bd8c-f08a96d1e2fa.jpeg"></img>Все что связано с созданием игр очень интересно и привлекательно, особенно для геймеров. Кто из любителей поиграть в какую-то интересную игру с закрученным сюжетом не хотел бы реализовать собственную?]]></description><content:encoded><![CDATA[
  <p id="HlCE">Все что связано с созданием игр очень интересно и привлекательно, особенно для геймеров. Кто из любителей поиграть в какую-то интересную игру с закрученным сюжетом не хотел бы реализовать собственную?</p>
  <p id="v11G">Всегда кажется, что “у меня получилось бы лучше”, но на практике многие так и не начинают свой путь. А зря! Игровая индустрия – это огромные инвестиции и деньги. А если есть еще и личная мотивация создать свою собственную игру, процесс обучения и реализации задуманного будет гораздо быстрее и проще. Давайте рассмотрим 5 движков, с помощью которых можно воплотить в жизнь все свои идеи.</p>
  <h2 id="qWEa">Unreal Engine Или Unity: Битва Титанов</h2>
  <p id="QWAE">Сегодня в мире гейм индустрии есть две самые главные компании, которые занимают львиную долю рынка и уже долго конкурируют друг с другом, чтобы заработать любовь, как можно большего количества людей. Это Unity и Unreal Engine. Про них слышали даже те, кто никогда не был частью сферы игр. За время своего существования они полюбились миллионам, а игры, созданные с их помощью, стали настоящими хитами.</p>
  <figure id="pROj" class="m_original">
    <img src="https://img2.teletype.in/files/98/9e/989ea820-9cfc-44c2-bd8c-f08a96d1e2fa.jpeg" width="1003" />
  </figure>
  <h2 id="POM8"><a href="https://itproger.com/course/unreal-engine" target="_blank">Unreal Engine</a>: Надежный и Технологичный</h2>
  <p id="Nclc">Unreal Engine — это мощный игровой движок, принадлежащий компании Epic Games. В 2014 году был признан самым успешным игровым движком. У него очень много наград, а общий успех спокойно можно заносить в книгу рекордов Гиннеса. Несмотря на то, что создан был Unreal Engine еще в 1998 году, он опережает многие технологии и постоянно стремится к расширению функциональности.</p>
  <p id="Z3pH">Unreal Engine славится своей впечатляющей графикой и рендерингом. Он обладает высокой степенью реалистичности и производительности, благодаря использованию мощного графического движка, известного как Unreal Engine 4.</p>
  <figure id="8E3G" class="m_original">
    <img src="https://img3.teletype.in/files/20/2d/202d34a8-2b1b-4ee0-8a4f-1915b3c0dea3.jpeg" width="1125" />
  </figure>
  <p id="9nlT">Движок позволяет использовать игры для различных платформ, включая ПК, консоли, мобильные устройства и даже виртуальную реальность. Но для мобильных игр и VR его применение не всегда позволяет добиться желаемых результатов.</p>
  <p id="D5r1">Что же касается технологичности, у UE имеется визуальная система программирования под названием Blueprints, которая позволяет разработчикам создавать игровую логику без необходимости писать код. Это крайне полезно для тех, кто не имеет опыта в программировании, но все же хочет создавать свои игры.</p>
  <p id="3e5a">Unreal Engine предоставляет все необходимые инструменты и ресурсы для создания игр любого жанра и масштаба, от небольших инди-проектов до крупных 2D и 3D игр. Движок был использован даже в кинематографе и очень ценится везде, где нужна качественная графика и эффекты. Он сочетает в себе комплексную разработку (IDE), которая насчитывает широкий спектр инструментов для разработки игр, включая редактор уровней, редактор материалов, средства моделирования и оформления, а также многое другое. Поэтому не удивительно, что Unreal Engine обожаем множеством разработчиков по всему миру.</p>
  <h2 id="J8Ya"><a href="https://itproger.com/course/unity-3d" target="_blank">Unity</a>: Перспективный и Мобильный</h2>
  <p id="BnqJ">Unity – это многоплатформенный игровой движок, разработанный компанией Unity Technologies в 2005 году. И хотя изначально его создавали для работы на Mac OS X, сегодня его применяют на 30 различных платформах. И если UE для мобильных игр подходит, но не очень, то Unity – это незаменимый гуру мобильной разработки.</p>
  <p id="WDJH">Движок имеет интуитивно понятный интерфейс и простоту в освоении. Поэтому изучить его не составит труда. У него также есть большой магазин ассетов (Asset Store), где разработчики могут приобретать готовые модели, текстуры, аудио файлы и другие ресурсы для использования в своих проектах, что значительно сокращает время разработки и повышает производительность. Всего доступно порядка 15 000 бесплатных и платных ассетов.</p>
  <p id="ahgM">Unity поддерживает один языков программирования – C#, который необходим разработчикам для создания игровой логики.</p>
  <figure id="y6Sa" class="m_original">
    <img src="https://img2.teletype.in/files/99/2d/992d1393-4ec2-4dca-a424-f06d9f9fcad4.jpeg" width="1125" />
  </figure>
  <p id="bZvw">В движке есть все инструменты и ресурсы для создания игр различных жанров, от 2D-платформ до 3D-шутеров, а также поддерживает разработку игр с использованием дополненной реальности. В VR он также преуспел, поэтому активно используется в этих целях разными компаниями.</p>
  <h2 id="p9GR"><a href="https://itproger.com/course/godot" target="_blank">Godot Engine</a>: Дружелюбный и Функциональный</h2>
  <p id="SBmA">Godot Engine – это бесплатный движок с открытым исходным кодом, выпущенный в 2014 году. Он поддерживает различные платформы, включая ПК, мобильные устройства (Android и iOS), консоли, веб, а также имеет версию Raspberry Pi. Это означает, что вы можете создавать игры для различных платформ и устройств без необходимости переписывать код с нуля.</p>
  <p id="WGcC">Godot Engine доступен бесплатно для скачивания и использования, поэтому вы можете получить полный доступ к исходному коду движка. С его помощью можно реализовывать 2D и 3D игры, при этом взаимодействуя с нужными инструментами для работы с графикой, анимацией, физикой, звуком и другими аспектами игрового процесса. А благодаря интуитивно понятному интерфейсу и простоте использования, движок освоит даже новичок. Он предлагает простую систему узла и сцены, которые позволяют легко управлять играми и создавать сложные игровые механики.</p>
  <figure id="vGyW" class="m_original">
    <img src="https://itproger.com/img/news/1591880111.jpg" width="1500" />
  </figure>
  <p id="PET6">Этот движок предоставляет множество готовых модулей и функций. Все они помогают реализовывать различные игровые механики, эффекты, системы физики, искусственный интеллект и многое другое. Godot Engine также поддерживает скрипты на нескольких языках, включая GDScript (язык, созданный разработчиками Godot), C#, Python и VisualScript.</p>
  <p id="Bc4W">Кроме того, движок очень дружелюбный. У него есть активное сообщество, где каждый сможет получить поддержку, задать вопросы и получить ответы.</p>
  <h2 id="9cas"><a href="https://itproger.com/course/gamemaker-rpg" target="_blank">GameMaker Studio</a>: Удобный и Дорогой</h2>
  <p id="KdNf">GameMaker Studio (GMS) — это объединенная среда разработки (IDE) и игровой движок, созданные компанией YoYo Games. Несмотря на понятный интерфейс и свой простой язык программирования, что делает его хорошим выбором для новичков в разработке игр, он значительно отстает от других движков. Так, для 3D игр его использовать нельзя, а кроссплатформенность открывает доступ далеко не ко всем устройствам.</p>
  <p id="tRVW">Но! GMS – это отличный движок для реализации проектов в 2D графике, особенно в инди-сегменте. Он использует расширенные инструменты для создания анимации, коллизий, уровней и других элементов игры. Их собственный язык программирования GameMaker дает возможность разработчикам контролировать логику игры и создавать собственные функции и классы.</p>
  <figure id="Xu2H" class="m_original">
    <img src="https://itproger.com/img/courses/1505555017.jpg" width="425" />
  </figure>
  <p id="4PQn">Для инди-игр не удасться найти движка лучше, чем GameMaker Studio. А еще движок предлагает визуальную систему программирования, называемую Drag and Drop, которая позволяет разработчикам создавать игровую логику, перетаскивая и соединяя готовые блоки. Простые игры можно разрабатывать без необходимости написания кода. А также можно учить язык программирования прямо во время создания игр, ведь множество кусков кода уже написаны.</p>
  <h2 id="t27v">CryEngine: Мощный и “Живой”</h2>
  <p id="Vqyp">CryEngine – это мощный игровой движок, принадлежащий немецкой компании Crytek и созданный в 2002 году. Многие знают его по первой игре – Far Cry. Он известен своим фотореалистичной графикой. Все, что связано с графическими эффектами – это нечто. Он поддерживает реалистичное освещение, теневые эффекты, отражение, анимацию, физику и другие визуальные элементы. У него имеется собственный движок, который создает реалистичную симуляцию физических эффектов, включая коллизии, разрушения, взрывы и т. д. А с помощью интересного пользовательского интерфейса, можно осуществить редактирование ландшафта, размещение объектов, управление освещением и другие функции.</p>
  <figure id="Ngct" class="m_original">
    <img src="https://itproger.com/img/news/1683962731.jpg" width="1920" />
  </figure>
  <p id="I3yA">Для работы потребуются знания С++, довольно мощный ПК и некоторое время для детального ознакомления с CryEngine. Как результат, вы получите крутую игру с “живой” графикой.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/dqxi4mk7rlt</guid><link>https://teletype.in/@it_guru/dqxi4mk7rlt?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/dqxi4mk7rlt?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>Как обучить ChatGPT на личных данных</title><pubDate>Tue, 30 May 2023 10:50:32 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/6e/95/6e952952-dc49-419c-b0dd-6bac33369f87.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2023/05/ac8db18d-a310-4700-802b-fbb3fadf8906.png"></img>В этой статье мы поговорим об архитектуре LLM и требованиях к данным для создания «частного ChatGPT», который использует ваши собственные данные. Мы изучим преимущества этой технологии и то, как вы можете преодолеть её ограничения.]]></description><content:encoded><![CDATA[
  <h1 id="ajlp">С появлением больших языковых моделей (LLM), таких как ChatGPT и GPT-4, многие задаются вопросом, можно ли создать частный ChatGPT, обучив модель на личных или корпоративных данных. Осуществимо ли это? Могут ли такие языковые модели предложить эти возможности?</h1>
  <p id="9HEy">В этой статье мы поговорим об архитектуре LLM и требованиях к данным для создания «частного ChatGPT», который использует ваши собственные данные. Мы изучим преимущества этой технологии и то, как вы можете преодолеть её ограничения.</p>
  <p id="LHjz">Это перевод статьи «How to create a private ChatGPT with your own data» от автора Mick Vleeshouwer. Здесь и далее повествование ведётся от лица автора.</p>
  <p id="uBhw"><strong>Отказ от ответственности:</strong> в этой статье представлен обзор архитектурных концепций, которые не относятся к Azure, но проиллюстрированы с использованием служб Azure, поскольку я — Solution Architect в Microsoft.</p>
  <figure id="fyBo" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/ac8db18d-a310-4700-802b-fbb3fadf8906.png" width="1617" />
  </figure>
  <h2 id="JSYS">1. Недостатки тонкой настройки LLM на личных данных</h2>
  <p id="0UD4">Часто люди называют тонкую настройку (то есть обучение) хорошим решением, которое позволяет добавить собственные данные поверх уже обученной модели.</p>
  <p id="vwEy">Однако у такого подхода есть недостатки: у модели могут быть сбои в ответах, она может выдавать нерелевантную запросу информацию. У GPT-4 такое явление назвали <a href="https://openai.com/research/gpt-4" target="_blank">риском галлюцинаций</a>. Всё потому, что GPT-4 обучался только на данных до сентября 2021 года.</p>
  <p id="E2HN">Недостатки при тонкой настройке LLM:</p>
  <ol id="hvpK">
    <li id="ffPW">Можно отследить, из какого датасета берется ответ.</li>
    <li id="B1lN">Нельзя ограничить доступ к документам с информацией для отдельных пользователей.</li>
    <li id="1NaT">Добавление новой информации для LLM требует переобучения модели.</li>
  </ol>
  <p id="4anG">Эти проблему делают почти невозможным использование тонкой настройки для персональных ответов на вопросы.</p>
  <p id="Me7A">Как преодолеть ограничения и по-прежнему получать выгоду от LLM?</p>
  <h2 id="liCq">2. Отделите свои знания от вашей языковой модели</h2>
  <p id="A8Y2">Чтобы пользователи получали точные ответы, нам нужно отделить нашу языковую модель от нашей базы знаний. Это позволит пользователям получать наиболее актуальную информацию. Отделить данные можно в режиме реального времени, и обучение модели не требуется.</p>
  <p id="h3KV">Будет хорошей идеей передавать все документы в модель во время выполнения. Однако это сложно сделать из-за ограничения количества символов (<a href="https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them" target="_blank">измеряемого в токенах</a>), которые могут быть обработаны за один раз.</p>
  <p id="eNOA">Например, GPT-3 поддерживает токены до 4 КБ, GPT-4 — до 8 КБ или 32 КБ. Поскольку цены указаны за 1000 токенов, использование меньшего количества токенов также может помочь сократить расходы.</p>
  <p id="kI3n">Вот, каким будет алгоритм:</p>
  <ol id="fweS">
    <li id="4EA5">Пользователь задает вопрос.</li>
    <li id="xOL0">Приложение находит наиболее релевантный текст, который (скорее всего) содержит ответ.</li>
    <li id="V9ni">LLM отправляется краткая подсказка с соответствующим текстом документа.</li>
    <li id="xLLR">Пользователь получит ответ или ответ «Ответ не найден».</li>
  </ol>
  <figure id="Wt0L" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/502004a6-620a-4bdc-8995-ad3f10310514.png" width="2406" />
  </figure>
  <p id="SzDj">Этот подход часто называют обоснованием модели. Мы предоставим дополнительный контекст для LLM, чтобы она отвечала на вопросы на основе соответствующих ресурсов.</p>
  <h2 id="muKe">3. Получите наиболее релевантные данные</h2>
  <p id="sKPa">Контекст — это ключевой аспект в настройке.</p>
  <p id="EQHE">Чтобы гарантировать, что языковая модель использует нужную информацию, нам необходимо создать базу данных, которую можно использовать для поиска релевантных документов с помощью семантического поиска.</p>
  <p id="1sih">Так мы предоставим языковой модели правильный контекст, и она сможет генерировать правильный ответ.</p>
  <h3 id="7r2u">3.1 Разбивайте и разделяйте данные</h3>
  <p id="UvSU">Поскольку в подсказке для ответа есть ограничение на токены, нам нужно дробить наши документы на более мелкие куски.</p>
  <p id="ShiF">Можно начать <a href="https://python.langchain.com/en/latest/reference/modules/text_splitter.html" target="_blank">с простого разделения документа на страницы</a>, чтобы текст страницы был равен длине токена.</p>
  <p id="AuKG">После этого нужно создать поисковые индексы для фрагментов текста, которые можно запрашивать с вопросом пользователя.</p>
  <p id="D7DI"><strong>Вариант 1: Используйте поисковый продукт</strong></p>
  <p id="Fe3v">Самый простой способ создать индекс семантического поиска — использовать существующую платформу «Поиск как услуга».</p>
  <p id="3TF6">Например, в Azure можно использовать Cognitive Search, который предлагает управляемый конвейер приема документов и <a href="https://learn.microsoft.com/en-us/azure/search/semantic-ranking" target="_blank">семантическое ранжирование</a> с использованием языковых моделей Bing.</p>
  <p id="7cL7"><strong>Вариант 2: Используйте вложения для создания собственного семантического поиска</strong></p>
  <p id="se0v">Вложение — это вектор (список) чисел с плавающей запятой. <a href="https://platform.openai.com/docs/guides/embeddings/which-distance-function-should-i-use" target="_blank">Расстояние между двумя векторами</a>измеряет их родство. Небольшие расстояния предполагают высокое родство, а большие расстояния предполагают низкое родство.</p>
  <p id="Bgng">Если вы хотите использовать новейшие семантические модели и лучше контролировать свой поисковый индекс, вы можете использовать модели встраивания текста от OpenAI. Для всех ваших разделов вам нужно будет предварительно вычислить вложения и сохранить их.</p>
  <p id="BYzl">В Azure можно хранить вложения в управляемой векторной базе данных, такой как Azure Cache для Redis (RediSearch), или в векторной базе данных с открытым исходным кодом, такой как Weaviate или Pinecone.</p>
  <p id="2ZLC">Во время работы приложения вы должны превратить вопрос пользователя во вложение, чтобы сравнить косинусное сходство встраивания вопроса с вложениями документов.</p>
  <figure id="ABBf" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/2ad91910-3f8a-4cc5-b2cf-bca8d0a24fe3.png" width="3248" />
  </figure>
  <h3 id="DJM4">3.2 Повышение релевантности с помощью различных стратегий фрагментации</h3>
  <p id="Jsd0">Чтобы находить наиболее актуальную информацию, важно, чтобы вы понимали свои данные и потенциальные запросы пользователей. Это знание поможет понять, как лучше всего разделить данные на фрагменты.</p>
  <p id="Ej6X"><strong>Общие шаблоны, которые могут улучшить релевантность:</strong></p>
  <ol id="PQmn">
    <li id="ucnR">Фрагментация по странице или по токену может привести к потере контекста. Используйте связанный друг с другом контент во фрагментах, чтобы увеличить выдачу наиболее релевантной информации.</li>
    <li id="OJZm">Обеспечьте больше контекста. Создайте очень структурированный документ с разделами, вложенными в несколько уровней (например, с разделами вида 1.3.3.7). Такой подход будет удачным, поскольку он даёт дополнительный контекст вроде названия главы и раздела.</li>
    <li id="535a">Создайте фрагменты с кратким содержанием более крупного раздела документа. Это позволит включить в ответ самый важный текст и объединить всю информацию в один блок.</li>
  </ol>
  <h2 id="pSnJ">4. Пишите краткие промпты, чтобы избежать галлюцинаций</h2>
  <p id="MfLp"><a href="https://platform.openai.com/docs/guides/completion/prompt-design" target="_blank">Разработка промптов</a> — это то, как вы «программируете» модель, обычно предоставляя ей инструкции в промпте или несколько примеров.</p>
  <p id="hHGz">Промпт — это важная часть в работе с ChatGPT для предотвращения нежелательных ответов. Сегодня создание промптов считается новым навыком, и каждую неделю публикуется все больше и больше примеров промптов.</p>
  <p id="SdO0">В промптах вы должны четко указать, что модель должна быть краткой в ответе и использовать только данные из релевантного контекста.</p>
  <p id="ZdNn">Если модель не может ответить на вопрос, она должна дать предопределенный ответ «нет ответа».</p>
  <p id="6oOf">Выходные данные должны включать сноску (цитаты) к исходному документу, чтобы пользователь мог проверить его фактическую точность, просмотрев источник.</p>
  <p id="IMlp"><strong>Пример промпта:</strong></p>
  <pre id="PyKv">&quot;You are an intelligent assistant helping Contoso Inc employees with their healthcare plan questions and employee handbook questions. &quot; + \
&quot;Use &#x27;you&#x27; to refer to the individual asking the questions even if they ask with &#x27;I&#x27;. &quot; + \
&quot;Answer the following question using only the data provided in the sources below. &quot; + \
&quot;For tabular information return it as an html table. Do not return markdown format. &quot;  + \
&quot;Each source has a name followed by colon and the actual information, always include the source name for each fact you use in the response. &quot; + \
&quot;If you cannot answer using the sources below, say you don&#x27;t know. &quot; + \
&quot;&quot;&quot;
###
Question: &#x27;What is the deductible for the employee plan for a visit to Overlake in Bellevue?&#x27;
Sources:
info1.txt: deductibles depend on whether you are in-network or out-of-network. In-network deductibles are $500 for employee and $1000 for family. Out-of-network deductibles are $1000 for employee and $2000 for family.
info2.pdf: Overlake is in-network for the employee plan.
info3.pdf: Overlake is the name of the area that includes a park and ride near Bellevue.
info4.pdf: In-network institutions include Overlake, Swedish and others in the region
Answer:
In-network deductibles are $500 for employee and $1000 for family [info1.txt] and Overlake is in-network for the employee plan [info2.pdf][info4.pdf].
###
Question: &#x27;{q}&#x27;?
Sources:
{retrieved}
Answer:
&quot;&quot;&quot;</pre>
  <p id="h5R3">Такое обучение модели нужно для улучшения качества ответов. Мы предоставляем модели пример того, как нужно обрабатывать вопрос пользователя. Также мы предоставляем источники с уникальным идентификатором и пример ответа, который состоит из текста из нескольких источников.</p>
  <p id="nQas">Во время выполнения <code>{q}</code>превратится в вопрос пользователя, а <code>{retrieved}</code> будет заполнен соответствующими разделами из БД для запроса.</p>
  <p id="fyUp">Не забудьте установить низкую температуру в ваших параметрах, если вы хотите получать предсказуемые ответы. Повышение температуры приведет к более неожиданным или творческим ответам.</p>
  <p id="A539">Этот промпт используется для создания ответа через (Azure) OpenAI API.</p>
  <p id="x3F2">Если вы используете gpt-35-turbo (ChatGPT), можно сохранять историю разговора, чтобы была возможность задавать уточняющие вопросы или другие логические задачи (например, резюмирование ответа).</p>
  <p id="TY3b">Отличный ресурс, чтобы узнать больше о проектировании промптов — это <a href="https://github.com/dair-ai/Prompt-Engineering-Guide" target="_blank">dair-ai/Prompt-Engineering-Guide</a> на GitHub.</p>
  <figure id="JbvN" class="m_custom">
    <img src="https://i.ytimg.com/vi_webp/E5g20qmeKpg/maxresdefault.jpg" width="120" />
  </figure>
  <h2 id="d8gD">5. Следующие шаги</h2>
  <p id="guap">В этой статье я обсудил архитектуру и паттерны проектирования, необходимые для реализации личной языковой модели, не вдаваясь в особенности кода.</p>
  <p id="gRoa">Вот, какие проекты вы можете изучить для вдохновения, чтобы приступить к созданию индивидуальной модели.</p>
  <ol id="D9W5">
    <li id="WOV4"><a href="https://github.com/openai/chatgpt-retrieval-plugin" target="_blank">Плагин извлечения ChatGPT</a>, позволяющий ChatGPT получать доступ к актуальной информации. На данный момент плагин поддерживает только общедоступный ChatGPT, но мы надеемся, что в будущем возможность добавления плагинов будет добавлена в ChatGPT API (OpenAI + Azure).</li>
    <li id="xe4D"><a href="https://github.com/hwchase17/langchain" target="_blank">LangChain</a>, популярная библиотека для объединения LLM и других источников знаний.</li>
    <li id="LcjR"><a href="https://github.com/Azure-Samples/azure-search-openai-demo" target="_blank">Azure Cognitive Search + OpenAI accelerator</a> для работы с личными данными. Он аналогичен ChatGPT и готов к развертыванию.</li>
    <li id="crxr"><a href="https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb" target="_blank">OpenAI Cookbook</a>, пример того, как использовать вложения OpenAI для вопросов и ответов в Jupyter (инфраструктура не требуется).</li>
    <li id="NXNG"><a href="https://devblogs.microsoft.com/semantic-kernel/hello-world/" target="_blank">Semantic Kernel</a>, новая библиотека для смешивания традиционных языков программирования с LLM.</li>
  </ol>
  <p id="0Ujj">Можно улучшить «собственный ChatGPT», связав его с другими системами при помощи LangChain или Semantic Kernel. Возможности безграничны.</p>
  <h2 id="igHo">Заключение</h2>
  <p id="ooZ1">В заключение, полагаться исключительно на языковую модель для создания информационного текста — ошибка.</p>
  <p id="0UBp">Тонкая настройка модели также не поможет, так как она не даст модели никаких новых знаний и не даст вам возможности проверить ее реакцию.</p>
  <figure id="Lud8" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/3d14e3bd-8266-423a-9fde-efb53e7fce3e.png" width="3280" />
  </figure>
  <p id="x779">Чтобы создать механизм вопросов и ответов поверх LLM, отделите свою базу знаний от большой языковой модели и генерируйте ответы только на основе предоставленного контекста</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/P-hkyoujoyd</guid><link>https://teletype.in/@it_guru/P-hkyoujoyd?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/P-hkyoujoyd?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>⠀</title><pubDate>Sun, 28 May 2023 11:48:26 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/8e/08/8e08ea9e-0f10-4f6f-8eed-42bd7dd153be.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2023/05/bebba6b9-ba3e-4305-96de-92ebc347486b.png"></img>Программное обеспечение с открытым исходным кодом (OSS) — это революция в разработке ПО.]]></description><content:encoded><![CDATA[
  <h1 id="zM0K">Топ-7 лучших проектов с открытым исходным кодом на GitHub 2023</h1>
  <p id="aSRy">Программное обеспечение с открытым исходным кодом (OSS) — это революция в разработке ПО.</p>
  <p id="ZOMy">На GitHub можно найти миллионы проектов с открытым исходным кодом, но их так много, что сложно найти лучшие проекты, соответствующие вашим потребностям.</p>
  <p id="2WVG">В этой статье перечислены 7 самых быстрорастущих open-source репозиториев GitHub, о которых вам следует знать.</p>
  <h2 id="tBrG">1. RLHF + PaLM: альтернатива ChatGPT с открытым исходным кодом</h2>
  <p id="WpNi">RLHF + PaLM — это незавершенная реализация языковой модели. Она сочетает обучение с подкреплением обратной связью от человека (RLHF) и архитектуру PaLM.</p>
  <p id="S0KI">Разработчики создают версию модели, аналогичную ChatGPT, но с дополнительными преимуществами архитектуры PaLM.</p>
  <p id="llZk">К сожалению, для этого решения не предусмотрена предварительно обученная модель.</p>
  <figure id="mkty" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/bebba6b9-ba3e-4305-96de-92ebc347486b.png" width="977" />
  </figure>
  <p id="tMy9">GitHub — lucidrains/PaLM-rlhf-pytorch: Implementation of RLHF (Reinforcement Learning with Human Feedback) on top of the PaLM architecture. Basically ChatGPT but with PaLM</p>
  <p id="8WO0">github.com</p>
  <h2 id="c544">2. RATH — альтернатива Tableau с открытым исходным кодом</h2>
  <p id="II65">RATH — это новое решение, у которого одно из самых быстрорастущих сообществ на GitHub.</p>
  <p id="YZyT">Благодаря передовым технологиям, новаторскому подходу к анализу и визуализации данных RATH быстро завоевала популярность среди профессионалов.</p>
  <p id="jgEJ">Сообщество RATH быстро растет: разработчики, Data Scientists и бизнес-аналитики вносят свой вклад в развитие проекта и делятся идеями о том, как максимально использовать его потенциал.</p>
  <p id="LDcr">Являетесь вы опытным аналитиком данных или только начинаете, RATH — это обязательный инструмент для всех, кто хочет улучшить навыки анализа и визуализации данных.</p>
  <figure id="kluC" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/e04ba5d0-c1da-49aa-869b-fdabc57c5883.png" width="3018" />
  </figure>
  <p id="MQDL">GitHub — Kanaries/Rath: Next generation of automated data exploratory analysis and visualization platform.</p>
  <p id="4syp">github.com</p>
  <h2 id="pcC3">3. Gogs — альтернатива GitHub с открытым исходным кодом</h2>
  <p id="xAMW">Gogs предлагает удобный интерфейс для управления версиями Git, что делает его отличной альтернативой GitHub. У Gogs есть отслеживание проблем, пулл реквесты и вики.</p>
  <p id="6ZR5">Благодаря возможности самостоятельного размещения и настройки Gogs представляет собой гибкое и безопасное решение для совместной работы с Git.</p>
  <figure id="KFpW" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/cada477f-7482-415b-a9aa-ce12f948b571.png" width="2133" />
  </figure>
  <p id="yqzV">GitHub — gogs/gogs: Gogs is a painless self-hosted Git service</p>
  <p id="BMla">github.com</p>
  <h2 id="0ald">4. NocoDB — альтернатива AirTable с открытым исходным кодом</h2>
  <p id="1C9k">NocoDB — это гибкая и масштабируемая платформа данных, которая поддерживает SQL, NoSQL и Graph.</p>
  <p id="eq2l">У NocoDB простой, но мощный интерфейс для создания баз данных и управления ими. Также у инструмента есть обновление данных в режиме реального времени.</p>
  <p id="SPtb">NocoDB — отличная альтернатива Airtable для тех, кому нужно больше контроля и настроек для данных.</p>
  <figure id="3On9" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/7f449b8a-c382-4105-88f1-aa4bc77353d0.png" width="1174" />
  </figure>
  <p id="aHAN">GitHub — nocodb/nocodb: 🔥 🔥 🔥 Open Source Airtable Alternative</p>
  <p id="hW84">github.com</p>
  <h2 id="RD41">5. Rocket.Chat — альтернатива Slack с открытым исходным кодом</h2>
  <p id="uM8m">Rocket.Chat обеспечивает общение для команд не только текстом, но и голосовыми и видеозвонками, совместным использованием экрана и обменом файлами.</p>
  <p id="6SUA">Он обладает широкими возможностями настройки и может быть развёрнут на сервере самостоятельно или использоваться в качестве облачного решения.</p>
  <p id="NgYD">Благодаря своим мощным инструментам для совместной работы Rocket.Chat является отличной альтернативой Slack.</p>
  <figure id="vOqM" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/682127ca-b022-43c1-ad69-e2a72809b0c3.jpg" width="1838" />
  </figure>
  <p id="L1QL">GitHub — RocketChat/Rocket.Chat: The communications platform that puts data protection first.</p>
  <p id="gbEC">github.com</p>
  <h2 id="RFfs">6. Plausible Analytics — альтернатива Google Analytics</h2>
  <p id="KUST">Plausible Analytics — это безопасная аналитика, которая предоставляет подробные отчеты об активности на веб-сайте в режиме реального времени и без сбора личных данных.</p>
  <p id="ZNH7">Она также предлагает простой и интуитивно понятный интерфейс для отображения производительности веб-сайта.</p>
  <figure id="wi0D" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2023/05/be499f07-1624-474d-9363-3a9dad756d6f.png" width="1600" />
  </figure>
  <p id="QLgC">GitHub — plausible/analytics: Simple, open-source, lightweight (&lt; 1 KB) and privacy-friendly web analytics alternative to Google Analytics.</p>
  <p id="l0RC">github.com</p>
  <h2 id="njg1">7. Mastodon — альтернатива Твиттеру с открытым исходным кодом</h2>
  <p id="clAe">Mastodon — это альтернатива централизованным социальным сетям, таким как Twitter.</p>
  <p id="zepe">Это децентрализованная сеть серверов, которая позволяет пользователям общаться друг с другом, обмениваться контентом и участвовать в онлайн-сообществах.</p>
  <p id="Pele">Она предлагает многие из тех же функций, что и традиционные социальные сети, включая возможность публиковать обновления, обмениваться изображениями и видео, а также взаимодействовать с другими пользователями через лайки, комментарии и репосты.</p>
  <p id="JeHi">Mastodon уделяет большое внимание конфиденциальности, свободе слова и контролю над своей личностью в Интернете, что делает его популярным среди пользователей, которые ценят эти принципы.</p>
  <p id="JCnr">GitHub — mastodon/mastodon: Your self-hosted, globally interconnected microblogging community</p>
  <p id="PIcz">github.com</p>
  <h2 id="arEr">Заключение</h2>
  <p id="AMk7">Эти 7 репозиториев GitHub с открытым исходным кодом — свидетельство активного и процветающего сообщества разработчиков Open Source кода.</p>
  <p id="5Hgh">Они предлагают бесплатные альтернативы проприетарным решениям как для разработчиков или аналитиков данных, так и для бизнеса.</p>
  <p id="hYV6">Используя преимущества открытого исходного кода, эти проекты оказались надежными и эффективными решениями, поэтому они, безусловно, заслуживают изучения и поддержки.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/khV9jIIsBrY</guid><link>https://teletype.in/@it_guru/khV9jIIsBrY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/khV9jIIsBrY?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>⠀</title><pubDate>Fri, 19 May 2023 19:04:25 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/cc/0d/cc0d9cdd-abdc-46a2-bd88-84a045140366.png"></media:content><description><![CDATA[Собрали для вас несколько простых задач по JavaScript для обучения и тренировки, а также пару теоретических вопросов. Задачи расположены в порядке возрастания сложности.]]></description><content:encoded><![CDATA[
  <h2 id="eFCu">Задачи по JavaScript для начинающих.</h2>
  <p id="jkJI">Собрали для вас несколько простых задач по JavaScript для обучения и тренировки, а также пару теоретических вопросов. Задачи расположены в порядке возрастания сложности.</p>
  <p id="Cu9U">Обратите внимание, что у любой задачи по программированию может быть несколько способов решения. Чтобы посмотреть добавленный нами вариант решения, кликните по соответствующей кнопке.</p>
  <h2 id="qzHt">Задача 1</h2>
  <p id="GIZv">Напишите однострочное решение, которое вычисляет сумму квадратных корней для всех чётных чисел целочисленного массива.</p>
  <p id="zT9Q">Вариант решения:</p>
  <pre id="ZY00">console.log(
 // Входной массив
 [1, 4, 3, 0, 4, 5, 4]
   // Оставляем только чётные числа
   .filter(element =&gt; !(element % 2))
   // Считаем квадратный корень и записываем в аккумулятор
   .reduceRight((accumulator, element) =&gt; accumulator + Math.sqrt(element), 0)
); // 6</pre>
  <p id="YHcJ">Метод <code>reduceRight()</code> применяет функцию к аккумулятору и каждому значению массива (справа налево), сводя его к одному значению. А метод <code>reduce()</code> выполняет функцию <code>callback</code> один раз для каждого элемента, присутствующего в массиве, за исключением пустот, принимая четыре аргумента:</p>
  <ul id="ewYV">
    <li id="NyOx">начальное значение (или значение от предыдущего вызова <code>callback</code>);</li>
    <li id="dz2J">значение текущего элемента;</li>
    <li id="iMOL">текущий индекс;</li>
    <li id="Ogrq">массив, по которому происходит итерация.</li>
  </ul>
  <h2 id="KAjB">Задача 2</h2>
  <p id="Q2Nd">Напишите функцию, которая пишет в консоль число в заданном диапазоне, в случае, если оно успешно делится или не делится с остатком или без остатка в зависимости от параметров.</p>
  <p id="mNhZ">Вариант решения:</p>
  <pre id="qmeL">function getNumbersModulatordBy(modulus, loggerCallback) {
 // Функция, которая возвращает функцию - это подход из функционального программирования
 // Называется замыканием (Closure)
 return function(start, end) {
   loggerCallback({ message: &quot;Конфигурация&quot;, config: configuration });
   loggerCallback({ message: &quot;Полученный модулятор&quot;, modulus: modulus });
   loggerCallback({
     message: &quot;Полученный start и end&quot;,
     start: start,
     end: end
   });

   while (start &lt;= end) {
     // Стоит обратить внимание:
     // 1. При нестрогом равенстве true == 1 и false == 0
     // 2. Здесь мы обращаемся к глобальному контексту configuration
     // p.s. поле isEntry может меняться
     if (start % modulus == configuration.isEntry) {
       // В данном случае мы используем loggerCallback как middleware
       // Это определит дальнейшую судьбу результата
       // Позволяет убрать side-effect
       loggerCallback(start);
     }
     start++;
   }
 };
}

// Глобальный контекст не имеет блочной видимости
// В данном случае переменная поднимается выше в самое начало кода
// Исполнитель JavaScript видит её в независимости от места инициализации
var configuration = {
 modulus: 10,
 isEntry: false,
 start: 45,
 end: 68
};

var loggerCallback = data =&gt; console.log(data);

let tenNumbersModulator = getNumbersModulatordBy(
 configuration.modulus,
 loggerCallback
);

// Переменные с глобальным контекстом доступны из:
// 1. globalThis (в Node.js)
// 2. window (в браузере)
window.configuration.modulus = 5;

let fiveNumbersModulator = getNumbersModulatordBy(
 configuration.modulus,
 loggerCallback
);

tenNumbersModulator(configuration.start, configuration.end); // 50, 60
tenNumbersModulator(10, 100); // 10, 20, 30, 40, 50, 60, 70, 80, 90, 100

// Так как мы изменили поле isEntry, то теперь:
// Функция вернёт те значения, которые не входят в модуляцию числа
window.configuration.isEntry = true;

fiveNumbersModulator(configuration.start, configuration.end); // 46, 51, 56, 61, 66
fiveNumbersModulator(10, 21); // 11, 16, 21</pre>
  <h2 id="56u1">Задача 3</h2>
  <p id="QBXg">Есть ферма животных, у всех животных есть имена и возраст. Животные бывают разных типов: Кошки, Собаки, Коровы. У каждого животного могут быть дети. Если животное является родителем этих детей, в свою очередь глубина семейного древа может достигать <code>N</code>либо <code>0</code>.</p>
  <p id="YZz8">Опишите структуры данных для фермы животных и напишите функцию, которая делает подсчёт всех возрастов животных и выводит общий возраст для всей фермы.</p>
  <p id="e1Yr">Вариант решения:</p>
  <pre id="qo4n">// Родительский класс для всех животных
class Animal {
 constructor(name, age, childs = null) {
   this.name = name;
   this.age = age;
   this.childs = childs;
 }
}

// Класс Cat - потомок класса Animal
// Имеет те же поля, что и Animal
class Cat extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Класс Dog - потомок класса Animal
// Имеет те же поля, что и Animal
class Dog extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Класс Cow - потомок класса Animal
// Имеет те же поля, что и Animal
class Cow extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Рекурсивная функция для подсчета age
// Обходит все дочерние элементы
function getAnimalsAge(animals) {
 let output = 0;

 if (animals.length &gt; 0) {
   // Использование функции reduce для получения общего age
   // https://learn.javascript.ru/array-iteration
   output += animals.reduce((acc, current) =&gt; {
     // Сумма age всех childs
     let count = 0;
     // Если childs пустой или его нет, тогда нет смысла пробегать по ним
     if (current.childs &amp;&amp; current.childs.length &gt; 0) {
       // Применение рекурсии
       count += getAnimalsAge(current.childs);
     }

     // Возвращаем сумму аккумулятора, текущего животного, сумму age всех childs
     return acc + current.age + count;
   }, 0);
 }

 return output;
}

// Функция для получения определённого количества животных
function generateAnimals(type, count) {
 let output = [];

 for (let i = 0; i &lt;= count; i++) {
   let parameter = {
     name: &#x60;${type} ${i}&#x60;,
     age: i,
     childs: []
   };

   let item = null;

   switch (type) {
     case &quot;Cat&quot;:
       item = new Cat(parameter.name, parameter.age);
       break;
     case &quot;Dog&quot;:
       item = new Dog(parameter.name, parameter.age);
       break;
     case &quot;Cow&quot;:
       item = new Cow(parameter.name, parameter.age);
       break;
   }

   if (item) {
     output.push(item);
   }
 }

 return output;
}

// Добавление childs ко всем переданным животным
function addChildsTo(animals, count, type) {
 animals.forEach(animal =&gt; {
   if (!animal.childs) {
     animal.childs = [];
   }
   // Обратите внимание, что массив - ссылка, поэтому изменяя здесь его поля
   // мы меняем их глобально
   animal.childs = generateAnimals(type, count);
 });
}

let cats = generateAnimals(&quot;Cat&quot;, 5);
addChildsTo(cats, 10, &quot;Cat&quot;);

let dogs = generateAnimals(&quot;Dog&quot;, 3);
addChildsTo(dogs, 3, &quot;Dog&quot;);

let cows = generateAnimals(&quot;Cow&quot;, 7);
addChildsTo(cows, 1, &quot;Dog&quot;);

// Использование оператора Spread (ES6)
// https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax
let animals = [...cats, ...dogs, ...cows];

console.log(getAnimalsAge(animals)) // 411</pre>
  <h2 id="xsFr">Задача 4</h2>
  <p id="ukgS">Перепишите функцию <code>clone</code> таким образом, чтобы она была способна клонировать переданный как параметр объект.</p>
  <p id="XKa1">Пример проблемы:</p>
  <pre id="wsae">let animal = {
 name: &quot;animal&quot;,
 age: 10,
 childs: [&quot;child 1&quot;, &quot;child 2&quot;]
};

let cat = clone(animal);
cat.name = &quot;cat&quot;;
cat.age = 5;
cat.childs.push(&quot;child 3&quot;);

console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // cat 5
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

function clone(obj) {
 return obj;
}</pre>
  <p id="6KLy">Варианты решения:</p>
  <h3 id="3DrA">Deep copy (глубокое копирование)</h3>
  <pre id="Dc6P">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27; ]

// Отличный вариант для JSON-safe объектов
let clone = (obj) =&gt; JSON.parse(JSON.stringify(obj));

// Опасен для рекурсивных объектов или когда имеется конструктор с параметрами
let clone = obj =&gt; {
 if (obj === null || typeof obj !== &quot;object&quot; || &quot;isActiveClone&quot; in obj)
   return obj;

 if (obj instanceof Date) var temp = new obj.constructor();
 //or new Date(obj);
 else var temp = obj.constructor();

 for (var key in obj) {
   if (Object.prototype.hasOwnProperty.call(obj, key)) {
     obj[&quot;isActiveClone&quot;] = null;
     temp[key] = clone(obj[key]);
     delete obj[&quot;isActiveClone&quot;];
   }
 }
 return temp;
};</pre>
  <h3 id="vc3b">Experimental deep copy (экспериментальное глубокое копирование)</h3>
  <p id="ZCrH">Как <a href="https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/10916838#10916838" target="_blank">пишут</a> на Stack Overflow, HTML-стандарт включает в себя <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm" target="_blank">алгоритм структурированного клонирования</a>, который может создавать глубокие копии объектов. Он всё ещё ограничен встроенными типами, но в дополнение к тем типам, что поддерживаются в JSON, поддерживает Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, Sparse Arrays, Typed Arrays и, вероятно, больше в будущем. Решает также проблемы цикличных и рекурсивных структур, которые ломают JSON.</p>
  <pre id="7Hrk">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27; ]

let clone = (obj) =&gt; require(&quot;v8&quot;).deserialize(require(&quot;v8&quot;).serialize(obj));</pre>
  <h3 id="4hND">Shallow copy (поверхностное копирование)</h3>
  <p id="pO7V">Клонирование вложенных свойств по ссылке пропускается, нужно быть осторожным в использовании.</p>
  <pre id="hTHj">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

// Копирует значение всех собственных итерируемых элементов объекта
let clone = (obj) =&gt; Object.assign(new Object(), obj);
// Более известен как оператор Spread
let clone = (obj) =&gt; { ...obj };</pre>
  <h2 id="GbP9">Задача 5</h2>
  <p id="7vy1">Выйдите из цикла, изменив только две отмеченные строки. Результат в консоли сейчас останавливается на <code>9 9</code>. Должен на <code>5 4</code>.</p>
  <pre id="A3NV">for (let i = 0; i &lt; 10; i++) { //! Эту строку можно изменить
 for (let j = 0; j &lt; 10; j++) {
   if (i === 5 &amp;&amp; j === 5) {
     //! Эту строку можно изменить
   }

   console.log(i, j);
 }
}</pre>
  <p id="mJVu">Вариант решения:</p>
  <p id="kNTC">Как <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/label" target="_blank">пишут</a> на MDN web docs, инструкция метки (label) используется вместе с <code>break</code> или <code>continue</code> для альтернативного выхода из цикла. Метка добавляется перед блочным выражением в качестве ссылки, которая может быть использована в дальнейшем.</p>
  <pre id="TFSN">cycle: for (let i = 0; i &lt; 10; i++) { //! Эту строку можно изменить
 for (let j = 0; j &lt; 10; j++) {
   if (i === 5 &amp;&amp; j === 5) {
     break cycle; //! Эту строку можно изменить
   }
   console.log(i, j);
 }
}</pre>
  <h2 id="etPO">Задача 6</h2>
  <p id="JkXY">Яблоко стоит 1.15, апельсин стоит 2.30. Сколько они стоят вместе – чему равна сумма 1.15 + 2.30 с точки зрения JavaScript?</p>
  <p id="o7am">Ответ:</p>
  <p id="7Iol"><code>3.4499999999999997</code></p>
  <p id="rYBH">Число хранится в памяти в бинарной форме, как последовательность бит – единиц и нулей. Но дроби, такие как 1.15, 2.30, которые выглядят довольно просто в десятичной системе счисления, на самом деле являются бесконечной дробью в двоичной форме. Это объяснение взято с сайта Современный учебник JavaScript, там же можно подробно <a href="https://learn.javascript.ru/number" target="_blank">почитать про числа в языке</a>.</p>
  <h3 id="J0Mc">Задача 7</h3>
  <p id="B4zf">Чему равен <code>typeof null</code> в режиме <code>use strict</code>?</p>
  <p id="uuWe">Ответ</p>
  <p id="lRUj"><code>object</code></p>
  <p id="LVw8">Как <a href="https://habr.com/ru/post/200664/" target="_blank">пишут</a> на Хабре:</p>
  <blockquote id="cilg">Все JavaScript-программисты давно привыкли к тому, что <code>typeof null === &#x27;object&#x27;; // true</code>, хотя фактически null — примитивное значение. Многие знают, что это баг, и лично Брэндан Айк это признаёт. Этот баг, вероятно, никогда не будет исправлен из-за необходимости сохранения обратной совместимости существующего кода с новыми версиями языка.</blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/hBXtPatgo8_</guid><link>https://teletype.in/@it_guru/hBXtPatgo8_?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/hBXtPatgo8_?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>⠀</title><pubDate>Fri, 19 May 2023 18:57:49 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/2f/97/2f978477-9bfc-4622-9dd1-8b9ca643dfb3.png"></media:content><description><![CDATA[Собрали для вас несколько простых задач по JavaScript для обучения и тренировки, а также пару теоретических вопросов. Задачи расположены в порядке возрастания сложности.]]></description><content:encoded><![CDATA[
  <h1 id="5OvM">Задачи по JavaScript для начинающих от Tproger и GeekBrains</h1>
  <p id="r8Qj"></p>
  <p id="jkJI">Собрали для вас несколько простых задач по JavaScript для обучения и тренировки, а также пару теоретических вопросов. Задачи расположены в порядке возрастания сложности.</p>
  <p id="Cu9U">Обратите внимание, что у любой задачи по программированию может быть несколько способов решения. Чтобы посмотреть добавленный нами вариант решения, кликните по соответствующей кнопке.</p>
  <h2 id="qzHt">Задача 1</h2>
  <p id="GIZv">Напишите однострочное решение, которое вычисляет сумму квадратных корней для всех чётных чисел целочисленного массива.</p>
  <p id="zT9Q">Вариант решения:</p>
  <pre id="7CiF">console.log(
 // Входной массив
 [1, 4, 3, 0, 4, 5, 4]
   // Оставляем только чётные числа
   .filter(element =&gt; !(element % 2))
   // Считаем квадратный корень и записываем в аккумулятор
   .reduceRight((accumulator, element) =&gt; accumulator + Math.sqrt(element), 0)
); // 6</pre>
  <p id="YHcJ">Метод <code>reduceRight()</code> применяет функцию к аккумулятору и каждому значению массива (справа налево), сводя его к одному значению. А метод <code>reduce()</code> выполняет функцию <code>callback</code> один раз для каждого элемента, присутствующего в массиве, за исключением пустот, принимая четыре аргумента:</p>
  <ul id="ewYV">
    <li id="NyOx">начальное значение (или значение от предыдущего вызова <code>callback</code>);</li>
    <li id="dz2J">значение текущего элемента;</li>
    <li id="iMOL">текущий индекс;</li>
    <li id="Ogrq">массив, по которому происходит итерация.</li>
  </ul>
  <h2 id="KAjB">Задача 2</h2>
  <p id="Q2Nd">Напишите функцию, которая пишет в консоль число в заданном диапазоне, в случае, если оно успешно делится или не делится с остатком или без остатка в зависимости от параметров.</p>
  <p id="mNhZ">Вариант решения:</p>
  <pre id="lbMp">function getNumbersModulatordBy(modulus, loggerCallback) {
 // Функция, которая возвращает функцию - это подход из функционального программирования
 // Называется замыканием (Closure)
 return function(start, end) {
   loggerCallback({ message: &quot;Конфигурация&quot;, config: configuration });
   loggerCallback({ message: &quot;Полученный модулятор&quot;, modulus: modulus });
   loggerCallback({
     message: &quot;Полученный start и end&quot;,
     start: start,
     end: end
   });

   while (start &lt;= end) {
     // Стоит обратить внимание:
     // 1. При нестрогом равенстве true == 1 и false == 0
     // 2. Здесь мы обращаемся к глобальному контексту configuration
     // p.s. поле isEntry может меняться
     if (start % modulus == configuration.isEntry) {
       // В данном случае мы используем loggerCallback как middleware
       // Это определит дальнейшую судьбу результата
       // Позволяет убрать side-effect
       loggerCallback(start);
     }
     start++;
   }
 };
}

// Глобальный контекст не имеет блочной видимости
// В данном случае переменная поднимается выше в самое начало кода
// Исполнитель JavaScript видит её в независимости от места инициализации
var configuration = {
 modulus: 10,
 isEntry: false,
 start: 45,
 end: 68
};

var loggerCallback = data =&gt; console.log(data);

let tenNumbersModulator = getNumbersModulatordBy(
 configuration.modulus,
 loggerCallback
);

// Переменные с глобальным контекстом доступны из:
// 1. globalThis (в Node.js)
// 2. window (в браузере)
window.configuration.modulus = 5;

let fiveNumbersModulator = getNumbersModulatordBy(
 configuration.modulus,
 loggerCallback
);

tenNumbersModulator(configuration.start, configuration.end); // 50, 60
tenNumbersModulator(10, 100); // 10, 20, 30, 40, 50, 60, 70, 80, 90, 100

// Так как мы изменили поле isEntry, то теперь:
// Функция вернёт те значения, которые не входят в модуляцию числа
window.configuration.isEntry = true;

fiveNumbersModulator(configuration.start, configuration.end); // 46, 51, 56, 61, 66
fiveNumbersModulator(10, 21); // 11, 16, 21</pre>
  <h2 id="56u1">Задача 3</h2>
  <p id="QBXg">Есть ферма животных, у всех животных есть имена и возраст. Животные бывают разных типов: Кошки, Собаки, Коровы. У каждого животного могут быть дети. Если животное является родителем этих детей, в свою очередь глубина семейного древа может достигать <code>N</code>либо <code>0</code>.</p>
  <p id="YZz8">Опишите структуры данных для фермы животных и напишите функцию, которая делает подсчёт всех возрастов животных и выводит общий возраст для всей фермы.</p>
  <p id="e1Yr">Вариант решения:</p>
  <pre id="GQCy">// Родительский класс для всех животных
class Animal {
 constructor(name, age, childs = null) {
   this.name = name;
   this.age = age;
   this.childs = childs;
 }
}

// Класс Cat - потомок класса Animal
// Имеет те же поля, что и Animal
class Cat extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Класс Dog - потомок класса Animal
// Имеет те же поля, что и Animal
class Dog extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Класс Cow - потомок класса Animal
// Имеет те же поля, что и Animal
class Cow extends Animal {
 constructor(name, age, childs = null) {
   super(name, age, childs);
 }
}

// Рекурсивная функция для подсчета age
// Обходит все дочерние элементы
function getAnimalsAge(animals) {
 let output = 0;

 if (animals.length &gt; 0) {
   // Использование функции reduce для получения общего age
   // https://learn.javascript.ru/array-iteration
   output += animals.reduce((acc, current) =&gt; {
     // Сумма age всех childs
     let count = 0;
     // Если childs пустой или его нет, тогда нет смысла пробегать по ним
     if (current.childs &amp;&amp; current.childs.length &gt; 0) {
       // Применение рекурсии
       count += getAnimalsAge(current.childs);
     }

     // Возвращаем сумму аккумулятора, текущего животного, сумму age всех childs
     return acc + current.age + count;
   }, 0);
 }

 return output;
}

// Функция для получения определённого количества животных
function generateAnimals(type, count) {
 let output = [];

 for (let i = 0; i &lt;= count; i++) {
   let parameter = {
     name: &#x60;${type} ${i}&#x60;,
     age: i,
     childs: []
   };

   let item = null;

   switch (type) {
     case &quot;Cat&quot;:
       item = new Cat(parameter.name, parameter.age);
       break;
     case &quot;Dog&quot;:
       item = new Dog(parameter.name, parameter.age);
       break;
     case &quot;Cow&quot;:
       item = new Cow(parameter.name, parameter.age);
       break;
   }

   if (item) {
     output.push(item);
   }
 }

 return output;
}

// Добавление childs ко всем переданным животным
function addChildsTo(animals, count, type) {
 animals.forEach(animal =&gt; {
   if (!animal.childs) {
     animal.childs = [];
   }
   // Обратите внимание, что массив - ссылка, поэтому изменяя здесь его поля
   // мы меняем их глобально
   animal.childs = generateAnimals(type, count);
 });
}

let cats = generateAnimals(&quot;Cat&quot;, 5);
addChildsTo(cats, 10, &quot;Cat&quot;);

let dogs = generateAnimals(&quot;Dog&quot;, 3);
addChildsTo(dogs, 3, &quot;Dog&quot;);

let cows = generateAnimals(&quot;Cow&quot;, 7);
addChildsTo(cows, 1, &quot;Dog&quot;);

// Использование оператора Spread (ES6)
// https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax
let animals = [...cats, ...dogs, ...cows];

console.log(getAnimalsAge(animals)) // 411</pre>
  <h2 id="xsFr">Задача 4</h2>
  <p id="ukgS">Перепишите функцию <code>clone</code> таким образом, чтобы она была способна клонировать переданный как параметр объект.</p>
  <p id="XKa1">Пример проблемы:</p>
  <pre id="JTwo">let animal = {
 name: &quot;animal&quot;,
 age: 10,
 childs: [&quot;child 1&quot;, &quot;child 2&quot;]
};

let cat = clone(animal);
cat.name = &quot;cat&quot;;
cat.age = 5;
cat.childs.push(&quot;child 3&quot;);

console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // cat 5
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

function clone(obj) {
 return obj;
}</pre>
  <p id="6KLy">Варианты решения:</p>
  <h3 id="3DrA">Deep copy (глубокое копирование)</h3>
  <pre id="xuk3">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27; ]

// Отличный вариант для JSON-safe объектов
let clone = (obj) =&gt; JSON.parse(JSON.stringify(obj));

// Опасен для рекурсивных объектов или когда имеется конструктор с параметрами
let clone = obj =&gt; {
 if (obj === null || typeof obj !== &quot;object&quot; || &quot;isActiveClone&quot; in obj)
   return obj;

 if (obj instanceof Date) var temp = new obj.constructor();
 //or new Date(obj);
 else var temp = obj.constructor();

 for (var key in obj) {
   if (Object.prototype.hasOwnProperty.call(obj, key)) {
     obj[&quot;isActiveClone&quot;] = null;
     temp[key] = clone(obj[key]);
     delete obj[&quot;isActiveClone&quot;];
   }
 }
 return temp;
};</pre>
  <h3 id="vc3b">Experimental deep copy (экспериментальное глубокое копирование)</h3>
  <p id="ZCrH">Как <a href="https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/10916838#10916838" target="_blank">пишут</a> на Stack Overflow, HTML-стандарт включает в себя <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm" target="_blank">алгоритм структурированного клонирования</a>, который может создавать глубокие копии объектов. Он всё ещё ограничен встроенными типами, но в дополнение к тем типам, что поддерживаются в JSON, поддерживает Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, Sparse Arrays, Typed Arrays и, вероятно, больше в будущем. Решает также проблемы цикличных и рекурсивных структур, которые ломают JSON.</p>
  <pre id="Bek5">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27; ]

let clone = (obj) =&gt; require(&quot;v8&quot;).deserialize(require(&quot;v8&quot;).serialize(obj));</pre>
  <h3 id="4hND">Shallow copy (поверхностное копирование)</h3>
  <p id="pO7V">Клонирование вложенных свойств по ссылке пропускается, нужно быть осторожным в использовании.</p>
  <pre id="TaOk">console.log(cat.name, cat.age); // cat 5
console.log(cat.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

console.log(animal.name, animal.age); // animal 10
console.log(animal.childs); // [ &#x27;child 1&#x27;, &#x27;child 2&#x27;, &#x27;child 3&#x27; ]

// Копирует значение всех собственных итерируемых элементов объекта
let clone = (obj) =&gt; Object.assign(new Object(), obj);
// Более известен как оператор Spread
let clone = (obj) =&gt; { ...obj };</pre>
  <h2 id="GbP9">Задача 5</h2>
  <p id="7vy1">Выйдите из цикла, изменив только две отмеченные строки. Результат в консоли сейчас останавливается на <code>9 9</code>. Должен на <code>5 4</code>.</p>
  <pre id="BOYa">for (let i = 0; i &lt; 10; i++) { //! Эту строку можно изменить
 for (let j = 0; j &lt; 10; j++) {
   if (i === 5 &amp;&amp; j === 5) {
     //! Эту строку можно изменить
   }

   console.log(i, j);
 }
}</pre>
  <p id="mJVu">Вариант решения:</p>
  <p id="kNTC">Как <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/label" target="_blank">пишут</a> на MDN web docs, инструкция метки (label) используется вместе с <code>break</code> или <code>continue</code> для альтернативного выхода из цикла. Метка добавляется перед блочным выражением в качестве ссылки, которая может быть использована в дальнейшем.</p>
  <pre id="Ucsz">cycle: for (let i = 0; i &lt; 10; i++) { //! Эту строку можно изменить
 for (let j = 0; j &lt; 10; j++) {
   if (i === 5 &amp;&amp; j === 5) {
     break cycle; //! Эту строку можно изменить
   }
   console.log(i, j);
 }
}</pre>
  <h2 id="etPO">Задача 6</h2>
  <p id="JkXY">Яблоко стоит 1.15, апельсин стоит 2.30. Сколько они стоят вместе – чему равна сумма 1.15 + 2.30 с точки зрения JavaScript?</p>
  <p id="o7am">Ответ:</p>
  <p id="7Iol"><code>3.4499999999999997</code></p>
  <p id="rYBH">Число хранится в памяти в бинарной форме, как последовательность бит – единиц и нулей. Но дроби, такие как 1.15, 2.30, которые выглядят довольно просто в десятичной системе счисления, на самом деле являются бесконечной дробью в двоичной форме. Это объяснение взято с сайта Современный учебник JavaScript, там же можно подробно <a href="https://learn.javascript.ru/number" target="_blank">почитать про числа в языке</a>.</p>
  <h3 id="J0Mc">Задача 7</h3>
  <p id="B4zf">Чему равен <code>typeof null</code> в режиме <code>use strict</code>?</p>
  <p id="uuWe">Ответ</p>
  <p id="lRUj"><code>object</code></p>
  <p id="LVw8">Как <a href="https://habr.com/ru/post/200664/" target="_blank">пишут</a> на Хабре:</p>
  <blockquote id="cilg">Все JavaScript-программисты давно привыкли к тому, что <code>typeof null === &#x27;object&#x27;; // true</code>, хотя фактически null — примитивное значение. Многие знают, что это баг, и лично Брэндан Айк это признаёт. Этот баг, вероятно, никогда не будет исправлен из-за необходимости сохранения обратной совместимости существующего кода с новыми версиями языка.</blockquote>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@it_guru/LVWmqS1POS1</guid><link>https://teletype.in/@it_guru/LVWmqS1POS1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru</link><comments>https://teletype.in/@it_guru/LVWmqS1POS1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=it_guru#comments</comments><dc:creator>it_guru</dc:creator><title>⠀</title><pubDate>Fri, 19 May 2023 18:10:38 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/26/f6/26f6b430-756f-47d9-9f6b-18007aa310ae.png"></media:content><description><![CDATA[<img src="https://media.tproger.ru/uploads/2018/02/1013270788.jpg"></img>Собранные книги по C++ позволят выучить этот непростой язык как новичкам, так и тем программистам, которые ранее изучали другие языки.]]></description><content:encoded><![CDATA[
  <h1 id="PUKV">Книги по C++: исчерпывающая подборка для начинающих</h1>
  <p id="3c7S">Собранные книги по C++ позволят выучить этот непростой язык как новичкам, так и тем программистам, которые ранее изучали другие языки.</p>
  <p id="9VMZ"></p>
  <ol id="GGkp">
    <li id="WS0S">Книги на русском</li>
    <li id="XZR4">Книги на английском</li>
  </ol>
  <h2 id="hoGb">Книги по C++ на русском</h2>
  <hr />
  <figure id="M8xE" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1013270788.jpg" width="90" />
  </figure>
  <h3 id="AJmz">Программирование. Принципы и практика с использованием C++</h3>
  <p id="ZO45">Книга написана создателем языка C++ — Бьёрном Страуструпом. Материал ориентирован в первую очередь на тех, кто не был знаком с программированием до прочтения этой книги. Она задумана как введение в разработку, а язык C++ играет, скорее, иллюстративную роль. Здесь не удастся найти информацию обо всех возможностях данного языка программирования, зато можно получить полезные советы и рекомендации для более эффективной работы с C++ от человека, который имеет бесценный опыт в программировании и огромное значение в сообществе программистов.</p>
  <p id="DyGM"></p>
  <hr />
  <figure id="Dg1G" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1011929412.jpg" width="90" />
  </figure>
  <h3 id="Trht">Язык программирования C++. Лекции и упражнения</h3>
  <p id="gOdB">Оригинал шестого издания был выпущен в далёком 2011 году, поэтому о стандартах 14/17 из этого учебника вы не узнаете. Тем не менее, это всё ещё хороший базис для начинающих. Стивен Прата вложил свой преподавательский опыт в эту книгу. В результате получился монументальный труд, который дружественно относится к читателю и понятным языком объясняет фундаментальные основы данного языка программирования.</p>
  <hr />
  <figure id="6gmW" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1013134422.jpg" width="90" />
  </figure>
  <h3 id="Q1xc">Изучаем C++ через программирование игр</h3>
  <p id="OMKy">Пусть эта книга и освещает только базовые элементы языка, её несомненный плюс в том, что она предлагает закреплять полученные знания путём создания небольших игр. В каждой главе дан определённый игровой проект, на примере которого поясняется, как можно использовать «фишки» «плюсов». Книга подойдёт и тем, кто до нее не был знаком с программированием.</p>
  <hr />
  <figure id="4cQv" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1011421957.jpg" width="90" />
  </figure>
  <h3 id="ZZsa">Объектно-ориентированное программирование в С++</h3>
  <p id="gqYb">Книга Роберта Лафоре из серии «Классика Computer Science». В ней очень грамотно и полно представлено понятие объектно-ориентированного программирования в C++. Кроме теории, книга предлагает читателю сделать около 100 различных упражнений, которые позволят отточить навык владения ООП. Отлично подходит для начинающих программистов.</p>
  <hr />
  <figure id="zmxe" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1001831979.jpg" width="90" />
  </figure>
  <h3 id="ij5w">Как программировать на C++</h3>
  <p id="pH3G">Харви и Пол Дейтелы в своей книге решили отойти от привычного порядка введения в C++ и уже с третьей главы знакомят читателя с основами ООП, тем самым не освещая должным образом структурное и процедурное программирование. Большое внимание уделяется объектно-ориентированному проектированию программных систем с помощью графического языка UML2. Данный учебник является одним из самых популярных в мире по C++.</p>
  <hr />
  <figure id="I5jV" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/cpp_stl_book.jpg" width="90" />
  </figure>
  <h3 id="dlW8">Осваиваем C++17 STL</h3>
  <p id="Xm53">Стандарт C++17 удвоил объем библиотеки по сравнению с С++11. Из книги вы узнаете об особенностях 17-го стандарта с примерами, научитесь создавать пулы потоков выполнения, диспетчеры памяти, типы итераторов. В материале рассмотрены отличия полиморфизма, мономорфизма, а также обобщённых алгоритмов. Подойдёт разработчикам, которые уже знают C++, но хотят овладеть особенностями библиотеки C++17 STL и использовать на практике её компоненты.</p>
  <hr />
  <figure id="itaZ" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1009504581.jpg" width="90" />
  </figure>
  <h3 id="yetv">Язык программирования C++. Базовый курс</h3>
  <p id="N3kW">Более тысячи страниц подробного введения в C++, которое детально покрывает буквально все аспекты языка в доступном формате. С самого начала книги читателя знакомят со стандартной библиотекой C++, её популярными функциями и средствами, что позволяет в скором времени приступить к написанию программ, даже если не были изучены некоторые нюансы языка. В книге используется стандарт С++11.</p>
  <hr />
  <figure id="Ohbf" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/cpp_tasks_book.jpg" width="90" />
  </figure>
  <h3 id="0mSv">Программирование на C++ в примерах и задачах</h3>
  <p id="8gxR">Книга включила набор сведений, необходимых для успешного анализа и составления эффективных программных кодов. Вся информация изложена последовательно и дополняется огромным количеством примеров, задач для практики, а также детальным разбором решений.</p>
  <hr />
  <figure id="ua0V" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/1014001523.jpg" width="90" />
  </figure>
  <h3 id="RPGg">Эффективное программирование на C++. Практическое программирование на примерах</h3>
  <p id="lf2k">Содержит в себе всё то же самое, что и «Учебник для начинающих: С++», но короче в 4 раза. В основном из-за того, что автор не пытается ввести читателя в программирование, а сразу учит С++ тех, кто пришел из других языков. Может быть немного сложна для понимания, но тем, кто сможет осилить курс, это ещё и здорово сократит время изучения.</p>
  <hr />
  <h2 id="gyZi">Книги по C++ на английском</h2>
  <hr />
  <figure id="MQo8" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/progcpp.jpg" width="90" />
  </figure>
  <h3 id="P5QC">Fundamentals of Programming C++</h3>
  <p id="VUZZ">Книга содержит огромное количество материала по C++ и явно стремится осветить все основные аспекты языка. В ней вы найдете информацию как о базовых элементах C++, так и об использовании библиотеки STL. Автор регулярно обновляет книгу, благодаря чему в ней представлена актуальная версия языка. Множество примеров кода и того, как работают программы, позволят закрепить пройденный материал.</p>
  <hr />
  <figure id="WV3S" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/C-Annotations.jpg" width="90" />
  </figure>
  <h3 id="EpvP">C++ Annotations</h3>
  <p id="CCuw">Книга рассчитана в первую очередь на тех, что уже знает язык Си или Си-подобный язык, например, Java. Поэтому она не рассказывает об общих моментах, которые одинаковы или, по крайней мере, похожи в таких языках, а сразу преподносит материал, присущий только C++. Поэтому если вы изучаете или уже изучили C или Java, то эта книга станет хорошим подспорьем в изучении C++. </p>
  <p id="nnPr"></p>
  <hr />
  <figure id="Vi8a" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/C-Succinctly.jpg" width="90" />
  </figure>
  <h3 id="h76D">C++ Succinctly</h3>
  <p id="W4jh">Книга написана специально для C#-разработчиков. Материал по языку C++ даётся с учётом имеющихся у программиста знаний о языке C#. Книга полезна, когда часть проекта на C++, а вы знаете C#. После изучения материала вы сможете писать полноценные программы уже на C++.</p>
  <hr />
  <figure id="3EIe" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/rooks-guide-cplusplus.jpg" width="90" />
  </figure>
  <h3 id="qrc4">The Rook&#x27;s Guide to C++</h3>
  <p id="7KTS">Данный учебник является трудом автора и его 25 студентов, большинство из которых — новички в C++. Большая часть книги была написана совместными усилиями примерно за 36 часов. Сам автор признаётся, что будь у него бесконечное количество времени, он бы отполировал книгу до блеска. Всё это сделано с целью удешевления производства книги и, как следствие, выпуска её в свободный доступ для всех желающих. В ней могут быть ошибки, но в целом в книге представлен неплохой материал по языку C++.</p>
  <hr />
  <figure id="l5YN" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/learn-c-3159805.jpg" width="90" />
  </figure>
  <h3 id="qH4j">Learn C++</h3>
  <p id="mnc3">В нашу подборку книг затесался сайт. Вы думаете, это какая-то ошибка? Вовсе нет: это онлайн-учебник по всему С++. Его несомненное преимущество в том, что каждая глава проиллюстрирована кодом, так что материал будет легче усвоить. Всё расписано достаточно подробно, но самое главное — книга регулярно дополняется в соответствии с новыми стандартами C++.</p>
  <hr />
  <figure id="3nbd" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/structured-programming-with-c-plus-plus.jpg" width="90" />
  </figure>
  <h3 id="ANrC">Structured Programming with C++</h3>
  <p id="1wvs">Книга научит основам структурного программирования. В первую очередь, она стремится донести до читателя, что такое «думать как программист», а уже во вторую — обучить языку C++. Материал представлен в удобочитаемой форме. Как и во многих учебниках, здесь есть материалы для самопроверки в каждой главе с ответами в конце. Автор подчёркивает, что материал фокусируется на решении типовых проблем и задач, возникающих в процессе написания программы.</p>
  <hr />
  <figure id="C4xh" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/brdavid6.jpg" width="90" />
  </figure>
  <h3 id="xgC9">Software Design Using C++</h3>
  <p id="BrAk">Ещё одна онлайн-книга, которая даёт материал в соответствии с тремя курсами, которые в американских университетах называются CS 1, CS 2 и «Структуры данных». Новичкам стоит начать именно с курса CS 1, поскольку в нём представлены основы программирования на C++. После переходите к курсу CS 2, а затем — к структурам данных.</p>
  <hr />
  <figure id="IWBx" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/002b0f19.jpeg" width="90" />
  </figure>
  <h3 id="pd90">How to Think Like a Computer Scientist</h3>
  <p id="85l5">Цели книги — научить использовать C++ и мыслить, как исследователь. Она делает акцент на использовании языка C++ как удобного инструмента для научных вычислений. Для знакомства с материалом желательна хотя бы математическая подготовка. Вы научитесь чётко формулировать проблему, представлять её решение, и только после этого писать код и проводить тесты.</p>
  <hr />
  <figure id="wfRD" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/Open-Data-Structures.jpg" width="90" />
  </figure>
  <h3 id="qeuN">Open Data Structures</h3>
  <p id="3Rhd">Автор книги, Пэт Морин, считает, что студентам компьютерных специальностей необходимо изучать структуры данных, но в большинстве случаев хорошие книги по этой теме стоят немало, и студенты не могут приобрести их ввиду материального положения. Поэтому он решил написать собственный учебник для свободного распространения.</p>
  <hr />
  <figure id="zVMX" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/03/C3elatest.pdf.jpg" width="90" />
  </figure>
  <h3 id="PCkI">Data Structures and Algorithm Analysis</h3>
  <p id="txwE">Фокус книги сосредоточен на создании эффективных структур данных и алгоритмов. После её прочтения вы научитесь выбирать или проектировать структуру данных, наиболее подходящую в той или иной части программы.</p>
  <p id="GrFj"></p>
  <hr />
  <figure id="40Ly" class="m_custom">
    <img src="https://media.tproger.ru/uploads/2018/02/12345.jpg" width="90" />
  </figure>
  <h3 id="vM9n">Упражнения</h3>
  <p id="ooYi">Раздел упражнений расположен на официальном сайте создателя языка, Бьёрна Страуструпа. Его не стали выпускать в печатном виде, поскольку раздел постоянно обновляется. Документ содержит множество упражнений различных уровней. Данный показатель указывается рядом с номером упражнения. Например, уровень (*1) означает, что задачу вполне реально решить за 10 минут, (*2) — за час, а на (*3) вы можете потратить целый день. Конечно, эти показатели не точные и целиком зависят только от вашего опыта, так что дерзайте! Чем больше задач вы решите, тем лучше освоите инструменты C++.</p>
  <hr />

]]></content:encoded></item></channel></rss>