Page 1 of 1

Файл с текстом параграфа

Posted: Wed Jun 10, 2026 7:46 pm
by Поляков
Скачать файл: Подпрограммы

Re: Файл с текстом параграфа

Posted: Tue Jun 16, 2026 7:16 am
by nikolay
1. В функции binary явная опечатка: в строке 2 условие записано как if s == 0: return '0'.

2. В тексте к isPrime сначала приводится вариант с диапазоном range(2, n), а затем добавляется if n < 2: return False и оптимизация до корня. Возможно стоит конеретизировать куда добавлять эти условия?

3. Возможно в оптимизации до корня стоило бы сделать акцент, что округление вверх/вниз здесь не принципиально, важно только, чтобы верхняя граница была не меньше корня из n. Т.е. можно написать и int(n**0.5).

Re: Файл с текстом параграфа

Posted: Tue Jun 16, 2026 7:54 pm
by bonzo
От меня нет особых комментариев, более системные (низкоуровневые) вещи рассказывать в имеющихся ограничениях, кажется, не стоит (про библиотеки, модули и т.п. можно было бы сказать со звездочкой, но конкретно мне нечего предложить, я очень плохо знаю питон).

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

Re: Файл с текстом параграфа

Posted: Wed Jun 17, 2026 1:42 pm
by Neket
1. Мне кажется странным, что вводится понятие локальной переменной без упоминания глобальных переменных. Естественным кажется определение через противопоставление: параметры функции и переменные, которые присваиваются внутри функции, являются локальными, и их можно использовать только внутри этой функции, а переменные, которые только используются внутри функции, или объявлены с ключевым словом global являются глобальными, и могут использоваться за пределами функции, сохраняя при этом свое значение. При этом для языка питон важно опять провести разграничение между присваиванием и другими способами использования переменной, так как это влияет на то, будет ли переменная локальной или глобальной. Упоминание концепции времени жизни переменной, на мой взгляд, как раз таки можно опустить. И ограничиться только тем, что если переменная глобальная, то одно и то же имя в разных функциях ссылается на одну и ту же переменную, а если локальная -- то на разные.

P.S. Дошел до пункта про локальные и глобальные переменные, в котором содержится большая часть описанных мною вещей. С точки зрения последовательности изложения, я бы лучше поднял его наверх. Не увидел каких-то принципиальных вещей в предшествующих ему пунктах, которые требуются для его понимания.

2. Мне показалась не очень понятной фраза "при определении функции её код не выполняется, ...". Если я правильно понял, какую мысль хотел выразить автор, то возможно лучше сказать конкретнее, что интерпретатор читает файл сверху вниз и начинает выполнение с первой встреченной им инструкции. Однако выполнение функции происходит не в тот момент, когда она была прочитана, а когда она была вызвана в коде, причем при каждом вызове она выполняется заново.

3. Возможно, стоит сказать, что вычисление аргументов функции происходит до ее вызова.

4. Возможно, стоит сказать, что вызов функции также является операцией, так как имеет значение. Тогда и то что значение функции можно сразу вывести на экран, и то что его можно использовать в выражениях, становится естественным.

5. Определение простоты не вполне корректное -- простое число имеет ровно два делителя. Под указанное в учебнике определение подходит единица, не являющаяся простым числом.

6. Обоснование добавление строки if n < 2: return false в функцию я бы объяснил более подробно. Например, так как по определению простыми числами могут быть только натуральные числа (чего кстати в приведенном определении тоже нет, хотя должно быть), а единица заведомо не является простым числом, можно сразу отсечь все числа, меньшие чем 2.

7. Категоричное утверждение о том, что программисты всегда стараются писать чистые функции, меня немного напрягает. Очевидно, что все функции программы не могут быть чистыми. С описанной далее мотивацией про простоту отладки и поддержки я согласен, я бы возможно немного смягчил формулировку, поменяв порядок предложений. Сначала сказал бы, что такое чистая функция, потом -- что их проще поддерживать и исправлять, затем -- что вычисления рекомендуется делать при помощи чистых функций, отделяя их таким образом от "нечистых", в которых происходит взаимодействие с внешним миром.

8. В пункте про функции, не имеющие результата, в последнем абзаце пропущено "нет" во фрагменте "вообще оператора return". В том же абзаце, наверное, слово значение следует заменить на выражение (ранее как раз говорилось, что после return идет выражение).

Re: Файл с текстом параграфа

Posted: Thu Jun 18, 2026 12:49 pm
by Поляков
nikolay wrote: Tue Jun 16, 2026 7:16 am 1. В функции binary явная опечатка: в строке 2 условие записано как if s == 0: return '0'.
Спасибо, исправлено.
nikolay wrote: Tue Jun 16, 2026 7:16 am 2. В тексте к isPrime сначала приводится вариант с диапазоном range(2, n), а затем добавляется if n < 2: return False и оптимизация до корня. Возможно стоит конеретизировать куда добавлять эти условия?
Исправлено.
nikolay wrote: Tue Jun 16, 2026 7:16 am 3. Возможно в оптимизации до корня стоило бы сделать акцент, что округление вверх/вниз здесь не принципиально, важно только, чтобы верхняя граница была не меньше корня из n. Т.е. можно написать и int(n**0.5).
Я боюсь ситуации, когда в результате вычисления с вещественными числами получится 25**0.5 = 4,99999999999 и int(.) = 4. Тогда пролетим. Поэтому лучше round.

Re: Файл с текстом параграфа

Posted: Thu Jun 18, 2026 12:51 pm
by Поляков
bonzo wrote: Tue Jun 16, 2026 7:54 pm В целом можно где-нибудь сказать, что пользовательские функции, по сути, расширяют язык исполнителя, вводя новые операции, которыми становится можно пользоваться наряду с имеющимися встроенными (а также что встроенные операции, в свою очередь, в своей реализации для более низкоуровневого исполнителя могут оказаться функциями, как у Вас и отмечено про функции ввода и пр.).
Добавил, спасибо.

Re: Файл с текстом параграфа

Posted: Thu Jun 18, 2026 1:09 pm
by Поляков
Neket wrote: Wed Jun 17, 2026 1:42 pm 1. Мне кажется странным, что вводится понятие локальной переменной без упоминания глобальных переменных. Естественным кажется определение через противопоставление: параметры функции и переменные, которые присваиваются внутри функции, являются локальными, и их можно использовать только внутри этой функции, а переменные, которые только используются внутри функции, или объявлены с ключевым словом global являются глобальными, и могут использоваться за пределами функции, сохраняя при этом свое значение. При этом для языка питон важно опять провести разграничение между присваиванием и другими способами использования переменной, так как это влияет на то, будет ли переменная локальной или глобальной. Упоминание концепции времени жизни переменной, на мой взгляд, как раз таки можно опустить. И ограничиться только тем, что если переменная глобальная, то одно и то же имя в разных функциях ссылается на одну и ту же переменную, а если локальная -- то на разные.
P.S. Дошел до пункта про локальные и глобальные переменные, в котором содержится большая часть описанных мною вещей. С точки зрения последовательности изложения, я бы лучше поднял его наверх. Не увидел каких-то принципиальных вещей в предшествующих ему пунктах, которые требуются для его понимания.
Так лучше укладывается с логику объяснения. Как только возникает проблема, она объясняется. Говорить про то, что параметры можно использовать только в теле функции, нужно сразу. Тут и возникает понятие локальной переменной. А глобальные в этой точке еще не актуальны.
Neket wrote: Wed Jun 17, 2026 1:42 pm 2. Мне показалась не очень понятной фраза "при определении функции её код не выполняется, ...". Если я правильно понял, какую мысль хотел выразить автор, то возможно лучше сказать конкретнее, что интерпретатор читает файл сверху вниз и начинает выполнение с первой встреченной им инструкции. Однако выполнение функции происходит не в тот момент, когда она была прочитана, а когда она была вызвана в коде, причем при каждом вызове она выполняется заново.
Имелось ввиду, что когда интерпретатор обработал def, в памяти уже есть объект-функция. Но она еще не выполнялась.
Neket wrote: Wed Jun 17, 2026 1:42 pm 3. Возможно, стоит сказать, что вычисление аргументов функции происходит до ее вызова.
Не совсем понял. А как иначе? Когда они могут вычисляться?
Neket wrote: Wed Jun 17, 2026 1:42 pm 4. Возможно, стоит сказать, что вызов функции также является операцией, так как имеет значение. Тогда и то что значение функции можно сразу вывести на экран, и то что его можно использовать в выражениях, становится естественным.
Я думаю, что это теоретизирование только запутает. Показанные примеры достаточны.
Neket wrote: Wed Jun 17, 2026 1:42 pm 5. Определение простоты не вполне корректное -- простое число имеет ровно два делителя. Под указанное в учебнике определение подходит единица, не являющаяся простым числом.
Исправлено.
Neket wrote: Wed Jun 17, 2026 1:42 pm 6. Обоснование добавление строки if n < 2: return false в функцию я бы объяснил более подробно. Например, так как по определению простыми числами могут быть только натуральные числа (чего кстати в приведенном определении тоже нет, хотя должно быть), а единица заведомо не является простым числом, можно сразу отсечь все числа, меньшие чем 2.
Исправлено.
Neket wrote: Wed Jun 17, 2026 1:42 pm 7. Категоричное утверждение о том, что программисты всегда стараются писать чистые функции, меня немного напрягает. Очевидно, что все функции программы не могут быть чистыми. С описанной далее мотивацией про простоту отладки и поддержки я согласен, я бы возможно немного смягчил формулировку, поменяв порядок предложений. Сначала сказал бы, что такое чистая функция, потом -- что их проще поддерживать и исправлять, затем -- что вычисления рекомендуется делать при помощи чистых функций, отделяя их таким образом от "нечистых", в которых происходит взаимодействие с внешним миром.
Исправлено.
Neket wrote: Wed Jun 17, 2026 1:42 pm 8. В пункте про функции, не имеющие результата, в последнем абзаце пропущено "нет" во фрагменте "вообще оператора return". В том же абзаце, наверное, слово значение следует заменить на выражение (ранее как раз говорилось, что после return идет выражение).
Исправлено.

