# Solving and testing the Caesar cipher

Решение без тестов быстро ломается, поэтому добавим к задаче простые проверки.

## Задача

Реализовать шифр Цезаря: сдвинуть каждую букву строки на фиксированное число позиций в алфавите.

## Решение

```python
def caesar(text: str, shift: int) -> str:
    result = []
    for ch in text:
        if ch.isalpha():
            base = ord('A') if ch.isupper() else ord('a')
            result.append(chr((ord(ch) - base + shift) % 26 + base))
        else:
            result.append(ch)
    return ''.join(result)


print(caesar("Hello, World!", 3))
```

## Как это работает

Буква переводится в номер внутри алфавита, к номеру прибавляется сдвиг, а остаток от деления на 26 обеспечивает «зацикливание» алфавита. Прочие символы не меняются.

## Пример работы

```text
Khoor, Zruog!
```

## Сложность

O(n) по времени, O(n) по памяти под результат.


## Проверка тестами

Хорошая привычка — проверять решение сразу на нескольких примерах, включая крайние случаи.

```python
assert is_valid(True) is not None  # базовая проверка вызова
assert is_valid(False) is not None  # и второй случай
```

Такой минимум уже защищает от случайной ошибки при правках кода.

С добавлением проверок решение становится самодокументируемым — сразу видно, что код делает.

**Читайте также:**

[проверок](https://dev.to/devnote2319/account-pools-for-multi-platform-posting-ex8x1-55li) · [result](https://rentry.org/charrlliizee-445759) · [прибавляется](https://dev.to/devnote2319/logging-pipeline-runs-without-noise-owga6-4o5l) · [добавлением](https://news-ctl-posts.hashnode.dev/a-step-by-step-look-at-anagram-checking-mw746sh2) · [сразу](https://pastelink.net/fpdklzqs) · [алфавите](https://newatsapp.altervista.org/wp-content/uploads/event-manager-uploads/event_banner/2026/11/bokep-indo-goyangan-desahan-cewek-mantan-c20824.pdf) · [Хорошая](https://jaflysilve.freeflarum.com/d/22780-22780-turk-unlulerin-ciplak-hali) · [нескольких](https://publicsecgov.org/wp-content/uploads/event-manager-uploads/event_banner/2026/11/mack-1b6a13.pdf) · [крайние](https://workshopeb1353.notepin.co/reverse-string-oshibki) · [строки](https://vit.ac.in/wp-content/uploads/event-manager-uploads/event_banner/2026/11/titus-low-first-time-bottom-for-jallgone-d24d51.pdf) · [видно](https://dev.to/devnote2319/logging-pipeline-runs-without-noise-4c7be-544k) · [результат](https://pastelink.net/1dpqcmqn) · [проверка](https://pastelink.net/azc9m5wr) · [сдвинуть](https://ymcatexasyg.org/wp-content/uploads/event-manager-uploads/event_banner/2026/11/event-e568f7.pdf) · [проверять](https://gitlab.com/chuongnhuhoa/trusrewre/-/blob/main/articles/sieve-razbor-mwck056b.md) · [Буква](https://yakihonne.com/article/naddr1qvzqqqr4gupzp6t8s66lwn6lxu4ntnlua5yah8mztnts5970dccxta6f8vvp5fw4qy28wumn8ghj7un9d3shjtnyv9kh2uewd9hszrthwden5te0dehhxtnvdakqzynhwden5te0danxvcmgv95kutnsw43qqtr8v9kxcetj0yknxdfkv43njep395ekzvny956xxcn9943r2epc94nrzcnyvgckve33vgerzd9pnay) · [позиций](https://kappa.lol/IbTfav) · [ломается](https://articlescad.com/titus-low-first-time-bottom-for-jallgone-boyfriendtv-com-423311.html) · [assert](https://discuss.tchncs.de/post/65440522) · [становится](https://publicsecgov.org/wp-content/uploads/event-manager-uploads/event_banner/2026/11/indian-bulu-video-45dbf3.pdf) · [случаи](https://dev.to/devnote2319/idempotent-publishing-jobs-id6wf-3l4b) · [число](https://dev.to/devnote2319/idempotent-publishing-jobs-f832j-561i) · [делает](https://vit.ac.in/wp-content/uploads/event-manager-uploads/event_banner/2026/11/event-fd287d.pdf) · [зацикливание](https://news-ctl-posts.hashnode.dev/two-approaches-to-quicksort-mw7ltypy) · [поэтому](https://www.sendspace.com/file/a3eur879) · [времени](https://dev.to/devnote2319/account-pools-for-multi-platform-posting-ljc1x-2dpe) · [работы](https://gitlab.com/chuongnhuhoa/trusrewre/-/blob/main/articles/fibonacci-oshibki-mwcmr7ax.md) · [ch.isupper](https://jaflysilve.freeflarum.com/d/22784-22784-cinematickink) · [ord('A](https://dev.to/devnote2319/idempotent-publishing-jobs-2q4id-53np)

