Skip to content

Align exercises from python#390

Merged
fey merged 29 commits into
mainfrom
align-exercises-from-python
Jun 19, 2026
Merged

Align exercises from python#390
fey merged 29 commits into
mainfrom
align-exercises-from-python

Conversation

@fey

@fey fey commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

No description provided.

fey and others added 29 commits June 10, 2026 16:18
- 10-hello-world: теория до паритета с Python (значение символов, где
  практиковаться, диаграмма интерпретатора), сохранён блок echo vs print_r,
  добавлена иллюстрация hello-world.png
- 30-comments: структура из Python (примеры, диаграмма, служебные
  комментарии BEGIN/END), сохранён PHP-блок о многострочных комментариях
- 40-instructions: разделы «Порядок имеет значение», «Альтернативная форма
  записи», «Зачем это нужно» (isPrime на PHP)
- 45-testing: актуализированная структура из Python, PHPUnit-вывод ошибки
- 50-syntax-errors: разделы о Parse error, «Почему ошибки простые», «Что
  делать»; задание выровнено с Python (вывод + намеренная поломка), как в JS
- data.yml: tips перенесены и адаптированы под PHP (w3schools, php.net,
  сообщество Telegram)

Локали en/es не тронуты — обновятся фазой перевода.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… PHP

- Теория RU всех уроков доведена до паритета с Python (101–153%)
- Задания выровнены с Python: батарейки, подлодка, забор/пирожные,
  магазин, пицца (код и тесты адаптированы под PHP)
- Новый урок 43-float: числа с плавающей точкой, демонстрация
  погрешности через print_r(0.1 + 0.2 - 0.3) без var_dump
- 45-linting: README актуализирован на PHP CS Fixer (PSR-1/PSR-12)
- definitions/tips перенесены из Python во все data.yml

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 10-definition, 12-change, 13-variables-naming, 15, 18, 19, 23: теория RU
  доведена до паритета с exercises-python, примеры адаптированы под PHP 8.4
- rename: 15-expressions -> 15-variables-expressions,
  18-concatenation -> 18-variable-concatenation (выравнивание slug по Python)
- delete: 14-errors (тема влита в 10-definition, прецедент JS)
- задания выровнены под сюжеты Python: 10 (url), 12 (deliveryStatus),
  18 (письмо магазина), 19 (стоимость заказа), 20 (склад),
  23 (MAX_LOGIN_ATTEMPTS); 13 и 15 сохранены (эквивалентны)
- data.yml: definitions/tips перенесены из Python

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- rename: 20-strings-concatenation -> 20-string-concatenation (slug по Python)
- 10-quotes: теория RU до паритета (терминология строка/строчка, пустые
  строки, контрольный вопрос), иллюстрация strings.png, tip на доку PHP
- 15-escape-characters: структура из Python + PHP-специфика про двойные
  кавычки, примеры расположения \n, вывод \n как текста, другие
  последовательности
- 20-string-concatenation: схема вычисления, раздел про пробелы,
  управляющие последовательности, заключение; оператор . вместо +
- 30-encoding: история ASCII, кракозябры, Unicode/UTF-8, зачем знать
  программисту; tips из Python
- задания не тронуты: педагогически эквивалентны Python

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 10-quotes: сообщение о ненайденном файле с апострофом и кавычками
- 15-escape-characters: подсказка с буквальным \n и переводом строки;
  исправлен namespace теста (Arithmetics -> Strings)
- 20-string-concatenation: сборка URL из частей (адаптация: exercises-php)
- 30-encoding: вывод символов по ASCII-кодам на отдельных строках

en/es EXERCISE.md — на фазу перевода.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…и адаптация под PHP

Модуль 5 плана выравнивания: новый модуль 31-advanced-strings забирает
уроки 25-interpolation, 30-symbols, 35-heredoc из 30-variables
(35-heredoc → 90-multiline-strings, slug по Python) и получает новый
урок 70-slices (substr() вместо срезов Python).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ия под PHP

- 100-call, 150-expression, 270-deterministic: теория RU до паритета с Python
- delete 120-function-signature (прецедент JS, тема влита в 135)
- rename 135 -> calling-functions-default-params, 180 -> variadic-parameters (slug по Python)
- задания выровнены под сюжеты Python, неймспейсы тестов по паттерну модуля

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…я под PHP

