Это первая часть новой серии руководств по созданию генетического алгоритма в F# и .NET Core 3.0.
Этот учебник посвящен созданию нового консольного приложения и изучению некоторых основ F#. К концу этого урока вы должны уметь:
- Понимание основ F#
- Создайте новую библиотеку классов F#.
- Создайте новое консольное приложение F# и свяжите его с библиотекой классов.
- Закодируйте базовый цикл ввода консоли
- Кодируйте простые функции и классы на F#
Предпосылки
Перед запуском вам необходимо установить Visual Studio 2019 (версия Community бесплатна и подходит для этой цели). Вам также необходимо убедиться, что рабочая нагрузка Разработка рабочего стола .NET отмечена при установке Visual Studio.
Понимание F#
Важный отказ от ответственности. Автор является новичком в F#. Я прочитал несколько книг и написал нейронную сеть на F#, а также код из этой серии статей, но в остальном я очень новичок в этом языке. Это представляет собой мою лучшую попытку поделиться знаниями, которые я изучил, но не представляет собой авторитетную модель типа передовой практики и может включать неточности, основанные на неполном понимании. Тем не менее, я хочу поделиться тем, что узнал
Крутое оформление консоли в Windows | Как сделать?
F# — это функциональный язык программирования, входящий в семейство языков .NET.
Преимущество функциональных языков программирования обычно заключается в качестве приложений. По умолчанию F# лучше обрабатывает пустые значения, а такие концепции, как размеченные объединения и сопоставление с образцом, затрудняют совершение ошибок.
Кроме того, синтаксис F# более лаконичен, чем C#, а это означает, что для выражения того же намерения требуется значительно меньше строк кода, чем в C# или других языках. Поскольку у вас меньше строк кода, скрыть ошибки сложнее.
Поскольку F# является частью .NET, он компилируется в IL и работает как часть .NET Framework и .NET Core.
Это означает, что другие языки .NET, такие как C# и VB .NET, могут взаимодействовать с библиотеками F#. Это также означает, что вы можете смешивать функциональное программирование и объектно-ориентированное программирование в зависимости от конкретных потребностей того, что вы программируете.
F# также не ограничивается строго функциональным программированием, поскольку F# можно использовать для создания традиционных классов в соответствии с соглашениями .NET (хотя синтаксис иногда очень уродлив для этого).
Общие сведения о консольных приложениях .NET Core 3.0
Консольные приложения — это текстовые утилиты, запускаемые из командной строки. Обычно они используются как часть автоматизированных процессов или для интеграции с другими инструментами.
Консольные приложения .NET Core 3.0 работают на разных платформах и не сильно привязаны к Windows, как консольные приложения .NET Framework.
В этой серии руководств конечным результатом не будет консольное приложение, но для того, чтобы сначала сосредоточиться на коде, мы начнем с консольного приложения для простоты.
Основы CMD | Консоль windows | Терминал юзера
Приложение, которое мы создадим
Это первая часть серии статей о построении генетического алгоритма на F#. В сериале будет представлена двухмерная игровая доска с изображением белки, собаки, желудя, дерева и кролика. По ходу серии мы будем больше говорить о том, что мы будем моделировать и как это будет работать, а также о том, что такое генетические алгоритмы.
Сейчас мы создадим простое консольное приложение, которое генерирует игровое поле с белкой где-то на нем, затем отображает игровое поле пользователю и позволяет ему случайным образом регенерировать новое игровое поле.
Для того чтобы это сделать нам понадобится:
- Тип WorldPos , который хранит 2D-локацию в игровом мире.
- Класс Squirrel , наследуемый от класса Actor.
- Класс World , который упорядочивает актеров в симуляции.
- Консольное приложение, которое отображает текущий World и предлагает пользователю ввести данные, повторяя цикл до тех пор, пока пользователь не нажмет X для выхода.
Настройка решения
Первоначально наше решение будет содержать два проекта: консольное приложение .NET Core и библиотеку классов .NET Standard.
Создайте консольное приложение
В Visual Studio создайте новый проект. В мастере создания нового проекта измените раскрывающийся список Language Type на F#, а затем найдите параметр Console App (.NET Core) , как показано на рисунке ниже. Убедитесь, что в качестве языка указан F#.
Нажмите Next , назовите проект как хотите. Какое бы имя вы ни выбрали, я рекомендую включить имя ConsoleApp где-нибудь в название, чтобы помнить, что это консольное приложение, поскольку у нас будет несколько проектов.
Создайте стандартную библиотеку .NET
В Visual Studio щелкните правой кнопкой мыши решение в верхней части обозревателя решений и выберите Add > New Project. .

Оттуда выберите параметр «Библиотека классов F# (стандарт .NET)», как показано на рисунке.
Убедитесь, что в качестве языка для параметра указан F# и что вы выбрали вариант .NET Standard, а не параметр .NET Core.
Хотя .NET Core может работать, преимущество .NET Standard заключается в том, что на него можно ссылаться из приложения .NET Framework или .NET Core. Если вы когда-нибудь захотите добавить какое-либо приложение .NET Framework 4.8, вы не сможете сослаться на библиотеку классов .NET Core.
Мое общее правило состоит в том, что если у меня нет веской причины не делать этого, я всегда буду создавать библиотеки классов .NET Standard.
Нажмите «Далее» и назовите библиотеку классов как хотите, а затем создайте ее. Я рекомендую заканчивать имя библиотеки на Logic, Domain или DomainLogic, чтобы было ясно, что это библиотека классов, обрабатывающая логику приложения. В оставшейся части этой серии я буду называть ее библиотекой логики предметной области.
Ссылка на библиотеку классов из консольного приложения
Теперь, когда у нас есть два проекта в одном решении, разверните консольное приложение в обозревателе решений, щелкните правой кнопкой мыши узел Dependencies и выберите Add Reference. .
На вкладке проектов установите флажок рядом с библиотекой логики домена, которую вы создали выше, и нажмите «ОК». Это позволит вашему консольному приложению .NET Core ссылаться на логику в библиотеке логики домена.
Добавление логики домена
Прежде чем мы сможем реализовать консольное приложение, нам нужно создать классы, на которые оно ссылается.
Обратите внимание, что в F# порядок файлов внутри проекта имеет значение. F# будет загружать файлы сверху вниз, поэтому файлы вверху не могут ссылаться на значения, определенные под ними. Visual Studio позволяет использовать клавишу Alt и клавиши со стрелками для перемещения элементов вверх и вниз в обозревателе решений, а также для добавления новых элементов выше или ниже существующего проекта.
Порядок, который нам понадобится для этого приложения:

