Функции являются модулями, из которых создаётся программа. Существуют, по крайней мере, две веские причины использовать функции: во-первых, они существенно упрощают разработку, отладку и поддержку программ, во-вторых, они могут позволить избежать дублирования кода. При грамотном использовании функций в программах отсутствуют запутанные логические конструкции, глубоко вложенные циклы и прочие нежелательные вещи. В конечном счете, использование функций делает программу легко читаемой и понятной даже программисту, который не участвовал в её разработке.
Функция – это часть программы (или подпрограмма), которая решает одну конкретную задачу. Точнее, данное определение относится к грамотно написанной функции, но именно к проектированию таких функций мы и стремимся. Функция может производить какие-то вычисления и возвращать полученный результат, а может просто выполнять последовательность действий и ничего не возвращать. Функция, которая не возвращает значения, в некоторых языках программирования называется процедурой. В объектно-ориентированном программировании функции называются методами.
Основы Программирования — #4 — Функции
Функцию часто представляют в виде черного ящика, который принимает что-то на вход и возвращает что-то на выходе.
Определение и вызов функции
Функции предназначены для того, чтобы их вызывать, а перед вызовом их требуется определить. Рассмотрим, как это делается. Для примера создадим функцию, которая приветствует пользователя на трёх разных языках.
//Определение функции
Void say_hello()
//Вызов функции
Разберём подробно эту программу. В данном случае функция не принимает никаких аргументов и не возвращает никакого значения: она просто выполняет некоторые действия, точнее, выводит три приветствия. Фактически мы просто назвали группу из трёх команд
именем say_hello(). После этого для выполнения этих команд достаточно вызвать функцию, другими словами, указать её имя, а не писать эти три команды. Таким образом, программа
Int main()
return 0;
Выполнит те же действия, что и программа
int main()
return 0;
Заметим, что рассмотренная функция say_hello(), работает всегда одинаково. Рассмотрим теперь функцию, которая может работать по-разному от вызова к вызову. Создадим функцию, которая принимает в качестве аргумента целое число n и выводит на экран n звёздочек.
using namespace std;
void drawStars(int n)
for (int i=1; i
int main()
drawStars(10);
return 0;
Следующая функция вычисляет среднее арифметическое трех чисел и возвращает это значение
float average(float x, float y, float z)
float sum = x+y+z;
return sum/3.0;
int main()
Определение функции состоит из нескольких частей:
- тип возвращаемого значения;
- название функции;
- формальные параметры;
- тело функции;
- оператор return.
Источник: studfile.net
Функции в Python за 1 минуту / Functions in Python in 1 minute
16 лучших практик для написания читаемого кода: что нужно знать любому программисту перед устройством на работу и не только
Читаемость кода — универсальный показатель в мире программирования. Это одна из первых вещей, которые должен знать разработчик. В этой статье мы рассмотрим 16 лучших практик, которые помогают писать более читаемый код.
Публикуем перевод, сделанный для Tproger международной IT-компанией Noveo.
1. Комментирование и документация
За последние 5 лет среды разработки (IDE) прошли большой путь. Это сделало комментирование кода важным как никогда. Использование определённых стандартов комментирования позволяет среде разработки и другим инструментам использовать комментарии определённым образом.
Рассмотрим этот пример:
Комментарий, который я добавил при определении функции, можно просматривать каждый раз, когда я использую функцию, даже из другого файла.
Вот ещё один пример, где я вызываю функцию из сторонней библиотеки:
2. Последовательные отступы
Я думаю, вы уже знаете, как расставлять отступы в коде. В любом случае, нужно напомнить, что последовательность в отступах будет хорошей идеей.
Есть несколько вариантов выставления отступов:
Стиль 1:
function foo() < if ($maybe) < do_it_now(); again(); >else < abort_mission(); >finalize(); >
Стиль 2
function foo() < if ($maybe) < do_it_now(); again(); >else < abort_mission(); >finalize(); >
Стиль 3
function foo() < if ($maybe) < do_it_now(); again(); >else < abort_mission(); >finalize(); >
Раньше я использовал второй стиль, но недавно перешёл на первый. Впрочем, это дело вкуса. Не существует “лучшего” стиля, которого должны придерживаться все без исключения. На самом деле лучший стиль — это последовательный стиль.
Если вы участвуете в проекте в составе команды, необходимо придерживаться стиля, который уже используется на проекте.
Стили отступов не всегда можно отличить друг от друга: иногда смешиваются различные правила. Например, в PEAR Coding Standards открывающая скобка (“<“) остаётся на той же строке, что и контролирующие структуры, но переносится на следующую строку при определении функций.
Стиль PEAR:
function foo() < // placed on the next line if ($maybe) < // placed on the same line do_it_now(); again(); >else < abort_mission(); >finalize(); >
Также можно отметить, что вместо табуляции для отступов используется четыре пробела.
Здесь находится статья Википедии, где можно прочитать о различных стилях отступов. А здесь вы можете найти отличный инструмент, который позволяет создать единый формат настроек и раз и навсегда решить вопросы вроде “табы или пробелы” для всех IDE и всех языков программирования.
3. Избегайте очевидных комментариев
Комментировать код — это просто прекрасно, но иногда комментарии становятся необязательными или попросту лишними.
Возьмём этот пример:
// get the country code $country_code = get_country_code($_SERVER[‘REMOTE_ADDR’]); // if country code is US if ($country_code == ‘US’) < // display the form input for state echo form_input_state(); >
Когда текст настолько очевиден, нет смысла дублировать его комментарием.
Если же комментарий необходим, можно сделать это одной строкой:
// display state selection for US users $country_code = get_country_code($_SERVER[‘REMOTE_ADDR’]); if ($country_code == ‘US’)
4. Группировка кода
Как правило, для выполнения определённых задач требуется несколько строк кода. Разумным будет оформлять такие задачи как отдельные блоки с разрывами между ними.
// get list of forums $forums = array(); $r = mysql_query(«SELECT id, name, description FROM forums»); while ($d = mysql_fetch_assoc($r)) < $forums []= $d; >// load the templates load_template(‘header’); load_template(‘forum_list’,$forums); load_template(‘footer’);
Последовательность в наименованиях
PHP сам не всегда бывает последовательным в наименованиях:
- strpos() при str_split()
- imagetypes() при image_type_to_extension()
Прежде всего, в именах должны быть различимы граница слов. Есть два популярных варианта:
- camelCase: заглавной становится первая буква каждого слова, кроме первого.
- Нижнее_Подчёркивание: слова разделяются нижним подчёркиванием, например, mysql_real_escape_string().
Существование нескольких опций создаёт ту же ситуацию, что и с отступами. Если на проекте уже существуют договорённости, нужно им следовать. Помимо того, некоторые платформы стремятся к использованию определённого стиля.
Например, большая часть проектов на Java использует camelCase, в то время как в PHP более популярно нижнее подчёркивание.
Здесь также возможно смешение. Некоторые разработчики используют нижнее подчёркивание для функций и названий классов, но предпочитают camelCase при написании названий методов класса:
Повторюсь: нет «лучшего» стиля. Просто будьте последовательны.
5. Принцип DRY
DRY — аббревиатура от английского Don’t Repeat Yourself (не повторяйтесь). Иногда используется вариант DIE — Duplication Is Evil (повторение — это зло).
Принцип гласит: «Каждый элемент знания должен иметь в системе единственное, не вызывающее сомнений и авторитетное значение».
Цель большинства приложений (или компьютеров в целом) — автоматизировать повторяющиеся задачи. Этого принципа нужно придерживаться в любом коде, даже когда речь идёт о веб-приложениях. Один фрагмент не должен повторяться в коде снова и снова.
Например, бОльшая часть веб-приложений состоит из нескольких страниц. Вероятность того, что эти страницы будут содержать одинаковые элементы, весьма высока. Обычно для этой цели используются header и footer. Не самой лучшей идеей будет копировать их для каждой страницы.
Вот как создаются шаблоны в CodeIgniter:
$this->load->view(‘includes/header’); $this->load->view($main_content); $this->load->view(‘includes/footer’)
6. Избегайте глубокой вложенности кода
Слишком большое количество уровней вложения затрудняет чтение и понимание кода.
function do_stuff() < // . if (is_writable($folder)) < if ($fp = fopen($file_path,’w’)) < if ($stuff = get_some_stuff()) < if (fwrite($fp,$stuff)) < // . >else < return false; >> else < return false; >> else < return false; >> else < return false; >>
Ради удобства чтения можно изменить код, чтобы уменьшить количество уровней вложения:
function do_stuff() < // . if (!is_writable($folder)) < return false; >if (!$fp = fopen($file_path,’w’)) < return false; >if (!$stuff = get_some_stuff()) < return false; >if (fwrite($fp,$stuff)) < // . >else < return false; >>
7. Ограничьте длину строки
Нашим глазам удобнее читать длинные и узкие колонки текста. Именно поэтому статьи в газетах обычно выглядят так:
Избегать длинных строк кода — хорошая практика.
Кроме того, если кому-то потребуется читать код из окна терминала (как, например, пользователям Vim), то будет разумно ограничить длину строки 80 символами.
8. Организация файлов и папок
Технически возможно написать приложение полностью в одном файле. Но чтение и поддержка такого проекта превратятся в кошмар.
На своих первых проектах я знал об идее создания «включённых файлов», но я тогда был не очень организованным человеком. Я создал папку “inc” с двумя файлами: db.php и functions.php. Но приложения росли, файл с функциями стал огромным, и поддерживать его стало невозможно.
Чтобы избежать этого можно или использовать фреймворк, или имитировать файловую структуру. Вот так, например, выглядит CodeIgniter:
10. Последовательность во временных именах
Как правило, названия переменных описывают их суть и состоят из нескольких слов. Но это не всегда относится ко временным переменным, которые иногда могут состоять из одного символа.
Нужно поддерживать последовательность имён для временных переменных, у которых есть определённая роль. Вот несколько примеров, которые я использую в коде:
// $i for loop counters for ($i = 0; $i < 100; $i++) < // $j for the nested loop counters for ($j = 0; $j < 100; $j++) < >> // $ret for return variables function foo() < $ret[‘bar’] = get_bar(); $ret[‘stuff’] = get_stuff(); return $ret; >// $k and $v in foreach foreach ($some_array as $k => $v) < >// $q, $r and $d for mysql $q = «SELECT * FROM table»; $r = mysql_query($q); while ($d = mysql_fetch_assocr($r)) < >// $fp for file pointers $fp = fopen(‘file.txt’,’w’);
11. Пишите специальные слова SQL заглавными буквами
Взаимодействие с базой данных — существенная часть большинства веб-приложений. Если вы пишете SQL-запросы, то будет разумно сделать читаемыми и их.
Несмотря на то, что специальные слова и названия функций SQL нечувствительны к регистру, их обычно пишут заглавными буквами, чтобы отличать от названий таблиц и колонок.
SELECT id, username FROM user; UPDATE user SET last_login = NOW() WHERE SELECT id, username FROM user u LEFT JOIN user_address ua ON(u.id = ua.user_id) WHERE ua.state = ‘NY’ GROUP BY u.id ORDER BY u.username LIMIT 0,20
12. Разделение кода и данных
Это ещё один принцип, который относится практически ко всем языкам программирования во всех средах разработки. В случае веб-разработки «данные» обычно обозначают вывод HTML.
Много лет назад, во время первого релиза PHP, это было реализовано как движок шаблонов. Тогда HTML-файлы с несколькими строчками на PHP были привычным делом. В любом случае, с течением времени ситуация сильно изменилась и сайты стали более динамичными и функциональными. Сейчас код составляет значительную часть веб-приложений, и соединять его с HTML уже будет неразумно.
Вы можете или самостоятельно применить этот принцип к своему приложению, или использовать сторонние инструменты (шаблонизаторы, фреймворки, CMS) и следовать их договорённостям.
Популярные PHP фреймворки:
- CodeIgniter
- Zend Framework
- Cake PHP
- Symfony
13. Изменяйте синтаксис внутри шаблонов
Вы можете не использовать модные шаблонизаторы, ограничиваясь плоским PHP внутри своих файлов шаблонов. Это не обязательно будет нарушением принципа разделения кода и данных, если вложенный код напрямую относится к выводу и он читаем. В таком случае вам будет нужно изменить синтаксис для контрольных структур.
Hello, username; ?>
|
My Message Board
title; ?>
Forums as $forum): ?>
id, $forum->title) ?> (Threads->count(); ?> threads)
description; ?>
Это позволяет избежать многих фигурных скобок. Кроме того, по отступам и структуре код становится похож на HTML-разметку.
14. Объектно-ориентированное против процедурного
Объектно-ориентированное программирование позволяет писать хорошо структурированный код, но это не значит, что вы должны полностью отказаться от процедурного программирования. На самом деле смешивание этих подходов может дать хорошие результаты.
Объекты можно использовать для представления данных, обычно они располагаются в базе данных.
class User < public $username; public $first_name; public $last_name; public $email; public function __construct() < // . >public function create() < // . >public function save() < // . >public function delete() < // . >>
Процедуры и функции можно использовать для отдельных задач, которые могут выполняться отдельно.
function capitalize($string)
15. Читайте Open Source код
Open Source проекты создаются как результат труда многих людей. Такие проекты должны быть очень доступными для чтения, чтобы команда могла работать максимально эффективно.
Следовательно, будет очень полезно просматривать код таких проектов, чтобы понять, какие методики применяют их разработчики.
16. Рефакторинг
Когда вы проводите рефакторинг, то меняете код, не изменяя возможности системы. Это можно представить как “чистку” кода для повышения читаемости и качества.
Рефакторинг не относится к багфиксингу или добавлению функционала. Можно рефакторить код, который был написан вчера, пока он ещё свеж в вашей голове, чтобы он был более читаемым и доступным для переиспользования, когда вы вернётесь к нему два месяца спустя. Как гласит старая истина «рефакторьте раньше, рефакторьте чаще».
Вы можете использовать любые из перечисленных «лучших практик» в процессе рефакторинга.
Перевод подготовлен международной IT-компанией Noveo.
Источник: tproger.ru
Груг против сложности. Я пролинтил все посты на Хабре про Python, и вот что я нашёл
Простите, я не могу так больше. Я слишком хорошо знаю Python, чтобы молчать при виде такого кода.
Я устал. Я не могу это читать. Простите за токсичную критику, накипело.
Самое забавное, что, по моим ощущениям, везде я вижу одни и те же классы проблем. Я даже запилил сервис, где можно закинуть код и получить код ревью, и, собрав немного статистики, понял, что 50 типов ошибок достаточно, чтобы покрыть большую часть проблем в чужом коде. Но выборка у меня была небольшая, и я подумал: а что, если проверить много кода? И всё заверте.
Давайте вспомним про гругов
Где-то тут проскакивала замечательная статья про гругов: на русском, на английском.
разработчик с мозгом груга не очень умный, но разработчик с мозгом груга программирует много лет и научился кое чему, хоть всё равно часто запутывается
Я как прочитал её, так сразу и понял: это я. Не очень умный программист, но за плечами горы опыта, и это формирует мой подход к написанию кода: не усложняй. На работе у нас есть чел — большая голова, он держит весь проект в своей «оперативной памяти» и пишет просто полотна кода с кучей ветвлений, и где-то в конце он ещё помнит, что в начале был if и нужно рассмотреть else. Я так не могу, я когда прыгаю jump-to-definition, на четвёртом уровне вложенности уже забываю, откуда я пришёл и что я делал. Я как бельчонок с хорошеньким хвостиком, если вы понимаете, о чём я.
Что же касается бельчонка, то он сидел в лесной чаще и рассеянно поглядывал то на одно дерево, то на другое. Он не мог, даже если бы пришлось пожертвовать своим хвостиком, вспомнить, в дупле какого дерева он жил и вообще ради чего он прискакал в лес и что там искал.
Я не могу писать большие и сложные штуки, а если и напишу, то там же и умру. Поэтому философия гругов мне очень подходит:
главный охотник на груга это сложность
сложность плохо
скажу снова:
сложность очень плохо
теперь ты скажи сам:
сложность очень, очень плохо
если выбрать между сложность и биться с динозавром, груг выбери динозавр: груг хотя бы видеть динозавра
И в этой статье я хотел немного поделиться тем, как можно бороться со сложностью в питоне.
Разработчик с мозгом груга хочет собрать знания в маленькую, простую и интересную страницу
Если вы умный
. то всё равно нужно стремиться упрощать. Потому что если вы пишете статью или вкладываете что-то в опенсорс, ваш код (внезапно) читают и/или запускают. Давайте заботиться о пользователях вашего кода? Кстати, пользователем вашего когда можете стать вы сами через несколько лет.
Что значит «упрощать» и «заботиться о пользователях»?
Я понимаю это как написание кода, который
- легко читать
- легко изменять
- легко отлаживать
- легко тестировать
Как писать такой код? Использовать линтеры и мозг, чтобы уменьшать сложность. Давайте обсудим типичные ошибки и антипаттерны.
Ты не сможешь рассмотреть все возможные ошибки
Действительно, выстрелить себе в ногу можно миллионом способов, особенно в динамически типизированном языке. Но мне поможет мой хоуми aka Николай Гумилёв Вильфредо Парето.
Закон Парето
- В большинстве случаев около 80% результата происходят из 20% причин.
- А вдруг мы можем рассмотреть топ 20% ошибок и надеяться, что покроем 80% случаев?
А как ты узнаешь самые распространённые ошибки?
Вообще не всё можно отловить программно. Например, плохой дизайн классов и модулей. Как-то я видел что-то вроде:
Не знаю, какой там был контекст, но если в зависимости от какого-то параметра вызывается либо родительский метод, либо метод наследника, то, возможно, где-то на уровне выше нужно было в зависимости от параметра передать либо объект родителя, либо объект наследника — наследование так и работает, оно переопределяет метод, вместо того чтобы заставлять вас писать if . Как подобное отлавливать — я не знаю. Это самый интересный класс ошибок, но в этой статье их не будет, сорян.
Итак, как автоматически искать ошибки? Для этого я построю вундервафлю, прям как аннигилятор в «Полицейский из Беверли-Хиллз 3».
Если эта штука напоминает вам flake8 с плагинами, то вы угадали — это он и есть.
Почему не pylint | mypy | dlint | black | . Мне нужен был линтер (не форматтер), в котором есть максимальное число подходящих мне плагинов, и для которого я мог бы легко написать свои. Flake8 мне показался наиболее подходящим.
Итак, я прошёлся по awesome flake8, поскрёб по закоулкам гитхаба, написал свой мини-плагин с тем, чего не хватало, и получилось вот это:
flake8==5.0.4 flake8-json==21.7.0 flake8-adjustable-complexity==0.0.6 flake8-annotations-coverage==0.0.6 flake8-annotations==2.9.1 flake8-builtins==1.5.3 flake8-cognitive-complexity==0.1.0 flake8-commas==2.1.0 flake8-comprehensions==3.10.0 flake8-eradicate==1.3.0 flake8-expression-complexity==0.0.11 flake8-functions==0.0.7 flake8-simplify==0.19.3 flake8-scream==0.1.0 git+https://github.com/i02sopop/flake8-global-variables pep8-naming==0.13.1 flake8-bugbear==22.7.1 flake8-pie==0.16.0 flake8-print==5.0.0 flake8-use-pathlib==0.3.0 git+https://github.com/c0ntribut0r/flake8-grug pylint==2.14.5 flake8-pylint==0.1.3
Я постарался отобрать те плагины, которые сделают код чище, но не стал включать спорные штуки (например, всякие следилки за докстрингами) и базовые и очевидные вещи (форматирование, всякие там отступы и пробелы). Даже среди того, что я выбрал, было много мусора, поэтому я отбирал ошибки поштучно, если интересно — вот мой .flake8 , он человекочитаем:
Маленькие открытия, пока я всё это собирал:
- Нашёл репо от команды BestDoctor. Они написали несколько плагинов для flake8, плюс вообще у них приятно — рекомендую python styleguide и погулять по репе. BestDoctor, оплату переводите на карту, как и договаривались.
- flake8-simplify тоже вполне хорош, я джва года искал набор таких правил
- Всякие code quality tools живут в PyCQA, могут пригодиться
- Аннигилятор уже изобрели в wemake, но мне не все правила подходили, и у него фатальный недостаток
Когда после всех настроек я запустил аннигилятор, я понял: я создал такого же брюзгу, как я. Ура!
И когда мой мега-линтер начал подсвечивать мой собственный код и бесить меня, я понял: он готов к работе.
Время запускать аннигилятор
Всё началось со статей Хабра, поэтому я решил соскрапать их все и скормить flake8. Я написал простую обёртку над Хабром и оставил на ночь. А потом запустил аннигилятор на всех постах.
Источник: habr.com