- rename 100-define → 100-define-function (namespace DefineFunction), задание sayHello по Python
- 200-return: паритет теории с Python 150-return (методы заменены функциями PHP), задание truncate из удалённого 300-parameters
- delete 300-parameters (тема покрыта 340 и теорией define)
- add 250-named-arguments: именованные аргументы PHP 8, задание trimAndRepeat
- add 300-type-annotations: объявления типов PHP, тест через Reflection
- add 350-modules: адаптация под require/include, задание amountPerPerson на ceil()
- add 400-packages: адаптация под Composer/Packagist, задание generatePin на rand()+srand
- 340-default-parameters: паритет теории, namespace DefaultParameters, тест выровнен с Python
- новые уроки: RU полноценно, en/es — краткая выжимка + es-дубль description.es.yml
- удалены неиспользуемые ассеты func_arg.png, func_return.png

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…д PHP

- 30-if, 40-if-else, 50-else-if: теория доведена до паритета с Python
  (блоки кода, ASCII-схемы, предикаты, вложенные if, ошибка с else)
- 60-ternary-operator: чистка оформления, namespace Logic → Conditionals
- add 70-match: новый урок про match-выражение PHP 8 (строгое сравнение,
  отличие от switch, UnhandledMatchError), RU/EN/ES
- задания 30/40/50/60 выровнены с Python (викторина, normalize_url
  с расширенными тестами, светофор, flip-flop)
- решения переведены на объявления типов (паттерн из 45-logic)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 23/25/26/30/55/70: теория доведена до паритета с Python (схемы,
  переворот строки, работа по шагам, нейтральный элемент)
- rename 30-syntax-sugar → 30-syntactic-sugar, 55-return-from-loop →
  55-return-from-loops (namespace SyntacticSugar/ReturnFromLoops)
- delete 28-build-strings (дублирует 23-aggregation-strings)
- add 80-for-in-range: foreach + range() с PHP-семантикой включения
  границ; задание FizzBuzz; RU/EN/ES
- add 90-debug: отладка, stack trace, типы ошибок, отладочная печать
  (сообщения PHP 8.4 проверены запуском); задание compress RLE; RU/EN/ES
- задания 10/30/55/70 выровнены с Python (printCountdown,
  buildProgressBar, hasAtSymbol, normalizeFilename)
- решения переведены на объявления типов (паттерн из 45-logic)
- 29-edge-cases и 50-mutators не тронуты (29 заберет сессия бонусов)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- переименован модуль 27-data-types → 33-data-types (slug по Python)
- 40-primitive-data-types: теория до паритета, задание выровнено с Python
- 50-data-types-weak-typing: паритет с 50-strong-typing с разворотом под
  слабую типизацию PHP (slug сохранен)
- новый урок 52-data-types-immutability на семантике значений (strtoupper)
- rename 55-type-conversion → 55-data-types-casting + паритет теории
- 45-tuples не переносится: кортежей в PHP нет

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 10-bool-type: теория доведена до паритета с Python, введен var_dump()
  для вывода bool, добавлены строгие операторы ===/!==, тема предикатов
  влита из удаляемого 15-predicates
- delete 15-predicates: тема влита в 10-bool-type (как в Python)
- add 15-bool-strings: сравнение строк, ord(), strlen(),
  str_starts_with/str_ends_with/str_contains (RU + en/es-выжимка)
- 20-logic-combine-expressions: паритет с Python, добавлен пример
  isFirstLetterAnA и иллюстрация even-or-odd.jpg
- 25-logical-operators: паритет с Python (isCorrectPassword, hasDiscount,
  isGoodApartment, таблицы истинности); 29-logical-operators-2 удален
  (его тема покрыта расширенной теорией, разбор isLeapYear — это решение
  задания 25)
- 28-logical-negation: паритет с Python (приоритет !, canDrive,
  законы де Моргана)
- delete 70-logic-weak-typing: слабая типизация покрыта 33-data-types
- add 90-logical-expressions: falsy/truthy в PHP, операторы &&/|| всегда
  возвращают bool (отличие от Python/JS), нестрогое сравнение, «ошибка
  выбора»; задание isFalsy перенесено из 70-logic-weak-typing
- решения index.php обновлены с объявлениями типов (введены в
  40-define-functions); удален неиспользуемый ассет lannisters.jpg

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… 55-data-types-casting

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts, иллюстрация naming, фикс диаграммы конкатенации

- delete 24-magic-constants (вердикт второго прохода: в Python темы нет)
- 13-variables-naming: перенос языконезависимой иллюстрации naming.png из Python
- 18-variable-concatenation: в текстовой диаграмме оператор + заменен на .
- variable-definition.png НЕ перенесена: на ней питоновский синтаксис без $

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tdiv в таблице операций

- 45-linting: задание в питоновском формате — исправить пробелы в готовом
  кривом коде коллеги (PSR-12), а не написать с нуля; эталон и тест не меняются