Идите вперед и создайте пустые файлы сценариев F # с такими именами. Вы можете удалить или переименовать файл F# по умолчанию, с которого начинается библиотека классов.
WorldPos
В файл WorldPos мы добавим следующий код:
Здесь мы говорим, что все принадлежит пространству имен MattEland.FSharpGeneticAlgorithm.Logic , а не корневому пространству имен. Это помогает поддерживать порядок.
Далее мы объявляем модуль с именем WorldPos . Это позволит другим файлам открывать (импортировать) логику, которую мы определяем здесь.
Затем мы определяем простой тип с именем WorldPos , который состоит из двух целочисленных значений: X и Y. Он компилируется как простой класс, но обратите внимание, синтаксис невероятно минимален.
Наконец, мы определяем функцию с именем newPos , которая принимает два параметра с именами x и y . Эта функция вернет новый объект со свойствами X и Y .
Вот интересная часть: F# интерпретирует тип возвращаемого значения как WorldPos , хотя явного синтаксиса, объявляющего это, не существует. Это связано с тем, что через оператор open не импортируется ничего, что могло бы соответствовать результату newPos , кроме объявленного выше типа WorldPos . Если бы они были, некоторые дополнительные объявления типов были бы явно необходимы.
Актеры
Далее давайте посмотрим на файл актеров:
Как и раньше, мы объявляем пространство имен и модуль, но здесь мы открываем другой модуль, в данном случае модуль WorldPos , который мы определили ранее.
Затем мы определяем абстрактный класс с именем Actor и украшаем его атрибутом AbstractClass , говорящим F#, что этот тип должен быть реализован абстрактно. Этот стиль синтаксиса часто необходим для концепций объектно-ориентированного программирования.
Как использовать консоль в Windows
Предполагается, что вопрос «зачем?» уже не стоит. Мне в моей работе консоль нужна для автоматизации сборки фронтенда (компиляция препроцессоров, сборка спрайтов, оптимизация кода и т.п.).
Будем ставить Git Bash (Git — система контроля версий, он нам очень пригодится в работе и поставляется с консолью Git Bash) и cmder (эмулятор консоли, позволяющий использовать несколько разных консолей, имеющий вкладки, нормальную работу с буфером обмена и прочие плюшки).
Почему не Power Shell
Power Shell — неплохая консоль, встроенная в Windows. Однако, среди веб-разработчиков множество пользователей OS X и Linux — эти ОС более стабильны, безопасны, а Linux — еще и на пару порядков более распространен на серверах, в сравнении с Windows. На OS X и Linux «из коробки» есть вменяемые консоли, имеющие много общего. Привыкайте сразу к хорошему, функциональному и универсальному.
Лично я, во-первых, всерьез исследую возможность выноса всей работы с автоматизацией фронтенда в виртуальную машину с Ubuntu (я бы перешел на Ubuntu полностью, но Photoshop не позволяет), а во вторых, мой рабочий компьютер Windows 10, а ноутбук — старенький MacBook Air и хочется иметь хоть какую-то унификацию работы с консолью.
Как получить нормальную консоль
- Скачать и установить Git (если еще не ставили). Установщик спрашивает добавлять ли в контекстное меню проводника пункты запуска Git Bash и Git GUI. Я отказался, ибо планирую использовать эмулятор консоли. Прочее можно оставить по умолчанию.
- Скачать с http://cmder.net mini-версию и распаковать в C:/cmder . Запустить C:/cmder/Cmder.exe от имени администратора (безразлично что именно он напишет при первом запуске), нажать Win + Alt + P для перехода к настройкам.
- В настройках: Startup → Tasks. Нажать кнопку Add default tasks… для добавления задач по умолчанию. В списке Predefined tasks (это все возможные к запуску внутри эмулятора консоли) появится несколько дополнительных пунктов, среди которых должен быть (иногда таких пунктов два).
- В настройках: Startup → выбираем радиокнопку Auto save/restore opened task. Теперь при открытии cmder Вы будете видеть вкладки с теми же консолями, с которыми работали перед закрытием. Сохранить.
- В главном окне программы нажать Ctrl + T для создания новой вкладки с консолью и в секции Create new console выбрать . При необходимости, можно поставить флажок «run as Administrator».
- Закрыть открытую изначально вкладку (самая первая, почти наверняка, PowerShell.exe) кликом средней кнопки мыши или из контекстного меню вкладки.
Как использовать полученную консоль
Тут важно понимать, с чем работаешь. Консоль — возможность «текстового» общения с компьютером: набираем команду — получаем реакцию. Если набранная команда запускает какой-то постоянно выполняющийся процесс (веб-сервер, к примеру), остановить выполнение можно по Ctrl + C . Да-да, то самое «копировать». Как же скопировать что-то из консоли? — спросите Вы.
С cmder — просто выделите нужный фрагмент мышью и он окажется в буфере обмена. Crtl + V работает штатно («вставить»).
Чаще всего, мы набираем какую то команду и передаваемый ей параметр (один или несколько) и/или ключи (указания как ей работать). Иногда, сразу же набираем еще несколько команд, разделяя их символами (команды будут выполнены в набранной последовательности, это не единственный возможный разделитель).
Для команд, которые используются часто, можно придумать сокращения (алиасы), чтобы вызывать их быстрее.
Файловая система
cd projects # переход в папку projects, которая есть текущей папке cd /d/projects # переход в папку projects, расположенную по адресу `D:/projects` (где бы не находился пользователь) cd .. # переход к родительской папке (вверх на 1 уровень)
Чтобы не набирать имя папки целиком, наберите первые пару символов и нажмите Tab — произойдет автодополнение (если нет двух папок, начинающихся с введенных символов, иначе будут показаны сами эти папки).
Посмотреть содержимое папки позволяет команда ls:
ls # показать содержимое папки (сортировка по имени, папки и файлы вперемешку, несколько столбцов) ls -a # то же, но показывать и скрытые файлы и папки ls -a -1 # то же, но в один столбец ls -hF -1 —sort=extension # показать содержимое папки «красиво, в один столбец» ls build/css # показать содержимое папки `ТЕКУЩАЯ_ПАПКА/build/css`
Создание папок и файлов — команды mkdir и touch.
mkdir project # создать папку с именем «project» mkdir project project/css project/js # создать несколько папок mkdir -p project/ # то же, что выше touch index.html # создать файл touch index.html css/style.css # создать файлы (папки `css/` и `js/` должны уже существовать)
Копирование файлов — команда cp
cp index.html catalog.html # копирование файла index.html в тот же каталог с переименованием в `catalog.html` cp index.html old/ # копирование файла `index.html` в папку `old/` (все произойдет в текущей папке) cp temp/ temp2/ -r # копирование каталога
Переименование или перемещение файлов — команда mv
mv index.html old # перемещение файла в папку mv index.html old/new_name.txt # перемещение файла в папку с переименованием файла mv order.txt orderNew.txt # переименовать файл
Удаление папок и файлов — команда rm
rm ghost.png # удалить файл rm -rf old # удалить папку и все из нее
Разные мелочи (как вдохновение для последующего изучения консольных команд):
df -h # показать статистику использования пространства на дисках grep -i -n —color ‘carousel’ index.html css/style.css # найти слово `carousel` в двух указанных файлах (с игнором регистра), вывести строки с этим словом и номера строк (искомое слово подсветить) find . -iname ‘*ind*’ # найти в текущей папке (и подпапках) все файлы, имена которых содержат `ind` и показать списком ls -a | tee file.txt # записать в `file.txt` результат вывода команды `ls -a`
Алиасы
Для команд можно создавать алиасы (синонимы). Для этого в файл C:/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.bashrc нужно вписать строки, наподобие
alias gs=’git status` alias pro=’cd /d/projects’ alias ls=’ls -hF -1 —color=tty —sort=extension’
ВНИМАНИЕ: чтобы алиасы, добавленные в c:/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.bashrc заработали, нужно перезапустить консоль.
Мелкие хитрости
- Ctrl + ~ — показать или скрыть консоль
- Ctrl + L — очистить экран
- Ctrl + U — полностью убрать всю набранную команду
- Ctrl + R — поиск по истории команд
- Alt + ←/→ — перемещение курсора по словам набранной команды
Кнопки клавиатуры «стрелка вверх» и «стрелка вниз» — переход по истории введенных команд (удобно для повтора команды с чуть измененными параметрами).
Важный момент
Не рекомендуются использовать кириллические символы в имени и пути рабочей папки (общей папки для всех проектов), равно как в папке с именем пользователя (которая c:/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/.bashrc ), ибо на Windows это может вызвать непредсказуемое поведение консольных утилит (да, лучше создать нового пользователя, если при установке Windows Вы указали кириллическое имя).
Заключение
Если Вы уже используете консоль на Windows, поделитесь опытом.
Понравилась статья? Ставьте лайк, делитесь в соц. сетях или купите мне кофе.
Источник: nicothin.pro
Оформляем консольное приложение
Некоторые приемы по управлению цветом и позиционированием текста в консольных приложениях как в DOS/Windows, так и в UNIX.
Многие считают, что консольная программа может выглядеть лишь черно-белой и невзрачной, «радуя» пользователя только сухими строчками текста. В лучшем случае при выводе табличных данных они более-менее выравниваются и обрамляются псевдографикой из плюсов-минусов (кстати, так же делали при печати таблиц на пишущих машинках в докомпьютерную эпоху).
Между тем не так давно, когда Windows и Mac еще не приучили мир к графическому интерфейсу, программы отлично рисовали цветные таблички-окошки безо всякой графики. До сих пор вы можете найти такие программы, например, широко распространенный файловый менеджер Far, один из последователей знаменитого Norton Commander. Более того, некоторые программы (например текстовая версия Norton Utilities) создавали «почти графический» интерфейс, заменяя таблицу символов видеоадаптера и даже делая это «на лету» для вывода полноценного графического курсора мыши. Я не буду рассматривать последний случай (скорее всего, для написания графического приложения вы будете использовать графическую платформу, например Windows), а вот о том, как красиво оформить консольное приложение, пару слов скажу.
Цвет
Для начала раскрасим стандартный черно-серый экран. Если вы используете обычный вывод в консоль (например, в C это функции семейства printf), то предпочтительный способ управления цветами зависит от платформы, под которую разрабатывается приложение. Если это UNIX, то самым простым и естественным способом установки цвета, а также и позиционирования курсора, будут ESC-команды.
Это последовательности символов, начинающиеся с комбинации «x27[» ( x27 – это и есть код символа ESC), за которой следуют параметры через запятую. Здесь и далее все справочные материалы вынесены во всплывающие окна. Вот таблица ESC-последовательностей для управления курсором и цветами выводимого текста.
Везде в тексте ESC обозначает символ с кодом 27 (0x1B), буквы x , y , n – переменные, значения которых записываются в десятичной форме.
Управление курсором
ESC[y;xH или ESC[y;xf – переместить курсор в позицию (x,y).
ESC[yA – переместить курсор на y строк вверх.
ESC[yB – переместить курсор на y строк вниз.
ESC[xC – переместить курсор на x символов вправо.
ESC[xD – переместить курсор на x символов влево.
Управление цветами
ESC[nm или ESC[n;nm ESC[n;n;nm – установить атрибуты вывода текста. Список атрибутов следующий:
| Установить атрибуты по умолчанию | |
| Полужирный шрифт | 1 |
| Подчеркнутый шрифт | 4 |
| Черный цвет символов | 30 |
| Красный цвет символов | 31 |
| Зеленый цвет символов | 32 |
| Желтый цвет символов | 33 |
| Синий цвет символов | 34 |
| Малиновый (magenta) цвет символов | 35 |
| Бирюзовый (cyan) цвет символов | 36 |
| Белый цвет символов | 37 |
| Черный цвет фона | 40 |
| Красный цвет фона | 41 |
| Зеленый цвет фона | 42 |
| Желтый цвет фона | 43 |
| Синий цвет фона | 44 |
| Малиновый (magenta) цвет фона | 45 |
| Бирюзовый (cyan) цвет фона | 46 |
| Белый цвет фона | 47 |
ESC-последовательности можно использовать и в Windows-консоли, но для этого потребуется специальный драйвер ansi.sys, который может быть и не установлен у пользователя вашей программы. Поэтому для приложения под Win32 лучше использовать функции, специально предназначенные для оформления вывода в консоль.
Функция SetConsoleTextAttribute позволяет установить цвета и другие атрибуты (например, подчеркивание), а функция GetConsoleScreenBufferInfo — получить текущие значения атрибутов и различные другие параметры. Принцип установки атрибутов очень прост: все символы, выведенные после вызова SetConsoleTextAttribute будут иметь установленные атрибуты. Устанавливаете нужные цвета, печатаете текст этими цветами, устанавливаете цвет следующей порции текста, выводите его, и так далее. Подробное описание этих функций доступно в MSDN (щелкните по имени функции), я его не буду повторять, а сразу приведу пример использования, из которого будет все понятно.
HANDLE consoleOutput; // Получаем хэндл консоли consoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); // Устанавливаем цвета и выводим строку SetConsoleTextAttribute(consoleOutput, BACKGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); printf(«Test string: red on bluen»); // Устанавливаем другие цвета и снова выводим строку SetConsoleTextAttribute(consoleOutput, BACKGROUND_RED | BACKGROUND_INTENSITY | FOREGROUND_GREEN); printf(«Test string: green on redn»);
Позиционирование
Теперь рассмотрим способы, которыми можно нарушить стандартный порядок «слева-направо сверху-вниз» вывода данных в консоль. Сразу замечу, что как только вы начинаете использовать позиционирование при выводе, результат работы программы будет, скорее всего, непригоден для перенаправления в файл. Если раскраска при выводе в файл будет просто проигнорирована (при использовании ESC-последовательностей они останутся в файле, но зато вы сможете просто вывести файл на консоль и весь текст будет вновь раскрашен, как при работе программы), то позиционирование приведет к тому, что вывод на экран и текст в файле будут отличаться друг от друга, возможно очень сильно. Но в любом случае, знать некоторые приемы не помешает.
Прием первый: динамическая строка.
Пока вы не перевели строку при выводе, ее содержимое можно активно менять. Этим, например, можно пользоваться для отображения прогресса какой-либо длительной операции. Для изменения содержимого строки можно поступить двумя путями.
Первый: удаляем выведенные символы с помощью символа «backspace» с кодом 8. Он возвращает курсор на одну позицию назад, символ, правда, не стирает, но позволяет записать другой поверх. В этом случае нужно точно считать число выведенных символов, чтобы всегда знать позицию курсора.
Второй: вернуться к началу строки и напечатать новую. Для возврата к началу строки БЕЗ перехода на новую, используйте символ «CR» (Carrige Return) с кодом 13 (0x0C). После этого напечатайте новую строку, заведомо длиннее уже выведенной, чтобы затереть все старые символы (если вы не хотите добиться специальных эффектов, обновляя только начало строки).
Прием второй: прямое управление курсором
В случае UNIX-приложения можно использовать уже описанные в разделе про цвет ESC-последовательности. Windows же предоставляет две функции для управления курсором в консоли: SetConsoleCursorPosition позволяет установить позицию курсора, а GetConsoleScreenBufferInfo позволяет получить текущие координаты курсора, размер консоли, положение видимой области (если включена прокрутка) и другие атрибуты. Обе эти функции используют дескриптор консоли, процесс получения которого уже был рассмотрен выше. Как и раньше, ограничусь примером.
HANDLE consoleOutput; COORD cursorPos; // Получаем хэндл консоли consoleOutput = GetStdHandle(STD_OUTPUT_HANDLE); // Задаем координаты курсора и перемещаем курсор cursorPos.X = 30; cursorPos.Y = 3; SetConsoleCursorPosition(consoleOutput, cursorPos); // Выводим строку printf(«Test string at position (30, 3)»); // Повторяем с другими координатами. cursorPos.X = 15; cursorPos.Y = 8; SetConsoleCursorPosition(consoleOutput, cursorPos); printf(«Test string at position (15, 8)»);
Рисование линий и рамок
Чтобы придать выводимому тексту красивый и законченный вид, можно использовать рамки. Особенно уместно они выглядят при выводе табличных данных, однако их можно использовать и для оформления ввода данных (приглашение и поле для ввода оформить в рамку), а при желании можно создать собственную псевдографическую оконную библиотеку (вспомним TurboVision и его многочисленные аналоги, столь популярные лет 10-15 назад).
Псевдографику можно использовать и совсем нетрадиционным способом, как это сделано, например, в моем анализаторе COM-порта. Рамки и линии рисуются с помощью набора из 40 символов, 4 из которых являются прямыми линиями (вертикальные/горизонтальные, одинарные и двойные), а оставшиеся 36 – уголками и соединениями между ними во всех возможных комбинациях. Ниже приведена таблица всех этих символов в двух кодировках: CP866 (консоль DOS/Windows – верхняя строка) и KOI-8R (нижняя строка). Первой пользуемся в Windows, второй в UNIX. Числа в шестнадцатеричном представлении, префиксы (типа x или 0x) опущены для краткости.
Таблица символов псевдографики в кодировках CP866 (DOS) и KOI8-R

Для проверки вы можете воспользоваться простой программой на PHP, которая выводит такие же рамки, как те, что изображены выше. Первая половина вывода рассчитана на DOS-консоль, вторая на UNIX в кодировке KOI8-R.
Источник: denvo.ru