<?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>Роман Осташев</title><generator>teletype.in</generator><description><![CDATA[Руковожу проектами внедрений]]></description><image><url>https://img4.teletype.in/files/73/5c/735c17d3-a6b3-4628-acb8-58ef3f6936aa.png</url><title>Роман Осташев</title><link>https://teletype.in/@romost</link></image><link>https://teletype.in/@romost?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/romost?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/romost?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 03:18:33 GMT</pubDate><lastBuildDate>Wed, 29 Apr 2026 03:18:33 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@romost/timelapse_modeling_renga_part1</guid><link>https://teletype.in/@romost/timelapse_modeling_renga_part1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost</link><comments>https://teletype.in/@romost/timelapse_modeling_renga_part1?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost#comments</comments><dc:creator>romost</dc:creator><title>Таймлапс Моделирование в Renga Часть 1</title><pubDate>Mon, 27 Nov 2023 08:34:08 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/57/cf/57cfe178-8fae-4d71-aaee-4b597a91e672.png"></media:content><tt:hashtag>таймлапс</tt:hashtag><tt:hashtag>ренга</tt:hashtag><tt:hashtag>бим</tt:hashtag><tt:hashtag>тим</tt:hashtag><tt:hashtag>моделирование</tt:hashtag><tt:hashtag>стальныеконструкции</tt:hashtag><tt:hashtag>timelapse</tt:hashtag><tt:hashtag>renga</tt:hashtag><tt:hashtag>bim</tt:hashtag><tt:hashtag>modeling</tt:hashtag><tt:hashtag>steelconstruciton</tt:hashtag><description><![CDATA[<img src="https://img3.teletype.in/files/25/61/2561787c-3558-45c9-acb1-bd2be1ffa409.png"></img>Привет, я записал таймлапс моделирования конструктивных решений в Renga, посмотреть можно на ютубе и на вк видео.]]></description><content:encoded><![CDATA[
  <figure id="iUfI" class="m_column">
    <iframe src="https://www.youtube.com/embed/pSooCJjkPq8?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="mYhC">Привет, я записал таймлапс моделирования конструктивных решений в Renga, посмотреть можно на <a href="https://youtu.be/pSooCJjkPq8?si=uDLvKMj7InMQAAOu" target="_blank">ютубе</a> и на <a href="https://vk.com/video154132847_456239305" target="_blank">вк видео</a>.</p>
  <p id="BvKD">Проект можно скачать по этой <a href="https://disk.yandex.ru/d/fn2eAn00t-d8bg" target="_blank">ссылке</a>.</p>
  <hr />
  <tt-tags id="NF3D">
    <tt-tag name="таймлапс">#таймлапс</tt-tag>
    <tt-tag name="ренга">#ренга</tt-tag>
    <tt-tag name="бим">#бим</tt-tag>
    <tt-tag name="тим">#тим</tt-tag>
    <tt-tag name="моделирование">#моделирование</tt-tag>
    <tt-tag name="стальныеконструкции">#стальныеконструкции</tt-tag>
    <tt-tag name="timelapse">#timelapse</tt-tag>
    <tt-tag name="renga">#renga</tt-tag>
    <tt-tag name="bim">#bim</tt-tag>
    <tt-tag name="modeling">#modeling</tt-tag>
    <tt-tag name="steelconstruciton">#steelconstruciton</tt-tag>
  </tt-tags>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@romost/Console-calculator</guid><link>https://teletype.in/@romost/Console-calculator?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost</link><comments>https://teletype.in/@romost/Console-calculator?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost#comments</comments><dc:creator>romost</dc:creator><title>Консольный калькулятор v1.0</title><pubDate>Thu, 21 Sep 2023 11:05:11 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/67/96/6796e19c-8358-42b2-b178-f794b75f63e4.png"></media:content><category>Код</category><tt:hashtag>coding</tt:hashtag><tt:hashtag>csharp</tt:hashtag><tt:hashtag>first_project</tt:hashtag><tt:hashtag>chat_gpt</tt:hashtag><tt:hashtag>yandexgpt2</tt:hashtag><tt:hashtag>yandex</tt:hashtag><tt:hashtag>github</tt:hashtag><description><![CDATA[<img src="https://img4.teletype.in/files/78/4d/784d3646-bbd7-466c-ad74-14e532203894.gif"></img>Мама, я стьюдент-пре-джуниор разработчик.]]></description><content:encoded><![CDATA[
  <p id="Nr2Q"><em>Мама, я стьюдент-пре-джуниор разработчик.</em></p>
  <figure id="wNZE" class="m_retina" data-caption-align="center">
    <img src="https://img4.teletype.in/files/78/4d/784d3646-bbd7-466c-ad74-14e532203894.gif" width="960" />
  </figure>
  <nav>
    <ul>
      <li class="m_level_1"><a href="#eerG">Введение</a></li>
      <li class="m_level_1"><a href="#SIV6">Что хотел сделать</a></li>
      <li class="m_level_1"><a href="#PVDa">Что сделал</a></li>
      <li class="m_level_2"><a href="#m6TO">Первый подход к снаряду</a></li>
      <li class="m_level_2"><a href="#fwBo">Второй подход к снаряду</a></li>
      <li class="m_level_2"><a href="#5ubp">Рефакторинг</a></li>
      <li class="m_level_2"><a href="#uLD3">Итог</a></li>
      <li class="m_level_1"><a href="#7Ysf">Что не получилось</a></li>
      <li class="m_level_2"><a href="#KuNt">Ввод с разных раскладок</a></li>
      <li class="m_level_2"><a href="#QOXw">Копирование ответа в буфер обмена</a></li>
      <li class="m_level_1"><a href="#JAby">YandexGPT 2</a></li>
      <li class="m_level_1"><a href="#uxx5">GitHub</a></li>
      <li class="m_level_1"><a href="#lFdq">Выводы</a></li>
    </ul>
  </nav>
  <hr />
  <h2 id="eerG">Введение</h2>
  <p id="FxKc">Не в первый раз я решаюсь начать учить программирование в личных и профессиональных целях, но в этот раз я взялся за это дело серьёзно. В начале лета 2023 я поставил перед собой цель — в конце лета я должен знать основы, и в свободное время начал изучать C# по курсу на <a href="https://ulearn.me/" target="_blank">ULearn.me</a>. Для общего развития в моих рекомендациях на YouTube появились видео о информатике.</p>
  <p id="wcel">Я считаю, что при обучении чему-то новому нужно как можно скорее приступать применять полученные знания на практике. Это помогает не утонуть в теории, поддерживать постоянный интерес к обучению и просто по человечески приятно видеть результаты по ходу своей работы (я так бельё глажу, гораздо легче, когда у тебя не просто уменьшается одна общая куча, а исчезают по одной много маленьких, отсортированных по какому-то признаку).</p>
  <p id="BcT9">Как применять знания на практике? Конечно же делать проекты, от простых к сложным, через тернии к звёздам. В целом, проектный подход мне близок, не только из-за того, что это мои непосредственные профессиональные компетенции, но и потому что я считаю, что проекты окружают нас повсюду. Ремонт, отпуск, поход в магазин, свидание, прохождение обучающего курса, написание статьи и т. п. — это проекты и мыслить в жизни нужно проектно. Из одной книжки помню примерно такую цитату: «профессиональная карьера — это череда проектов», я бы её дополнил до: «жизнь — это череда проектов».</p>
  <p id="91zY">С таким настроем я приступил к этому проекту, и конечно же, забыл об основах проектного менеджмента, начал сразу с кодинга, минуя планирование и проектирование, о чём в дальнейшем пожалел.</p>
  <figure id="YNJH" class="m_retina" data-caption-align="center">
    <img src="https://img4.teletype.in/files/39/ad/39ad0b2b-9a4a-47e0-a715-8db512d7b5dc.png" width="231" />
    <figcaption>Прогресс на момент начала проекта</figcaption>
  </figure>
  <h2 id="SIV6">Что хотел сделать</h2>
  <p id="vZQt">Я сразу понимал, что хотел сделать калькулятор, где всё было бы написано в одной строке, чтобы не было «многострочности», то есть такого:</p>
  <pre id="PYiN">Enter first number: 2
