Найти в Дзене
Я, Golang-инженер

#49. Обработка данных с терминала пакетом flag

Оглавление

Это статья об основах программирования на Go. На канале я рассказываю об опыте перехода в IT с нуля, структурирую информацию и делюсь мнением.

Хой, джедаи и амазонки!

Разбираюсь с обработкой данных, которые можем ввести в терминал. Ранее такие вещи выполнял для выхода из программы или присвоения значений переменным, например:

Код и вывод в терминал
Код и вывод в терминал

Вроде бы всё просто - вводим значения, и можем далее с ними работать. Зачем нужен какой-то особый пакет flag? Go разбираться.

1. Инфо о пакете flag

1.1. Стандартная библиотека

Возьмём себе за правило при каждой новой функции/пакете заглядывать в стандартную библиотеку (или спецификацию).

В стандартной библиотеке мы видим вот что:

Фрагмент информации о пакете flag в стандартной библиотеке Go
Фрагмент информации о пакете flag в стандартной библиотеке Go

Что здесь интересного? Есть содержание страницы:

  • Применение (пакета);
  • Синтаксис.

Библиотека нам говорит сухим канцелярным языком что-где-как. При этом не приходит понимание "для чего", пока не начнёшь изучать информацию на практике.

Короче, стандартная библиотека, она, как маяк - на который можно ориентироваться, в море информации.

Идём плавать в море информации. На очереди русскоязычное коммьюнити.

1.2. Блогеры

Посмотрел, какие статьи есть в инете по теме пакета flag. Если вкратце - все они сложноваты для моего уровня, много деталей и информации с которой пока не сталкивался. Примеры ниже.

1.2.1. Хабр

Фрагмент статьи "Конфигурация программ на Go" с Хабра:

Фрагмент статьи №1
Фрагмент статьи №1

Напрягает информация "интерфейс определения", а также в коде type ... struct, *time.Time - в общем, вещи с которыми пока не сталкивался.

Это в IT более чем привычно, поэтому нужно учиться жить с тем, что постоянно предстоит разбираться в чём-то, а вопросов становится всё больше. Это и называется инженерная насмотренность.

1.2.2. DigitalOcian

Рассмотрим фрагмент статьи "Использование пакета Flag в Go" на сайте DigitalOcian:

Фрагмент статьи №2
Фрагмент статьи №2

Весьма подробная статья на мой взгляд, полезна к изучению.

1.2.3. Перевод стандартной библиотеки

Блог о GO - перевод определённой версии пакета из стандартной библиотеки:

Фрагмент статьи №3
Фрагмент статьи №3

Перевод страницы из стандартной библиотеки.

Минус такого подхода: когда выходит новая версия Go, библиотека меняется; статья - зависит от блогера.

В чём польза - приличный перевод, в сравнении с автоматизированным переводом веб-страницы из стандартной библиотеки. Сравните - слева автоматизированный перевод, справа - блог Go с осмысленным переводом.

Фрагмент двух сайтов
Фрагмент двух сайтов

Есть ещё несколько блогов, которые появились на первой поисковой страничке:

1.3. Нейросети

1.3.1. Конфигурирование

Вот что говорит нейросеть о целях пакета flag:

Пакет flag в Go используется для обработки аргументов командной строки. Он позволяет легко определять и использовать флаги командной строки, вводимые пользователем, а также принимать аргументы, значения которых передаются через командную строку. Это может быть полезно, например, для конфигурирования приложения или для передачи в нее необходимых параметров.
>>> Конфигурирование приложения в Go может быть использовано для передачи параметров, необходимых для работы приложения, в момент запуска. Например, конфигурация может быть записана в файле конфигурации, который загружается при запуске приложения, или передаваться в командной строке.
Например, если вы пишете веб-сервер на Go, вы можете использовать флаги командной строки для того, чтобы предоставлять параметры, такие как порт, на котором приложение будет слушать запросы, или путь к базе данных, которую приложение будет использовать для хранения данных.
Еще один пример - если вы пишете небольшой утилитарный скрипт на Go, вы можете использовать флаги, чтобы задавать параметры, такие как путь к файлу, который нужно обработать, или тип операции, которую нужно выполнить на файле.

В общем, изучив три источника (библиотека, интернет-публикации, информация от нейросети) - мы окунаемся если не в "море информации", то уж в озеро - точно.

Прежде чем разобрать пример, с которым я работал, хочу поделиться информацией о нейросетях и компании NVidea.

1.3.2 NVIDEA и нейросети

Инвестиции - моё второе хобби, после IT, с тенденцией перейти во что-то большее. Но с зарубежными бумагами я не работаю, а вот друг (изучает Python) сообщил интересную информацию по акциям от NVIDEA.

Акции компании NVidea подскочили в стоимости за месяц на 44% (на май 2023).

Причина -  успех нейросети ChatGPT и его аналогов с тенденцией роста расходов технологических компаний на оборудование для применения ИИ. Рассмотрим скачок стоимости акций NVIDEA за тридцать дней:

График стоимости акций NVidea за месяц
График стоимости акций NVidea за месяц

Справедливости ради, посмотрим историю изменения цены акций NVIDEA за всё время:

График стоимости акций NVidea за всё время торгов на бирже
График стоимости акций NVidea за всё время торгов на бирже

Вы можете задать вопрос - при чём тут видеокарты и нейросети? Дело в том, что это стереотип, будто NVIDEA занимается только видеочипами, а, например, серверным оборудованием, необходимым для ИИ.

Фрагмент с сайта NVIDIA
Фрагмент с сайта NVIDIA

Основные направления работы компании NVIDIA:

  1. Графические процессоры: NVIDIA создает графические процессоры (GPU) для игровых и профессиональных компьютеров и ноутбуков. Это основной источник дохода компании до 2023 (около 80% дохода). Серия GeForce – одна из самых популярных продуктовых линеек компании.
  2. ИИ: NVIDIA занимается исследованиями в области искусственного интеллекта, глубокого обучения и машинного обучения. Компания предоставляет мощные процессоры, такие как серия Tesla, для данных компьютерных систем.
  3. Автомобильная индустрия: NVIDIA работает над созданием автономных систем управления и аналитикой для автомобилей, основанных на искусственном интеллекте. NVIDIA DRIVE представляет собой конечное решение для автомобильных производителей, которые хотят внедрить автоматизированные и автономные функции в свои автомобили.
  4. Виртуализация и облачные технологии: NVIDIA предоставляет облачные решения для данных центров, удаленных рабочих станций и виртуальных компьютеров с помощью NVIDIA GRID и NVIDIA vGPU.
  5. Профессиональная визуализация: компания предлагает решения для профессиональной визуализации, такие как создание фильмов, моделирование, научных исследований и многое другое. Профессиональные графические карты серии NVIDIA Quadro и NVIDIA RTX используются в таких отраслях, как кино, телевидение, архитектура и медицина (ЗЫ, на моём рабочем ПК для CAD-моделирования установлена Quadro 4000).

В общем, NVIDEA - это не только про игры. Для кругозора полезно знать.

2. Пример задачи с пакетом flag

Условия задачи:

Написать программу для нахождения подстроки в кириллической подстроке. Программа должна запускаться с помощью команды:
go run main.go --str "строка для поиска" --substr "поиска"

Решение на GitHub'e <<<

Чтобы запустить программу, в терминал нужно ввести примерно следующее:

go run temp.go -str "Голод - не тётка" -substr "лод"

Разберём код поэтапно.

2.1. Функция main()

Фрагмент кода №1
Фрагмент кода №1
  • Строка 10: вывод в терминал названия кода;
  • Строка 11: функция, которая назначает и считывает два флага;
  • Строка 12-14: проверка ввода двух флагов;
  • Строка 15: поиск подстроки в строке.

Всё, короткая функция main(). Далее разберём последующие функции.

2.2. Создание флагов

Ниже представлена функция создания двух флагов:

Фрагмент кода №2
Фрагмент кода №2

Рассмотрим, что у нас под капотом функции создания флага - строки кода 21 и 22. Сигнатура функции:

Описание функции
Описание функции

2.2.1. Аргументы функции

  • name - название флага;
  • value - значение флага по-умолчанию;
  • usage - описание флага.

Функция flag.String() возвращает указатель на строку (*string), содержащую значение флага. С первыми двумя, думаю, всё понятно. А для чего использовать описание флага?

2.2.2. Аргумент usage

Аргумент usage в функции flag.String() (как и других функций пакета flag) используется для описания флага, которое будет использоваться при автоматической генерации справки для пользователей.

Когда пользователь запускает программу с флагом -h или -help, пакет flag анализирует набор определенных флагов и автоматически генерирует справочную информацию для пользователей.