Спасибо за отзыв и предложения.

Re: Файл с текстом параграфа

Posted: Thu Jun 18, 2026 1:45 pm
by Neket
Поляков wrote: Thu Jun 18, 2026 1:09 pm
Neket wrote: Wed Jun 17, 2026 1:42 pm 1. Мне кажется странным, что вводится понятие локальной переменной без упоминания глобальных переменных. Естественным кажется определение через противопоставление: параметры функции и переменные, которые присваиваются внутри функции, являются локальными, и их можно использовать только внутри этой функции, а переменные, которые только используются внутри функции, или объявлены с ключевым словом global являются глобальными, и могут использоваться за пределами функции, сохраняя при этом свое значение. При этом для языка питон важно опять провести разграничение между присваиванием и другими способами использования переменной, так как это влияет на то, будет ли переменная локальной или глобальной. Упоминание концепции времени жизни переменной, на мой взгляд, как раз таки можно опустить. И ограничиться только тем, что если переменная глобальная, то одно и то же имя в разных функциях ссылается на одну и ту же переменную, а если локальная -- то на разные.
P.S. Дошел до пункта про локальные и глобальные переменные, в котором содержится большая часть описанных мною вещей. С точки зрения последовательности изложения, я бы лучше поднял его наверх. Не увидел каких-то принципиальных вещей в предшествующих ему пунктах, которые требуются для его понимания.
Так лучше укладывается с логику объяснения. Как только возникает проблема, она объясняется. Говорить про то, что параметры можно использовать только в теле функции, нужно сразу. Тут и возникает понятие локальной переменной. А глобальные в этой точке еще не актуальны.
Просто как только возникает понятие локальной прееменной, возникает и вопрос "а как по-другому?" И глобальные переменные сразу становятся актуальны.

В целом я согласен, что разговор про глобальные переменные можно и отложить. Однако мне кажется важным, чтобы в этот момент не возникло неправильное понимание, что переменная res локальная, так как она встретилась внутри функции. И следовательно все переменные, которые встречаются внутри функции -- локальные, а глобальных не существует.

В пункте про глобальные переменные, они определяются как "введенные в основной программе" (а локальные как "введенные в функции"). При этом понятие "введенная переменная" не формализовано, и может быть трактовано по-разному. Например как "встретилась в коде в первый раз, когда я его читаю сверху вниз". Скорее всего, имелось в виду "проинициализированная", "получившая свое значение в результате присваивания", но и это не совсем корректно. Во-первых, переменную можно явно объявить глобальной внутри функции при инициализации (про ключевое слово global сказано позднее, но как про способ получить доступ к уже существующей глобальной переменной, хотя на самом деле этой переменной могло и не существовать ранее). Во-вторых, переменные с одним и тем же именем могут получить свое значение и в основной программе, и внутри функции одновременно -- и тогда это будут разные переменные, что неочевидно из текста учебника.
Поляков wrote: Thu Jun 18, 2026 1:09 pm
Neket wrote: Wed Jun 17, 2026 1:42 pm 3. Возможно, стоит сказать, что вычисление аргументов функции происходит до ее вызова.
Не совсем понял. А как иначе? Когда они могут вычисляться?
Я имел в виду, что побочные эффекты от вычисления аргументов функции уже наступили в момент ее вызова. Особенно это принципиально, когда возникает пример, где аргументов функции является результат вызова другой функции. Хотя возможно это слишком сложная мысль, о которой не обязательно задумываться на текущем этапе.

Re: Файл с текстом параграфа

Posted: Fri Jun 19, 2026 4:11 pm
by volkov
Показалось, что не хватает явного упоминания локальности видимости имён локальных переменных (это, наверное, хорошо укладывается в пояснения о изолированности реализации одной функции от других). И того, что аргументы сопоставляются просто по порядку, а их имена не играют роли. Возможно, с каким-то примером в духе:

Code: Select all

def ab(a, b):
  print("ab: a = " + str(a))
  print("ab: b = " + str(b))

def ba(b, a):
  print("ba: a = " + str(a))
  print("ba: b = " + str(b))
  ab(b, a)

ba(1, 2)
Картинка (возможно, как раз с кадрами стека вызовов), тут бы помогла.

(У части школьников вечно с этим путаница.)