- 20-basic: в таблицу операций добавлено целочисленное деление intdiv()
  (зеркало строки про // в Python)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ib и сокращение 270-deterministic

- delete 900-stdlib (вердикт второго прохода: в Python урока нет)
- 270-deterministic: убраны разделы «побочные эффекты» и «чистые функции» —
  в Python их нет, текст приведен к структуре эталона

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…и про комментарии

- префиксы по эталону: 20-tags -> 15-tags, 30-comments -> 20-comments,
  40-instructions -> 30-instructions, 45-testing -> 40-testing
  (slug-части и namespace не меняются)
- 20-comments: задание заменено на питоновский TODO-сюжет (EXERCISE, эталон,
  тест проверяет содержимое файла); en/es EXERCISE устарели — на фазу перевода
- блок echo в 10-hello-world сохранен (PHP-специфика);
  errors-python.png не переносится (скриншот с Python-кодом)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rnary

- рокировка префиксов: 70-match -> 65-match (позиция Python), 65-switch -> 70-switch
- вступления переписаны под новый порядок: match вводится самостоятельно
  (по питоновскому тексту), switch подается как доисторический аналог match
  с блоком сравнения в конце
- 60-ternary-operator: вводный блок сжат до питоновской структуры
  (оговорка про выражение сохранена компактно); EXERCISE уже был выровнен

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ние 500-reading-documentation

- 200-return -> 150-return, 340-default-parameters -> 200-default-parameters:
  default-parameters теперь идет ПЕРЕД 250-named-arguments, как в Python —
  теория именованных аргументов опирается на значения по умолчанию
- delete 500-reading-documentation (вердикт второго прохода: в Python урока нет)
- удален неиспользуемый ассет func_return.png (нигде не упоминался)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…вост модуля, иллюстрация symbols

- 60-deep-into-strings/{10-unicode,30-locales,40-startwith} ->
  31-advanced-strings/{100-unicode,110-locales,120-startwith};
  модуль 60 удален; namespace DeepIntoStrings -> AdvancedStrings
- уроки адаптированы под уровень модуля 31 (решение гейта): задания и эталоны
  переписаны прямым кодом без функций/циклов/условий —
  100-unicode: strlen vs mb_strlen на 'Привет!' (13 / 7);
  120-startwith: позиция подстроки через mb_strpos, ловушка 0 vs false
  описана текстом с отсылкой к будущим урокам логики;
  110-locales уже соответствовал уровню
- en/es уроков 100/120 устарели — на фазу перевода
- 30-symbols: перенос языконезависимой иллюстрации symbols.png из Python

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…егации

- 26-conditions-inside-loops -> 15 (позиция Python, до агрегации);
  теория без блока «Агрегация с условием» (в Python его нет);
  задание countChars -> countHashtags (порт count_hashtags)
- задания агрегации заменены питоновскими с жизненным контекстом:
  20: multiplyNumbersFromRange -> calculateElectricityBill (ступенчатый тариф)
  23: joinNumbersFromRange -> sanitizePhoneNumber (очистка номера, str_contains)
  25: printReversedWordBySymbol -> maskCardNumber (маскирование карты)
  решения в полной форме ($x = $x + 1) — сахар вводится только в 30
- namespace-опечатки исправлены: AgregationNumber(s) -> AggregationNumbers,
  AgregationString -> AggregationStrings
- delete 29-edge-cases (вердикт второго прохода)
- теория 10-while переписана по новой питоновской структуре (Первый пример /
  По шагам / Тело цикла / Цикл внутри функции); теория 20 приведена к Python
  (перенесена иллюстрация iterations.png, убраны Excel-абзац и вопросы-затравки,
  PHP-вставка про Undefined variable сохранена)
- while.png не переносится (на иллюстрации Python-код)
- en/es EXERCISE уроков 15/20/23/25 устарели — на фазу перевода

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Align the solution filename with the test filename (SolutionTest.php),
matching the PHPUnit convention where SolutionTest tests Solution.

- rename 72 modules/**/index.php -> Solution.php
- update require/file_get_contents in 72 SolutionTest.php and src/Functions.php
- set exercise_filename: Solution.php in spec.yml
- update 350-modules theory references (ru/en/es)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ions

Проставлены объявления типов там, где их не хватало (начиная с урока
40-define-functions/300-type-annotations):

- Решения (Solution.php): isFalsy, getNumberExplanation, generateAmount,
  makeItFunny
- Примеры в теории: 350-modules (ru), 65-switch и 75-elvis (ru/en/es +
  description.es.yml)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Вынес ручной `require 'Solution.php'` из 72 тестов в общий базовый класс
`HexletBasics\Exercise\TestCase`, который в `setUp()` подключает соседний
Solution.php через рефлексию (без зависимости от CWD).

Буфер вывода PHPUnit стартует до setUp(), поэтому вывод решения по-прежнему
ловится `expectOutputString`. Удалил устаревший src/Functions.php (runScript).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fey fey merged commit f831036 into main Jun 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant