Как получить имя компьютера python
Различная информацию об операционной системе и языке Python.
Python часто используется в качестве кроссплатформенного языка и иногда необходимо знать, на какой системе работает программа.
Например, инструмент для управления сетевой конфигурацией операционной системы может определять переносимое представление сетевых интерфейсов, псевдонимов, IP-адресов и т. д., но когда приходит время редактировать файлы конфигурации, то Python должен знать больше о хосте, чтобы использовать правильные команды и файлы конфигурации операционной системы.
Модуль platform включает в себя инструменты для получения сведений об аппаратной платформе, операционной системе и интерпретаторе на которой выполняется программа.
Содержание:
-
Кроссплатформенные функции:
- IP-адрес.
- MAC-адрес.
- Имя пользователя.
- Тип операционной системы.
- Скорость работы системы.
- Время.
- Скриншот.
- Скорость интернет‑соединения.
- Модель процессора.
- getpass нужен для определения информации о пользователе;
- os используем для взаимодействия с функциями ОС, вроде вызова внешних исполняемых файлов;
- psutil работает с некоторыми низкоуровневыми системными функциями;
- platform предоставит информацию об ОС.
- socket — для работы с сокетами и получения IP-адресов;
- getnode получает MAC-адрес машины;
- speedtest замеряет характеристики интернет‑соединения;
- telebot сделает всю рутину по работе с Telegram-ботом.
- datetime позволит определить время работы программы;
- pyautogui быстро и без боли работает с GUI;
- PIL. Image — для снятия скриншота.
-
platform.architecture() , platform.machine() , platform.node() , platform.platform() , platform.processor() , platform.python_build() , platform.python_compiler() , platform.python_branch() , platform.python_implementation() , platform.python_revision() , platform.python_version() , platform.python_version_tuple() , platform.release() , platform.system() , , platform.version() , platform.uname() ,
-
platform.java_ver() ,
-
platform.win32_ver() , platform.win32_edition() , platform.win32_is_iot() ,
-
platform.mac_ver() ,
-
platform.libc_ver() ,
-
platform.freedesktop_os_release() (доступна в Python 3.10).
Кроссплатформенные функции.
Функция platform.architecture() запрашивает исполняемый файл executable для получения различной информации об архитектуре. По умолчанию двоичный файл интерпретатора Python.
Возвращает кортеж (bits, linkage), который содержит информацию об архитектуре битов и формате связи, используемом для исполняемого файла. Оба значения возвращаются в виде строк.
Функция полагается на системную команду file для выполнения реальной работы. Это доступно на большинстве, если не на всех платформах Unix и некоторых не-Unix платформах и только в том случае, если исполняемый файл указывает на интерпретатор Python.
Примечание.
В Mac OS X (и, возможно, на других платформах) исполняемые файлы могут быть универсальными файлами с несколькими архитектурами. Чтобы получить 64-разрядность текущего интерпретатора, более надежно запросить атрибут sys.maxsize :
platform.machine() :
platform.node() :
Функция platform.node() возвращает сетевое имя компьютера, может быть не полностью! Если значение не может быть определено, то возвращается пустая строка..
platform.platform(aliased=0, terse=0) :
Функция platform.platform() возвращает одну строку, идентифицирующую базовую платформу, с максимально возможным количеством полезной информации.
Вывод предназначен для чтения человеком, а не для машинного анализа. Это может выглядеть по-разному на разных платформах, и это предназначено.
Если aliased имеет значение True , функция будет использовать псевдонимы для различных платформ, которые сообщают имена систем, которые отличаются от их общих имен, например SunOS будет сообщаться как Solaris.
При установке значения terse в значение True функция возвращает только абсолютный минимум информации, необходимой для идентификации платформы.
platform.processor() :
Возвращается пустая строка, если значение не может быть определено. Обратите внимание, что многие платформы не предоставляют эту информацию или просто возвращают то же значение, что и для platform.machine() .
platform.python_build() :
Функция platform.python_build() возвращает кортеж (buildno, builddate) с указанием номера и даты сборки Python в виде строк.
platform.python_compiler() :
Функция platform.python_compiler() возвращает строку, идентифицирующую компилятор, используемый для компиляции Python.
platform.python_branch() :
Функция platform.python_branch() возвращает строку, идентифицирующую ветвь SCM реализации Python.
platform.python_implementation() :
Функция platform.python_implementation() возвращает строку, идентифицирующую реализацию Python. Возможные возвращаемые значения: ‘CPython’ , ‘IronPython’ , ‘Jython’ , ‘PyPy’ .
platform.python_revision() :
Функция platform.python_revision() возвращает строку, идентифицирующую ревизию SCM реализации Python.
platform.python_version() :
Обратите внимание, что в отличие от Python sys.version() , возвращаемое значение всегда будет включать уровень исправления (по умолчанию 0).
platform.python_version_tuple() :
Функция platform.python_version_tuple() возвращает версию Python как кортеж (major, minor, patchlevel) строк.
Обратите внимание, что в отличие от Python sys.version, возвращаемое значение всегда будет включать уровень исправления (по умолчанию он равен 0).
platform.release() :
platform.system() :
platform.system_alias(system, release, version) :
Функция platform.system_alias() возвращает (system, release, version) , связанные с общими маркетинговыми именами, используемыми в некоторых системах.
platform.version() :
platform.uname() :
Функция platform.uname() представляет портативный интерфейс команды uname. Возвращает именованный кортеж, содержащий шесть атрибутов: system , node , release , version , machine и processor .
Обратите внимание, что функция platform.uname() добавляет шестой атрибут ( processor ), отсутствующий в результате os.uname(). Кроме того, имена атрибутов отличаются для первых двух атрибутов. Функция оs.uname() называет их sysname и nodename .
Функции платформы Java
Функция platform.java_ver() возвращает версию интерфейса для Jython.
Функции платформы Windows
Функция platform.win32_ver() получает дополнительную информацию о версии из реестра Windows и возвращает кортеж (release, version, csd, ptype) , относящийся к выпуску ОС, номеру версии, уровню CSD (пакет обновления) и типу ОС (многопроцессорный/однопроцессорный).
Примечание. Эта функция лучше всего работает с установленным пакетом win32all Марка Хаммонда. Очевидно, что функция platform.win32_ver() работает только на Win32-совместимых платформах.
platform.win32_edition() :
platform.win32_is_iot() :
Функция platform.win32_is_iot() возвращает True , если версия Windows, возвращенная platform.win32_edition() , распознается как версия IoT .
Функции платформы Mac OS.
Функция platform.mac_ver() Получите информацию о версии Mac OS и возвращает ее как кортеж (release, versioninfo, machine) , а versioninfo так-же является кортежем (version, dev_stage, non_release_version) .
Функции платформы Unix.
Функция platform.libc_ver() пытается определить версию libc , с которой связан исполняемый файл, по умолчанию интерпретатор Python.
Возвращает кортеж строк (lib, version) , которые по умолчанию соответствуют заданным параметрам в случае сбоя поиска.
Обратите внимание, что эта функция хорошо знает, как разные версии libc добавляют символы к исполняемому файлу. Можно использовать только для исполняемых файлов, скомпилированных с использованием gcc .
Файл читается и сканируется кусками байтов.
Функции платформы Unix.
platform.freedesktop_os_release() :
Вызывает ошибку OSError или подкласс OSError , если невозможно прочитать ни /etc/os-release , ни /usr/lib/os-release .
В случае успеха функция возвращает словарь, в котором ключи и значения являются строками. В значениях есть специальные символы, такие как " и $ без кавычек. Поля NAME , ID и PRETTY_NAME всегда определяются в соответствии со стандартом. Все остальные поля являются необязательными. Поставщики могут включать дополнительные поля.
Обратите внимание, что такие поля, как NAME , VERSION и VARIANT , представляют собой строки, подходящие для представления пользователям. Программы должны использовать такие поля, как ID , ID_LIKE , VERSION_ID или VARIANT_ID для идентификации дистрибутивов Linux.
Я пишу программу чата для локальной сети. Я хотел бы иметь возможность идентифицировать компьютеры и получить пользовательское имя компьютера с Python.
использовать socket и gethostname() функциональность. Это получит hostname компьютера, на котором работает интерпретатор Python:
оба они довольно портативные:
любые решения, используя HOST или HOSTNAME переменные среды не портативный. Даже если он работает в вашей системе при запуске, он может не работать при запуске в специальных средах, таких как cron.
вы, вероятно, загрузите модуль ОС в любом случае, поэтому другое предложение будет:
он всегда (даже в Windows) возвращает полное имя хоста, даже если вы определили короткий псевдоним в /и т. д./хосты.
если вы определили псевдоним в /и т. д./хосты затем socket.gethostname() возвращает псевдоним. platform.uname()[1] делает то же самое.
я столкнулся с случаем, когда вышеуказанное не сработало. Вот кто я. используя сейчас:
сначала он вызывает gethostname, чтобы узнать, возвращает ли он что-то, похожее на имя хоста, если не использует мое исходное решение.
На самом деле вы можете посмотреть на весь результат в platform.uname()
Если я прав, вы ищете сокет.функция функцией gethostname:
socket.gethostname() можно сделать
в некоторых системах имя хоста задается в среде. Если это так для вас, то модуль ОС может вытащить его из окружающей среды через os.функции getenv. Например, если HOSTNAME-это переменная среды, содержащая то, что вы хотите, ее получит следующее:
Update: как отмечено в комментариях, это не всегда работает, так как не все среды настроены таким образом. Я считаю, что в то время я изначально ответил я использование этого решения, как это было первое, что я нашел в веб-поиске, и это сработало для меня в то время. Из-за отсутствия переносимости я, вероятно, не использовал бы это сейчас. Однако я оставляю этот ответ для справочных целей. FWIW, это устраняет необходимость в других импортах, если ваша среда имеет имя системы, и вы уже импортируете модуль ОС. Протестируйте его - если он не работает во всех средах, в которых вы ожидаете, что ваша программа будет работать, используйте одно из других решений предоставлена.
вы можете использовать поле nodename и избегайте использования индексации массива:
хотя, даже документация os.команде uname предлагает использовать socket.gethostname()
Мне нужно было имя ПК для использования в моем файле pylog conf, и библиотека сокетов недоступна, но библиотека ОС доступна.
Как получить имя вашей рабочей станции
В этом разделе мы будем использовать модуль платформы, чтобы получить имя нашего компьютера. Мы на самом деле упомянули этот трюк в моем предыдущем в моей предыдущей статье, но поскольку нам нужна эта информация для следующего фрагмента, я собираюсь повторить этот трюк здесь:
Это было довольно безболезненно, верно? Только две строки кода, и у нас есть то, что нам нужно. Но есть на самом деле, по крайней мере, еще один способ получить это:
Этот фрагмент также чрезвычайно прост, хотя первый немного короче. Все, что нам нужно было сделать, это импортировать встроенный розетка Модуль и позвоните его GetHostName метод. Теперь мы готовы получить IP-адрес нашего ПК.
Как получить IP-адрес вашего ПК с Python
Мы можем использовать информацию, которую мы выбрали выше, чтобы получить IP-адрес нашего ПК:
В этом примере мы снова используем розетка Модуль, но на этот раз мы его GetHostbyName Способ и пройти во имя ПК. розетка Затем модуль вернет IP-адрес.
Вы также можете использовать Тим Золотой WMI модуль Отказ В следующем примере исходит от его замечательной кулинарной книги WMI:
Все, что он делает, если петля по установленным сетевым адаптерам и распечатает их соответствующие описания и IP-адреса.
Как получить MAC-адрес с Python
Теперь мы можем обратить наше внимание на получение MAC-адреса. Мы посмотрим на два разных способа получить его, начиная с рецепта ActiveState:
Поскольку я не писал код выше, я не буду входить в него в глубину. Тем не менее, я понимаю, что этот сценарий работает с первой проверкой, чтобы увидеть, может ли он сделать запрос ARP, который доступен только в Windows 2000 и выше. После того, как это подтвердило, он пытается использовать модуль CTYPES, чтобы получить адрес INET. После этого сделано, он проходит через некоторые вещи, которые я не понимаю, чтобы построить MAC-адрес.
Когда я впервые начал поддерживать этот код, я думал, что должен быть лучший способ получить MAC-адрес. Я думал, что, возможно, модуль WMI Tim Golden WMI или, возможно, пакет Pywin32 будет ответом. Я довольно уверен, что он дал мне следующий фрагмент или я нашел его на одном из архивов списка рассылки Python:
К сожалению, хотя этот метод работает, заметно замедлял сценарий входа в систему, поэтому я закончил использовать оригинальный метод в конце. Я думаю, что г-н Golden выпустил более новую версию модуля WMI, так что это возможно, что теперь это быстрее.
Как получить имя пользователя
Получение входа в текущее имя пользователя с Python Trivial. Все, что вам нужно, это Pywin32 пакет Отказ
Один быстрый импорт, и у нас есть имя пользователя в двух строках кода.
Как найти, какие группы пользователь в
Мы можем использовать UserID, который мы приобрели выше, чтобы узнать, какие группы это в.
Это более пугающее, чем любой из предыдущих скриптов, на которых мы смотрели, но это на самом деле довольно легко понять. Сначала мы импортируем модули или метод, который нам нужен. Далее у нас есть простая функция, которая принимает пользовательский объект в качестве своего единственного параметра. Эта функция будет включать в себя групп пользователя и добавить их в список, который затем возвращается к абонеру. Следующая часть головоломки получает основной контроллер домена, который мы используем ОС модуль для.
Мы передаем PDCName и UserID в GetObject (что является частью модуля Win32Com), чтобы наш пользовательский объект. Если это работает правильно, то мы можем получить полное имя и группы пользователя. Если он не удается, то мы ловим ошибку и попытаемся получить информацию с некоторыми функциями из модуля Win32Net. Если это также не удается, мы просто устанавливаем некоторые значения по умолчанию.
Обертывание
Надеюсь, вы узнали некоторые ценные трюки для использования в вашем собственном коде. Я использовал эти сценарии в течение нескольких лет с Python 2.4+, и они отлично работают!
Я пишу чат-программу для локальной сети. Я хотел бы иметь возможность идентифицировать компьютеры и получить имя компьютера с помощью Python.
Используйте socket и gethostname() функциональность. Это получит hostname компьютера, на котором запущен интерпретатор Python:
Оба из них довольно портативны:
Любые решения, использующие переменные среды HOST или HOSTNAME , не являются переносимыми. Даже если он работает в вашей системе при запуске, он может не работать при работе в специальных средах, таких как cron.
В любом случае вы, вероятно, загрузите модуль os, поэтому еще одно предложение:
Он всегда (даже в Windows) возвращает полное имя хоста, даже если вы определили короткий псевдоним в /etc/hosts.
Если вы определили псевдоним в /etc/hosts, то socket.gethostname() вернет псевдоним. platform.uname()[1] делает то же самое.
Я столкнулся с ситуацией, когда выше это не сработало. Это то, что я сейчас использую:
Сначала он вызывает gethostname, чтобы увидеть, возвращает ли он что-то похожее на имя хоста, если оно не использует мое исходное решение.
На самом деле вы можете посмотреть на весь результат в platform.uname()
Если я прав, вы ищете функцию socket.gethostname:
В некоторых системах имя хоста устанавливается в среде. Если это так, os module может вывести его из среды через os.getenv. Например, если HOSTNAME - это переменная среды, содержащая то, что вы хотите, следующее ее получит:
Обновление. Как отмечено в комментариях, это не всегда работает, поскольку не все настройки среды настроены таким образом. Я считаю, что в то время, когда я сначала ответил на это, я использовал это решение, поскольку это было первое, что я нашел в веб-поиске, и это работало для меня в то время. Из-за отсутствия переносимости я, вероятно, не использовал бы это сейчас. Однако я оставляю этот ответ для справки. FWIW, он устраняет необходимость в других импортах, если ваша среда имеет имя системы, и вы уже импортируете модуль os. Проверьте его - если он не работает во всех средах, в которых вы ожидаете, что ваша программа будет работать, используйте один из других предоставленных решений.
Если вы часто имеете дело с разными компьютерами, вам, конечно, нужен простой в использовании и быстрый инструмент для сбора информации о системе. Сегодня я покажу, как сделать программу, которая удаленно с помощью Python может получить из своей или чужой системы некоторые важные данные — от IP до модели процессора и отсылающую собранные данные в Telegram.
Чтобы просто посмотреть IP-адрес и другие настройки сети, вам придется обратиться к командной строке и выполнить команду ipconfig / all . Ситуация одна из самых частых для эникейщиков и удаленных шаманов, но она хотя бы быстро решаема. Но если придется собирать более серьезный набор информации о машине, с которой сейчас будете работать, — без автоматизации не обойтись. Этим мы сегодня и займемся.
Сбор информации о системе удаленно с помощью Python
Имейте в виду, что эта программа может использоваться как для быстрого сбора информации о своей системе, так и для кражи идентифицирующей информации с компьютера жертвы. Мы граждане законопослушные, поэтому пусть это и не пароли, но, чтобы не раздражать правоохранителей, все тесты будут проводиться на изолированных виртуальных машинах.
Инструменты
Сначала давайте разберемся, где будем писать код. Можно кодить в обычном виндовом «Блокноте», но мы воспользуемся специальной IDE для Python — PyCharm. Установка и настройка просты как два рубля: скачал установщик, запустил — и кликай себе «Далее», пока есть такая кнопка.
Еще нам потребуется Python. Я буду использовать версию 3.9.0 — с ней точно все работает.
Задачи
Давай сначала обрисуем, что мы вообще планируем делать. Я планирую собирать следующую информацию:
И отправляться это все будет прямиком вам в телегу через специальный бот.
Зачем?
Наверняка у вас возник вопрос: зачем может понадобиться MAC-адрес или модель процессора? Эти параметры меняются очень и очень редко, так что прекрасно подходят для фингерпринтинга. Даже если пользователь купит более быстрый интернет‑канал или поменяет часовой пояс, вы без особого труда сможете определить, что уже имел дело с этим компьютером. Стоит помнить, что ровно такие же методы используют хитрые рекламщики для идентификации пользователей, да и разработчики триальных версий программ тоже. Эта статья поможет чуть лучше понять, что можно узнать о вашем компьютере в полностью автоматическом режиме, а как применить эту информацию — решать только вам.
В этой статье мы не будем показывать, как сформировать устойчивый к незначительным изменениям идентификатор, который поможет однозначно определить конкретный компьютер. Если вам станет интересно — пишите в комментах, и, возможно, я напишу небольшую статью на эту тему!
Создаем основу программы
Для отправки данных я решил воспользоваться Telegram-ботом. Создать его вы можете через BotFather, а после сохранить token вашего творения. Публиковать его нельзя — любой, кто получит этот токен, сможет захватить контроль над вашим ботом.
Для подключения к Bot API «телеги» нужны всего две строчки:
Чтобы оценить быстродействие, можно написать еще пару строк. Весь дальнейший код расположим между ними. Описанное выше подключение бота уже вписано сюда.
Теперь перейдем собственно к сбору данных.
Сбор данных
Теперь кратко рассмотрим, что делает каждый модуль. Если какие‑то функции вам не нужны, выбросите строку импорта модуля и код, который использует этот модуль. Все просто!
Итак, за работу с ОС и локальными ресурсами отвечают эти 4 модуля:
Этими модулями реализованы сетевые взаимодействия:
Служебные примочки, которые трудно отнести к категориям выше:
После этого нам требуется узнать основные стабильные характеристики системы: IP- и MAC-адреса, имя пользователя и ОС:
Строки кода снабжены комментариями и в пояснениях не нуждаются.
Скорость интернет-соединения
Важно понимать, что замер не претендует на сверхточность, потому что мы никак не можем легко проверить, какую часть канала потребляют другие программы или даже другие устройства в сети. Если вы подключились к рабочей станции удаленно, ваше соединение тоже что‑то будет потреблять. В программе поправка на это не реализована из‑за ее слишком низкой точности и трудоемкости.
Часовой пояс и время
Частота процессора
Может помочь выявить причину тормознутости компьютера: если процессор постоянно молотит на полную, но программы виснут — процессор устарел, а если простаивает — виновата программа. Да и просто общее представление о железе дает.
Более глубокий фингерпринтинг
В этой статье умышленно не рассказывается, как получить идентификатор жесткого диска или GUID установленной Windows: мы не методичку для рекламщиков пишем, а программировать тренируемся. Тем не менее вы легко можете добавить сбор и такой информации, воспользовавшись консольной утилитой wmic . Ее вывод можно парсить с помощью Python-скрипта, так что даже не придется писать лишние обвязки. На скриншоте пример получения серийного номера BIOS.
Скриншот рабочего стола
Тут все тоже максимально просто, а за собственно снятие скриншота отвечает только последняя строка кода. Остальное мы используем для корректной обработки входящей команды бота.
Запись в файл
Теперь, когда все готово, мы можем приступать к финальному сбору и отправке данных. Создаем готовый файл с нашими данными: если использовался максимальный сбор информации, а точнее весь код выше, то используем такую запись, в противном случае убирайте ненужные вам данные:
Длинный, но легко читаемый код. Первая его часть обеспечивает обработку команды / start , вторая — запись всех данных в файл. Результат попадет в info. txt , но путь, конечно, можно изменить прямо в коде.
Дело остается за малым — отправить результат в Telegram.
Отправка данных
Теперь дополним код выше, чтобы он еще и файлы отправлял.
Сначала указывается подпись к скриншоту, потом читаем и отправляем файлы в виде фото и документа, затем зачищаем следы и закрываем соединение с ботом. Ничего сложного!
Естественно, если нам не нужен, к примеру, скриншот, мы можем вырезать код его отправки, получив такой вариант:
Также следует учесть одну деталь: перед запуском программы вы должны отправить своему боту команду /start, чтобы он понял, кому следует отправлять данные.
Собираем программу
Чтобы не тянуть с собой на другой компьютер Python и зависимости программы, давайте упакуем все в один исполняемый файлик. Делается это с помощью PyInstaller, который ставится простой командой pip install pyinstaller .
Переходим с помощью командной строки в папку с нашей программой и собираем ее командой
Аргумент --onefile заставит PyInstaller упаковать все в единственный файл. После -i надо указать путь до иконки исполняемого файла, если вы хотите ее использовать. Если она не нужна, просто удалите этот аргумент. Последним идет путь к файлу с нашим кодом. Если вы не хотите, чтобы при запуске появлялась консоль (например, если владелец компьютера не знает, что вы собрались ему помочь :D), поменяйте расширение входного файла с кодом на . pyw или укажите опцию -w .
Не забывайте проверять наличие модулей и их обновлений, чтобы избежать ошибок. Временный путь можно указать любой, но лично я указываю C:\ Temp . Само собой, если обнаружена ОС на базе Linux, то этот код придется поправить.
Еще следует проверить, как сильно и чем детектится наш файл. Чтобы вам не лезть на VirusTotal, я сделал это сам.
Результат сканирования на VirusTotal
Полный код проекта я разместил на GitHub. Там есть и программа‑сборщик, о которой я расскажу ниже.
Пишем сборщик с графическим интерфейсом
Для создания GUI сборщика нам придется работать с библиотекой Tkinter, поэтому прежде всего импортируем ее и нужные элементы:
После этого нужно создать окно, которое и будет основой интерфейса:
Нам нужен только ввод API-ключа для доступа к боту. Делается такой ввод кодом ниже:
Это создаст два графических объекта — поле ввода и подпись к нему.
В этом интерфейсе не хватает кнопки для сборки выходного файла. Давайте создадим ее:
Создаем функцию, которая должна находиться в файле после импорта библиотек. В ней мы должны создавать файл и записывать в него код полезной нагрузки.
Не шутите с пробелами! Перед тем как вставлять код, убедитесь, что там нет лишних пробелов, иначе может возникнуть трудно обнаружимая ошибка.Но на этом наша функция не заканчивается, так как нужно дать пользователю понять, готов ли файл. Делаем это с помощью MessageBox:
Теперь осталось только запустить отрисовку и обработку сообщений строкой root. mainloop( ) .
Опционально можно собрать и сборочный интерфейс. Для этого используем старый добрый PyInstaller:
И все готово! Теперь вы имеете полноценную программу для сбора данных о системе и ее сборщик, который ускорит процесс работы.
Каждый раз прибегать к PyInstaller, чтобы собрать программу, не слишком удобно. Можно воспользоваться модулем os и вызывать PyInstaller автоматически.
Если вам понадобилась иконка, можно добавить в команду сборки параметр -i file. ico , а для сборки «невидимой» программы дописать -w — ровно как при ручной сборке!
Вывод
В этой статье мы разобрали от начала и до конца, как вытащить из своей или чужой системы некоторые важные данные — от IP до модели процессора. Конечно, главное тут в том, что вы научились хоть немного писать код самостоятельно — а применить всегда куда‑нибудь получится.
Если заинтересовались программированием на Python — почитайте нашу статью о написании простого вируса, она станет отличным закреплением навыков программирования. Успехов!
Читайте также: