<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Роман Осташев</title><subtitle>Руковожу проектами внедрений</subtitle><author><name>Роман Осташев</name></author><id>https://teletype.in/atom/romost</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/romost?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@romost?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=romost"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/romost?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-29T03:18:36.494Z</updated><entry><id>romost:timelapse_modeling_renga_part1</id><link rel="alternate" type="text/html" href="https://teletype.in/@romost/timelapse_modeling_renga_part1?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=romost"></link><title>Таймлапс Моделирование в Renga Часть 1</title><published>2023-11-27T08:34:08.106Z</published><updated>2023-11-27T08:34:08.106Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/57/cf/57cfe178-8fae-4d71-aaee-4b597a91e672.png"></media:thumbnail><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><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/25/61/2561787c-3558-45c9-acb1-bd2be1ffa409.png&quot;&gt;Привет, я записал таймлапс моделирования конструктивных решений в Renga, посмотреть можно на ютубе и на вк видео.</summary><content type="html">
  &lt;figure id=&quot;iUfI&quot; class=&quot;m_column&quot;&gt;
    &lt;iframe src=&quot;https://www.youtube.com/embed/pSooCJjkPq8?autoplay=0&amp;loop=0&amp;mute=0&quot;&gt;&lt;/iframe&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;mYhC&quot;&gt;Привет, я записал таймлапс моделирования конструктивных решений в Renga, посмотреть можно на &lt;a href=&quot;https://youtu.be/pSooCJjkPq8?si=uDLvKMj7InMQAAOu&quot; target=&quot;_blank&quot;&gt;ютубе&lt;/a&gt; и на &lt;a href=&quot;https://vk.com/video154132847_456239305&quot; target=&quot;_blank&quot;&gt;вк видео&lt;/a&gt;.&lt;/p&gt;
  &lt;p id=&quot;BvKD&quot;&gt;Проект можно скачать по этой &lt;a href=&quot;https://disk.yandex.ru/d/fn2eAn00t-d8bg&quot; target=&quot;_blank&quot;&gt;ссылке&lt;/a&gt;.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;tt-tags id=&quot;NF3D&quot;&gt;
    &lt;tt-tag name=&quot;таймлапс&quot;&gt;#таймлапс&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;ренга&quot;&gt;#ренга&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;бим&quot;&gt;#бим&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;тим&quot;&gt;#тим&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;моделирование&quot;&gt;#моделирование&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;стальныеконструкции&quot;&gt;#стальныеконструкции&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;timelapse&quot;&gt;#timelapse&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;renga&quot;&gt;#renga&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;bim&quot;&gt;#bim&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;modeling&quot;&gt;#modeling&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;steelconstruciton&quot;&gt;#steelconstruciton&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

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

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

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

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

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

</content></entry><entry><id>romost:about</id><link rel="alternate" type="text/html" href="https://teletype.in/@romost/about?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=romost"></link><title>Привет, меня зовут Рома</title><published>2023-09-17T07:03:42.948Z</published><updated>2023-09-17T07:03:42.948Z</updated><summary type="html">Я занимаюсь цифровизацией строительства, учусь в аспирантуре и иногда пишу код.</summary><content type="html">
  &lt;p id=&quot;6OpI&quot;&gt;Я занимаюсь цифровизацией строительства, учусь в аспирантуре и иногда пишу код.&lt;/p&gt;
  &lt;p id=&quot;JOr3&quot;&gt;Инженер в душе и в голове, считаю что образование &lt;a href=&quot;https://nngasu.ru/&quot; target=&quot;_blank&quot;&gt;ПГС&lt;/a&gt; — лучшая подготовка к самостоятельной жизни. Участвую в профессиональных конкурсах, &lt;a href=&quot;https://steel2real.ru/novosti/news-2023/412-news-2023&quot; target=&quot;_blank&quot;&gt;иногда побеждаю&lt;/a&gt;. Женат.&lt;/p&gt;

</content></entry></feed>