Описание каждого флага будет содержать строку, переданную в качестве аргумента usage при определении этого флага. Например, для кода, который я разбираю, справка для пользователя будет выглядеть так:

Вызов справки за счёт флага -h
Вызов справки за счёт флага -h

Как видим, справка содержит описание флагов, которые мы задали в строках 21 и 22 (см. Фрагмент кода №2).

2.2.3. Анализ CMD и обработка флагов

В строке 23 мы вызываем функцию flag.Parse().

Эта функция используется для анализа командной строки и обработки флагов, определенных с помощью пакета flag.

Когда мы инициализировали флаги в вашей программе с помощью функций пакета flag (в данном случае - flag.String()), пакет flag не обрабатывает эти флаги автоматически при запуске программы. Вместо этого мы должны явно вызвать функцию flag.Parse(). Это позволяет пакету flag понимать, какие флаги были установлены при запуске вашей программы.

Функция flag.Parse() анализирует аргументы командной строки и устанавливает значения флагов, переданных в ней. После этого, мы можем получить значение флага, используя указатель (астериск) - об этом в следующем разделе.

При этом, вызывать flag.Parse() нужно после инициализации самих флагов.

2.3. Проверка получения флагов

Функция выглядит так:

Фрагмент кода №3
Фрагмент кода №3

Что здесь интересного. Основное - если мы не ввели в терминал значения, отличные по-умолчанию, т.е. флаги пусты, программа выведет сообщение об ошибке.

Что ещё интересного: в описании условия строки 29 мы использовали указатель * для обращения к значению флага. Ради интереса давайте напечатаем флаги без указателя:

Фрагмент кода №4
Фрагмент кода №4

В этом коде в строке 29 я напечатал флаги без указателя. Если скриншот мЕлок - вот крупнее вывод в терминал:

Вывод в терминал
Вывод в терминал

Флаги без указателя - это адреса на ячейки хранения флагов в памяти.

2.5. Поиск одной строки в другой

Рассмотрим код:

Фрагмент кода №5
Фрагмент кода №5

В целом, ничего сложного - мы используем стандартный пакет Go - strings.

У strings.Index под капотом 78 строк кода. Вот фрагмент этого кода:

Частичный код strings.Index
Частичный код strings.Index

Для нас тут представляет интерес сигнатура функции, см. строку 1097:

  • s - строка, в которой будет выполнен поиск;
  • substr - строка для поиска.

А возвращает функция индекс первого вхождения подстроки в строку.

2.6. Выполнение кода

При внесении всех флагов, результат кода будет следующим:

Пример вывода №1
Пример вывода №1

Здесь всё правильно, считаем по количеству символов 0-1-2-3-4-5-6-7 - с седьмой позиции начинается строка "is".

Попробуем ввести кириллицей:

Пример вывода №2
Пример вывода №2

Здесь уже позиция 15. Дело в том, что латинские символы (а также служебные знаки, цифры и некоторые другие символы) в кодировке UTF-8 используют таблицу ASCII, а там по 1 байту на символ. А кириллица уже использует 2 байта.

Попробуем провернуть это дело японской письменностью:

Пример вывода №3
Пример вывода №3

Здесь символы занимают уже по три байта, поэтому девятка.

Для информации - в этой строке используются иероглифы (кандзи) и две слоговые азбуки:

  1. ガ - Катакана.
  2. ラ - Катакана.
  3. ン - Катакана.
  4. は - Хирагана.
  5. 良 - Кандзи.
  6. い - Хирагана.
  7. 言 - Кандзи.
  8. 語 - Кандзи.

Просто информация для расширения кругозора. Когда-то изучал японский язык.

3. Выводы

На примере мы изучил пакет flag - самые основы. Понял, что за счёт ввода информации в CMD мы можем задавать конфигурирование для утилит. А также расширил кругозор - узнал, что компания NVIDIA обеспечивает инфраструктурой нейросети и искусственный интеллект.

Успехов, Бро!

aisvri Available for hire https://unsplash.com/photos/J-t5oehf3a8
aisvri Available for hire https://unsplash.com/photos/J-t5oehf3a8

Бро, ты уже здесь? 👉 Подпишись на канал для новичков «Войти в IT» в Telegram, будем изучать IT вместе 👨‍💻👩‍💻👨‍💻