Enter second: 2
Enter operation: +
Answer: 4</pre>
  <p id="yoJv">Во-первых, это не красиво, во-вторых, я всё-таки планирую пользоваться своим приложением, а постоянно отбивать Enter просто не удобно. Писать приложение ради того чтобы написать — не мой подход.</p>
  <p id="Po0T">Кроме «однострочности», я хотел сделать хоть какие-то настройки для солидности проекта. И людям не стыдно показать, если есть настройки — приложение серьёзное. Пока я точно не знал какие это будут настройки, но они должны быть.</p>
  <p id="VMbb">Приложение должно корректно отрабатывать крайние значения (например, деление на ноль), выводить предупреждения если в строке не валидные данные и выполнять ряд проверок. Одним словом, оно должно быть стабильным и иметь защиту от дурака.</p>
  <p id="DqxB">Подытожим задачи проекта:</p>
  <ol id="Vpax">
    <li id="zM8D">Приложение должно быть юзерфрендли</li>
    <li id="Lv3Z">В приложении должны быть настройки</li>
    <li id="eJUe">В приложении должна присутствовать защита от дурака</li>
  </ol>
  <h2 id="PVDa">Что сделал</h2>
  <h3 id="m6TO">Первый подход к снаряду</h3>
  <p id="sufR">Исходя из принципа от простого к сложному я начал делать «многострочный» калькулятор, в моих планах было получить работающее приложение и уже по ходу дела доводить его до того состояния, которое я себе представлял.</p>
  <p id="SBkT">В начале, конечно, всё шло гладко и в режиме «многострочности», и даже в режиме «однострочности» приложение корректно отрабатывало все тесты. Проблемы начались тогда, когда я понял, что люди калькулятором так не пользуются, точнее пользуются только в момент первого ввода или после отчистки памяти. Мне, и я предполагаю, что любому пользователю калькулятора, естественно второй и последующие разы вводить только оператор и следующее число, пока не отчисться память, то есть примерно так:</p>
  <pre id="5thu">12+12            //первый ввод
24               //ответ
-2
20               //ответ
/36,745
0,54429174037    //ответ</pre>
  <p id="bWOy">Но из-за того что я назвал переменные firstNumber и secondNumber, я запутался в собственном коде и не смог перестроить его на логику предыдущего и текущего числа. Знаю, звучит глупо, но для меня это было фатально, было решено сделать Ctrl+A → Del и на следующий день, с чистой головой, нарисовать алгоритм и только потом кодить.</p>
  <p id="RKtV">Записей кода, к сожалению, не осталось, показать нечего.</p>
  <h3 id="fwBo">Второй подход к снаряду</h3>
  <p id="6iKP">На следующий день я начал с проектирования и планирования, для этого нарисовал, в первую очередь для своего же понимания, алгоритм работы приложения.</p>
  <figure id="ogtD" class="m_column" data-caption-align="center">
    <img src="https://img4.teletype.in/files/f7/bb/f7bb2fad-143a-4a69-a4c9-9c4dd7fc114c.png" width="2580" />
    <figcaption>Первый вариант алгоритма</figcaption>
  </figure>
  <p id="s1dE">Так я и пошёл сверху вниз реализуя функциональность по блокам. Первым делом занялся получением строки из консоли, для этого написал отдельный метод GetString, в котором сразу подумал о первой проверке — проверке на пустую строку ввода (это к теме защиты от дурака). </p>
  <pre id="FVRy" data-lang="clike">public static string GetString()
{
    var imputString = Console.ReadLine();
    while (String.IsNullOrEmpty(imputString))
    {
        Console.WriteLine(&quot;WARNING: Strig is empty (in memory &quot; + previousNubmber + &quot;)&quot;);
        imputString = Console.ReadLine();
    }
    return imputString;
}</pre>
  <p id="ymm9">Следующим на очереди был блок определения оператора. Есть массив, находим индекс любого элемента массива в строке, вычленяем подстроку с указанным индексом и длинной. Сейчас звучит всё просто, но для того чтобы найти способ поиска <u>любого</u> элемента массива в строке пришлось потратить не мало времени, сказывается неопытность в работе с документацией C#, но в итоге нашёл IndexOfAny и был рад. Ближе к концу проекта я научился задавать корректные поисковые запросы для более релевантного поиска специфической информации.</p>
  <pre id="TCDw" data-lang="clike">str = GetString();
char[] arrOperation = { &#x27;+&#x27;, &#x27;-&#x27;, &#x27;*&#x27;, &#x27;/&#x27;, &#x27;^&#x27; };

//find operation
var operationIndex = str.IndexOfAny(arrOperation);
var operation = str.Substring(operationIndex, 1);</pre>
  <p id="eHxu">Прежде чем приступить к единственному ромбику в алгоритме я понимал, что сами математические операции логичнее всего выделить в отдельный метод, и уже этот метод вызывать в ромбике. Так появился метод MathMagic. Про округление возвращаемого значения до roundValue <a href="#5ubp">чуть попозже</a>, а сейчас хочется сказать, что синтаксический сахар C# действительно сахар. If без фигурных скобок — красота, для моего дилетантского, в теме кодинга, глаза. Я ещё не слишком силён во всех всплывающих подсказках в Visual Studio и в целом возможностях IDE, но когда после написание первого «else» программа предложила написать код дальше я бы очень удивлён. Факт, что Visual Studio понимает намерение пользователя — это что-то из области фантастики.</p>
  <p id="Udce">Знаю, что переменные лучше не называть одной буквой, но на мой взгляд, здесь это уместно, читается и понимается, по крайне мере мне самому, легче.</p>
  <pre id="gk8q" data-lang="clike">public static double MathMagic(double x, double y, string o)
{
    var ans = 0d; //на сколько разобрался, это лучше чем &quot;double ans = 0;&quot;
    if (o == &quot;+&quot;)
        ans = x + y;
    else if (o == &quot;-&quot;)
        ans = x - y;
    else if (o == &quot;*&quot;)
        ans = x * y;
    else if (o == &quot;/&quot;)
        ans = x / y;
    else
        ans = Math.Pow(x, y);
    return Math.Round(ans, roundValue);
}</pre>
  <p id="VJ1k">Теперь можно полноценно говорить и о ромбике. Он реализован на простой проверке индекса оператора, который мы уже определили. Глобальные переменные previousNumber и curentNumber парсятся из строки, полученной методом GetString, вычисляется MathMagic и на экран выводиться ответ равный previousNumber. </p>
  <p id="U8iy"><em>Спойлер: CultureInfo.InvariantCulture нормально не работает.</em></p>
  <pre id="bhqP" data-lang="clike">if (operationIndex == 0)
{
    //not first enter
    curentNumber = double.Parse(str.Substring(operationIndex + 1), CultureInfo.InvariantCulture);

    previousNubmber = MathMagic(previousNubmber, curentNumber, operation);
    Console.WriteLine(previousNubmber);
}
else
{
    //first enter
    previousNubmber = double.Parse(str.Substring(0, operationIndex), CultureInfo.InvariantCulture);
    curentNumber = double.Parse(str.Substring(operationIndex + 1), CultureInfo.InvariantCulture);

    var output = MathMagic(previousNubmber, curentNumber, operation);
    previousNubmber = output;
    Console.WriteLine(previousNubmber);
}</pre>
  <p id="Vfpr">Осталось всё засунуть в бесконечный цикл for и функционал в первой итерации готов, выглядит примерно так.</p>
  <pre id="cqI5" data-lang="clike">public static double previousNubmber = 0;
public static double curentNumber = 0;
public static int roundValue = 6;

public static void Main() 
{
    var str = &quot;&quot;;
    for (; ;)
    {
        //получение строки
        //определение оператора
        //математика
    }
}</pre>
  <p id="M1qH">Выход из цикла не предусмотрен, поскольку можно просто закрыть окно консоли и получить тот же результат, это больше соответствует тому как я пользуюсь приложениями.</p>
  <h3 id="5ubp">Рефакторинг</h3>
  <p id="hUqt">Приложение работает, но в задачах проекта остались ещё два пункта, начнём с настроек.</p>
  <p id="GZNG">Тестируя приложения в ходе разработки, я сразу приметил себе одну особенность из которой можно будет сделать, желанную мной, настройку — это округление ответа до заданной точности, здесь мы возвращаемся к roundValue.</p>
  <p id="bJFC">Для начала необходимо в принципе определить, что данные в строке — это настройка. Из моего скромного опыта работы с консольными приложениями от профессиональных разработчиков я знаю, что команды в строке выглядят как «-r» или «--round», честно сказать, почему так я не знаю, но решил сделать также. Между получением строки и определением оператора в бесконечном цикл for вставил проверку строки с помощью StartsWith (нашел уже гораздо быстрее чем IndexOfAny). </p>
  <p id="mRkZ">Суть в том, что вызывается метод округления RoundForAnswer, в строку выводиться релевантная информация и цикл for начинается заново.</p>
  <pre id="YzCH" data-lang="clike">//input round value
if (str.StartsWith(&quot;-r&quot;) || str.StartsWith(&quot;--round&quot;))
{
    roundValue = RoundForAnswer(str);
    Console.WriteLine(&quot;Now rounds the value to &quot; + roundValue + &quot; decimal places, (in memory &quot; + previousNubmber + &quot;)&quot;);
    continue;
}</pre>
  <p id="8YOe">Сам метод прост как две копейки, в возвращаемое значение парситься подстрока с указанного символа.</p>
  <pre id="OyHl" data-lang="clike">public static int RoundForAnswer(string s)
{
    var value = roundValue;
    if (s.StartsWith(&quot;-r&quot;))
        value = int.Parse(s.Substring(3));
    else if (s.StartsWith(&quot;--round&quot;))
        value = int.Parse(s.Substring(8));
    return value;
}</pre>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="PuFE">Предполагаю, что метод будет вызываться только с релевантными строковыми данными (то есть «-r» или «--round» точно есть в строке). Вероятно, при работе в команде в таких случаях нужно предусматривать или проверку данных, или детально описывать метод в ///&lt;summary&gt;.</p>
  </section>
  <p id="tIWP">Таким образом, приложение стало серьёзнее в нём появились настройки, настраивать можно один параметр. Я доволен.</p>
  <figure id="oWp9" class="m_retina" data-caption-align="center">
    <img src="https://img2.teletype.in/files/9b/9a/9b9a29be-80ea-4d73-b9c3-765957a192d8.gif" width="960" />
  </figure>
  <p id="ykKy">Если есть команда, значит должна быть и справка к этой команде. Похожим способом я определяю, что в строку ввели «-h» или «--help», после чего выводиться таблица с доступными командами и ещё решил добавить информацию о доступных операторах. На моё удивление \t сработал так как я себе представлял, он не просто ставит табуляцию, а ещё и выравнивает таблицу.</p>
  <pre id="XG79" data-lang="clike">Console.WriteLine(&quot;[Help]&quot;);
Console.WriteLine(&quot;Comands\n&quot; + 
                  &quot;-c \t --cancel \t Cancel/clear memory\n&quot; +
                  &quot;-h \t --help \t Help\n&quot; +
                  &quot;-i \t --info \t Application information\n&quot; +
                  &quot;-r \t --round \t Round value (default is 6 decimal places) [-r 4 -&gt; 4 decimal places]\n&quot; +
                  &quot;\nOperation\n&quot; +
                  &quot;+ \t Plus operation\n&quot; +
                  &quot;- \t Minus operation\n&quot; +
                  &quot;* \t Multiplication operation\n&quot; +
                  &quot;/ \t Divide operation\n&quot; +
                  &quot;^ \t Exponentiation operation\n&quot;);
                  </pre>
  <p id="GgOD">Настало время реализации защиты от дурака. В приложении есть 5 проверок, одну из них мы <a href="#s1dE">уже видели</a>, это проверка на пустую строку, в этом блоке реализованы 4 остальные:</p>
  <ol id="KppL">
    <li id="mpP4">Проверка отсутствие оператора в строке. Конструкцию поиска arrOperation.Any (str.Contains) через документацию по C# найти мне не удалось, здесь я прибегнул к помощи Алисы и YaGPT 2, подробнее об этом <a href="#JAby">ниже</a>.</li>
    <li id="HhpX">Проверка деление на ноль. Как не странно, сначала не было условия ИЛИ, и только в ходе тестов, я понял, что не могу делить на числа от 0 до 1.</li>
    <li id="eUtD">Проверка на запрещённые символы в строке. Долго не хотел делать массив arrBanSymbol, в моей голове была установка, что можно как-то с помощью языковых конструкций проверять, что в строке есть только цифры и математические операторы. Поиски мои не увенчались успехов и в коде появился массив с запрещёнными символами.</li>
    <li id="D7dt">Проверка отсутствие чисел в строке. Зеркальная первой в списке проверка, есть оператор, но нет числа.</li>
  </ol>
  <pre id="2pDE" data-lang="clike">char[] arrOperation = { &#x27;+&#x27;, &#x27;-&#x27;, &#x27;*&#x27;, &#x27;/&#x27;, &#x27;^&#x27; };
char[] arrBanSymbol = &quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%&amp;()_=&#x60;&#x27;;:&#x27;&quot;.ToCharArray(); //for check
//str check
if (arrOperation.Any(str.Contains) == false) //check for arrOperation in str
{
    Console.WriteLine(&quot;WARNING: String without operation (in memory &quot; + previousNubmber + &quot;)&quot;);
    continue;
}
else if (str.Contains(&quot;/0&quot;) &amp;&amp; str.Contains(&quot;/0.&quot;) != true) //check for divide by zero
{
    Console.WriteLine(&quot;WARNING: Divide by zero (in memory &quot; + previousNubmber + &quot;)&quot;);
    continue;
}
else if (arrBanSymbol.Any(str.Contains)) //check for arrBanSymbol in str
{
    Console.WriteLine(&quot;WARNING: String contains ban symbols (in memory &quot; + previousNubmber + &quot;)&quot;);
    continue;
}
else if (arrOperation.Any(str.Contains) &amp;&amp; str.Length == 1) //check for str with arrOperation, but without numbers
{
    Console.WriteLine(&quot;WARNING: String without numbers (in memory &quot; + previousNubmber + &quot;)&quot;);
    continue;
}</pre>
  <figure id="iET8" class="m_retina">
    <img src="https://img4.teletype.in/files/bc/47/bc471691-6aec-4aab-829d-1a11b1936a3a.gif" width="960" />
  </figure>
  <h3 id="uLD3">Итог</h3>
  <p id="pcgo">В итоге алгоритм эволюционировал до такого.</p>
  <figure id="Yv2C" class="m_column" data-caption-align="center">
    <img src="https://img3.teletype.in/files/e8/2b/e82b365b-bd33-4fdd-b93e-440663232cdd.png" width="1968" />
    <figcaption>Финальный алгоритм</figcaption>
  </figure>
  <p id="HgHQ">Основной цикл приложения выглядит примерно так.</p>
  <pre id="4IyE" data-lang="clike">public static double previousNubmber = 0;
public static double curentNumber = 0;
public static int roundValue = 6;

public static void Main() 
{
    var str = &quot;&quot;;
    for (; ;)
    {
        //получение строки
        //команды
        //проверка данных в строке
        //определение оператора
        //математика
    }
}</pre>
  <h2 id="7Ysf">Что не получилось</h2>
  <h3 id="KuNt">Ввод с разных раскладок</h3>
  <p id="GRID">Главный момент из-за которого, я не могу сказать, что проект выполнен на 100% — это, то что не удалось реализовать ввод с английской и русской раскладкой клавиатуры. Я использую приложение на нампаде, писать числа на клавишах вверху клавиатуры — занятие не из приятных, и к тому же не быстрое. </p>
  <p id="rkIf">Клавиша точки на нампаде на разных раскладах ставит разный символ: на английской будет «12.34+56.78», а на русской «12,34+56,78»; и вроде как всё просто решается простым CultureInfo.InvariantCulture, но в моём случае он готовит данные под тип double, а не даёт возможность использовать и точку и запятую.</p>
  <pre id="xwLb" data-lang="clike">using System.Globalization;

previousNubmber = double.Parse(str.Substring(0, operationIndex), CultureInfo.InvariantCulture);curentNumber = double.Parse(str.Substring(operationIndex + 1), CultureInfo.InvariantCulture);</pre>
  <p id="me00">Без использования CultureInfo.InvariantCulture приложение корректно работает только с запятыми, то есть на русской раскладке. Поскольку команды и сообщения (можно сказать, что пользовательский интерфейс) на английском, то оставлять ввод чисел на русской раскладке — это преступление. Исходя из логики, что лучшее — враг хорошего, я оставил попытки неопытного разработчика разгрызть этот орех. Стоит отметить, что пользуюсь приложением уже некоторое время, и данный момент ни как не мешает, если бы не знал даже не заметил, знание — бремя.</p>
  <h3 id="QOXw">Копирование ответа в буфер обмена</h3>
  <p id="87Pq">Одной из задач проекта было удобство его использования (юзерфрендли). Считать в собственном калькуляторе, конечно хорошо, но ещё лучше если ответ автоматически копируется в буфер обмена, а дальше его можно вставить там где это необходимо. </p>
  <p id="Lgc0">Я конечно изначально это не планировал, это родилось само собой, по ходу тестирования и использования (agile в чистом виде). Реализация этой фичи полностью бы удовлетворила задачу удобства использования, но этому не суждено было сбыться. Все поиски по этой теме вели меня на классы System.Windows.Clipboard или System.Windows.Forms, которые в .NET 6.0 просто отсутствуют. Уверен, что это можно сделать, но пока я не знаю как. Опять же таки из логики, что лучшее — враг хорошего, я оставил поиски, а фича осталась не реализованной.</p>
  <h2 id="JAby">YandexGPT 2</h2>
  <p id="a1Yh">Поиск информации — это важная часть обучения, в силу своей неопытности искать в поиске по документации C# у меня получается не так хорошо как хотелось бы. На помощь приходят нейросети, я решил попробовать найти необходимую мне информацию в YaGPT 2, которую недавно выпустил Яндекс. Мне понравилось.</p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="ItFn">Далее YaGPT 2 я буду называть Алисой, имеется ввиду общение с ней именно в этом навыке.</p>
  </section>
  <p id="sEEG">Решил специально не использовать каких-то конструкций (кроме «С#» вначале), чтобы переписка максимально походила на то, как я бы задавал вопрос опытному разработчику.</p>
  <figure id="6vqt" class="m_retina" data-caption-align="center">
    <img src="https://img2.teletype.in/files/53/9e/539e1c5b-907d-4793-9619-af7b18032349.gif" width="540" />
    <figcaption>Поиск arrOperation.Any(str.Contains)</figcaption>
  </figure>
  <p id="iX67">Конечно я также пытался найти ответы и на те моменты, которые у меня не получилось реализовать в программе.</p>
  <figure id="06us" class="m_retina" data-caption-align="center">
    <img src="https://img1.teletype.in/files/89/38/89387fb1-f9e6-45b9-8d9b-f28079f88955.gif" width="540" />
    <figcaption>Попытки найти способ копировать значение в буфер обмена</figcaption>
  </figure>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="m8aj">Предательски Алиса выдаёт другой ответ на момент записи экрана, когда я писал код информацию о ValueTuple она не выводила. Надо будет изучить.</p>
  </section>
  <p id="JPFJ">Внезапно Алиса перестала понимать о чем идёт речь. Сетую на то, что мой запрос для ней выглядит странно, но человеку я задал вопрос бы именно так.</p>
  <figure id="7Duw" class="m_retina" data-caption-align="center">
    <img src="https://img3.teletype.in/files/ef/93/ef9352c9-7ba9-4bc7-be19-1b25144d5bd3.gif" width="540" />
    <figcaption>Потеря контакта</figcaption>
  </figure>
  <p id="Fkfb">После попробовал вставить кусок кода побольше для того чтобы появился контекст, ответ забавный.</p>
  <figure id="ja5z" class="m_retina" data-caption-align="center">
    <img src="https://img3.teletype.in/files/e5/c8/e5c8141b-62cc-47c9-ac55-c1eedbda08d1.gif" width="540" />
    <figcaption>Да, это код на C#</figcaption>
  </figure>
  <p id="1cMU">Опыт поиска информации через Yandex GPT 2 определённо положительный. Искал я, конечно, гораздо больше информации через Алису и вопросы были более глупыми. </p>
  <p id="qsi3">Если не удаётся найти информацию в документации, я щёл со своим запросом к Алисе, плюс у неё можно после попросить ссылки на источники.</p>
  <figure id="ZSXf" class="m_retina" data-caption-align="center">
    <img src="https://img2.teletype.in/files/df/77/df77bc9f-867a-434e-9c97-d7c64dc9c85a.gif" width="540" />
    <figcaption>Логический переход к следующему блоку</figcaption>
  </figure>
  <h2 id="uxx5">GitHub</h2>
  <p id="3XjN">Известен не только в узких кругах, я думаю, что каждый, кто проведёт достаточно времени в интернете хотя бы раз услышит что-то о GitHub, и я не исключение.</p>
  <p id="KfJZ">Завершённый проект или итерация проекта должны быть доступны для скачивания, доработки и комментирования другими людьми. Обратная связь — неотъемлемая часть обучения, критически необходимо производить общение с более опытными коллегами, так я и решился создать аккаунт на GitHub.</p>
  <p id="9IaM">Просмотрев информацию, что вообще такое Git (про Hub более менее понятно), я понял что меня ждёт куча кнопок с функционалом, который мне не нужен, а это значит запутаться и кликнуть не туда будет очень просто. Благо со второй попытки получилось опубликовать репозиторий, и теперь с гордостью могу сказать, что исходный код моего калькулятора вы можете <a href="https://github.com/RomanOstashev/Console-calculator" target="_blank">скачать на GitHub</a>.</p>
  <p id="vjxU">Многое на площадке осталось не понятным, надеюсь со временем разберусь. Почему в релиз попал только исходный код без скомпилированного приложения я так и не понял. По этому для простых обывателей, без Visual Studio, по <a href="https://disk.yandex.ru/d/K8Gh6KzKOckCVw" target="_blank">этой ссылке</a> можно скачать уже само приложение. </p>
  <h2 id="lFdq">Выводы</h2>
  <p id="JumT">Проект без выводов - не проект.</p>
  <p id="q0dJ">Радости полные штаны от реализованного проекта, ещё больше рад, что в ходе создания такого простого приложения познакомился с GitHub и YaGPT 2. Я считаю, что задачи выполнены, приложение можно использовать. Осталось добавить его в быстрый доступ и использовать по максимуму.</p>
  <p id="HhNe">Я на 99% уверен, что написанный мной код может быть улучшен, какие-то части можно написать более эффективно, а может быть и всё приложение. Но на текущий момент я доволен тем, что написал и как это работает, в будущем возможны доработки.</p>
  <p id="kYTg">Возможные планы на улучшение:</p>
  <ul id="SO5H">
    <li id="3RYF">Реализация нескольких операторов в одной строке</li>
    <li id="2NEj">Реализация функционала скобок</li>
    <li id="JdU0">Тригонометрия</li>
  </ul>
  <section style="background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="XPQI">Если вам было интересно читать статью о самом начале пути разработчика, подписывайтесь! Как наберётся материал, подобных статей будет больше. Рад комментариям и обсуждениям по теме, ссылки на профильные ресурсы для просмотра и чтения приветствуются.</p>
  </section>
  <hr />
  <tt-tags id="VZVL">
    <tt-tag name="coding">#coding</tt-tag>
    <tt-tag name="csharp">#csharp</tt-tag>
    <tt-tag name="first_project">#first_project</tt-tag>
    <tt-tag name="chat_gpt">#chat_gpt</tt-tag>
    <tt-tag name="yandexgpt2">#yandexgpt2</tt-tag>
    <tt-tag name="yandex">#yandex</tt-tag>
    <tt-tag name="github">#github</tt-tag>
  </tt-tags>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@romost/about</guid><link>https://teletype.in/@romost/about?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost</link><comments>https://teletype.in/@romost/about?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=romost#comments</comments><dc:creator>romost</dc:creator><title>Привет, меня зовут Рома</title><pubDate>Sun, 17 Sep 2023 07:03:42 GMT</pubDate><description><![CDATA[Я занимаюсь цифровизацией строительства, учусь в аспирантуре и иногда пишу код.]]></description><content:encoded><![CDATA[
  <p id="6OpI">Я занимаюсь цифровизацией строительства, учусь в аспирантуре и иногда пишу код.</p>
  <p id="JOr3">Инженер в душе и в голове, считаю что образование <a href="https://nngasu.ru/" target="_blank">ПГС</a> — лучшая подготовка к самостоятельной жизни. Участвую в профессиональных конкурсах, <a href="https://steel2real.ru/novosti/news-2023/412-news-2023" target="_blank">иногда побеждаю</a>. Женат.</p>

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