Осваиваем Python по-быстрому №2 (задачи)

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Осваиваем Python по-быстрому №2 (задачи)

Непрочитанное сообщение Olej » 04 дек 2021, 16:59

Такая тема уже была (там задавали много вопросов и записывались простенькие примеры кода) - Осваиваем Python по-быстрому...
Но там:
- уже полных 5 страниц форума...
- а последние информативные сообщения относятся к 2015 году...
- нужно ещё отметить, что на те даты многие решения относились к Python 2.x (или сравнительно с Python 3.x), а на сегодня есть смысл говорить только о Python 3.x
P.S. Тем не менее, начально смотреть там по ссылке выше - там много интересных материалов.

Поэтому есть прямой смысл продолжить такой разговор в новой теме (хотя настоятельно рекомендую вычитать прежнюю указанную тему).

P.P.S. ... особенно потому что моей внучке :-o :lol: ... да-да ... в школе (это собственно спецкурс Яндекс для школьников) задают множество заданий, приходится кой-чего разъяснять ... а там есть некоторые интересные задачи!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 04 дек 2021, 17:04

Olej писал(а):
04 дек 2021, 16:59
а там есть некоторые интересные задачи!
Начну вот с такого:
Следующее простое число
Напишите функцию next_prime_number(), которая после каждого вызова выводит следующее простое число. Первое простое число – это 2.
Пример
Ввод:
next_prime_number()
next_prime_number()
next_prime_number()
next_prime_number()
next_prime_number()
next_prime_number()
Вывод:
2
3
5
7
11
13
Решение "в лоб" по описанной схеме может выглядеть так:

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

lst=[]

def next_prime_number():
   global lst
   if 0 == len(lst):
      lst.append(2)
   else:
      m = lst[-1]
      more = True;
      while more:
         m += 1
         count = 0
         for j in lst:
            if m % j != 0:
               count += 1
         more = (count != len(lst))
      lst.append(m)
   return lst[-1]

for n in range(6):
   print(next_prime_number())
Выполнение:

Код: Выделить всё

olej@R420:~/2021$ ./prime.py 
2
3
5
7
11
13
Вложения
prime.py
(431 байт) 41 скачивание

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 04 дек 2021, 17:08

Olej писал(а):
04 дек 2021, 17:04
Решение "в лоб" по описанной схеме может выглядеть так:
А вот решение которое мне нравится:

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

lst=[]

def next_prime_number():
   global lst
   if len(lst) != 0:
      m = lst[-1] + 1
      while (sum(list(map(lambda x: int(m % x != 0), lst))) != len(lst)):
         m += 1
   else:
      m = 2      
   lst.append(m)
   return lst[-1]

for n in range(6):
   print(next_prime_number())
Выполнение:

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./prime.py 
2
3
5
7
11
13
Вложения
prime.py
(337 байт) 42 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 05 дек 2021, 11:02

Olej писал(а):
04 дек 2021, 17:04
Начну вот с такого:
Шифр Гамбетта
Леон Гамбетта – премьер Французской республики в XIX веке. Для конспиративной переписки он предложил заменить буквы числами и складывать их с числами ключа по модулю, равному длине используемого алфавита.
Сложение по модулю означает, что после сложения чисел нужно от результата взять остаток от деления на длину алфавита. Тогда полученным значениям можно будет снова сопоставить буквы.
Разберем пример.
Допустим, мы решили каждой букве алфавита сопоставить ее индекс в нем. Возьмем для примера слово КОДИРОВАНИЕ для шифрования и слово ЧИСЛО в качестве ключа.
Пронумеруем буквы русского алфавита числами от 0 до 32.
Затем запишем в одной строке числа, соответствующие буквам кодируемого сообщения, а под ними числа, соответствующие буквам ключа.
Поскольку ключ короче, будем повторять его нужное число раз.
Затем будем складывать числа по вертикали по модулю 33 и заменять получившиеся числа снова на буквы.
К О Д И Р О В А Н И Е
11 15 4 9 17 15 2 0 14 9 5
Ч И С Л О Ч И С Л О Ч
24 9 18 12 15 24 9 18 12 15 24
2 24 22 21 32 6 11 18 26 24 29
В Ч Х Ф Я Ё К С Щ Ч Ъ
Для дешифровки нужно просто из чисел зашифрованного сообщения вычесть числа ключа, причем если получается отрицательное число, то к нему нужно прибавить длину алфавита, в нашем примере 33.
Напишите функции для шифрования и дешифровки сообщений таким способом.
Для шифрования crypt() – принимает аргументы: алфавит, кодируемое сообщение и ключ, возвращает закодированную строку.
Для дешифровки decrypt() – аргументы: алфавит, сообщение, ключ, возвращает расшифрованную строку.
Как вариант (строго по схеме описанной в задаче):

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def crypt(alphabet, line, word):
   result = ""
   for i in range(len(line)):
      l_dig = alphabet.find(line[i])
      w_dig = alphabet.find(word[i % len(word)])
      m = (l_dig + w_dig) % len(alphabet)
      result += alphabet[m]
   return result   

def decrypt(alphabet, line, word):
   result = ""
   for i in range(len(line)):
      l_dig = alphabet.find(line[i])
      w_dig = alphabet.find(word[i % len(word)])
      m = l_dig - w_dig
      if m < 0:
         m += len(alphabet)
      result += alphabet[m]
   return result

alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
line     = 'КОДИРОВАНИЕ'
word     = 'ЧИСЛО'
print("алфавит:        ", alphabet)
print("ключ:           ", word)
print("исходное:       ", line)
result = crypt(alphabet, line, word)
print("кодированное:   ", result)
print("декодированное: ", decrypt(alphabet, result, word))
print()

alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
line     = 'ENCRYPTION'
word     = 'NUMBER'
print("алфавит:        ", alphabet)
print("ключ:           ", word)
print("исходное:       ", line)
result = crypt(alphabet, line, word)
print("кодированное:   ", result)
print("декодированное: ", decrypt(alphabet, result, word))
Выполнение:

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./hambett.py 
алфавит:         АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ
ключ:            ЧИСЛО
исходное:        КОДИРОВАНИЕ
кодированное:    ВЧХФЯЁКСЩЧЬ
декодированное:  КОДИРОВАНИЕ

алфавит:         ABCDEFGHIJKLMNOPQRSTUVWXYZ
ключ:            NUMBER
исходное:        ENCRYPTION
кодированное:    RHOSCGGCAO
декодированное:  ENCRYPTION
Вложения
hambett.py
(1.33 КБ) 43 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 05 дек 2021, 11:12

Матричное шифрование
Этот способ шифрования основан на том, что текст можно записать в таблицу по строкам, а прочитать затем по столбцам.
Не зная размеры таблицы, расшифровать его потом будет довольно сложно.
Напишите две функции – для шифрования encrypt(text, n) и для дешифровки – decrypt(text, n).
В первом случае функция принимает аргументы: текст для шифрования и размер строки в таблице, а возвращает зашифрованный текст.
Второй функции для расшифровки кроме текста нужно передать размер строки исходной таблицы, а возвращает она расшифрованный текст.
Если длина текста не кратна числу n, то текст перед шифрованием дополняется пробелами до нужной длины, а после расшифровки лишние пробелы в конце удаляются.

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def encrypt(line, length):
   cols = length
   rows = len(line) // cols
   if len(line) % cols != 0:
      rows += 1
   matrix = []
   beg = 0;
   for r in range(rows):
      el = line[beg:beg + cols]
      if len(el) < cols:
         el += (cols - len(el)) * " "
      matrix.append(el)
      beg += cols
   result = ""
   for c in range(cols):
      for r in range(rows):
         result += matrix[r][c]
   return result

def decrypt(line, length):
   rows = length
   cols = len(line) // rows
   matrix = []
   beg = 0;
   for r in range(rows):
      el = line[beg:beg + cols]
      matrix.append(el)
      beg += cols
   result = ""
   for c in range(cols):
      for r in range(rows):
         result += matrix[r][c]
   return result.rstrip()

line = "I love you!"
print("исходное:       ", line)
result = encrypt(line, 5)
print("кодированное:   ", result)
print("декодированное: ", decrypt(result, 5))
print()

line = "Whirling, twirling round and round Falling softly to the ground."
print("исходное:       ", line)
result = encrypt(line, 8)
print("кодированное:   ", result)
print("декодированное: ", decrypt(result, 8))
print()
Выполнение:

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./matrix.py 
исходное:        I love you!
кодированное:    Ie!   ly oo vu 
декодированное:  I love you!

исходное:        Whirling, twirling round and round Falling softly to the ground.
кодированное:    W,n nny h gadg git n  trrwrdFsoolio ao uirurlftnnlnolthdgiduile.
декодированное:  Whirling, twirling round and round Falling softly to the ground.
Вложения
matrix.py
(1.22 КБ) 43 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 05 дек 2021, 19:39

Напишите функцию-сортировщик данных по типам. В качестве аргумента функция typification() получает список данных, а возвращает словарь, в котором данные рассортированы по типам: int, str, float, tuple, list, dict, bool, set. Если какого-то типа не оказалось, такой ключ в словаре создавать не надо.

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def typification(lst):
   result = {}
   for val in lst:
      key = type(val).__name__
      if key not in result:
         result[key] = []
      result[key].append(val)
   return result

data = [3, 'xzy', 'abc', {'1': 's'}, [1, 2, 3], -2.5, 14, {'a': 1}]
print("input : ", data)
print("output: ", typification(data))

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./types.py 
input :  [3, 'xzy', 'abc', {'1': 's'}, [1, 2, 3], -2.5, 14, {'a': 1}]
output:  {'int': [3, 14], 'str': ['xzy', 'abc'], 'dict': [{'1': 's'}, {'a': 1}], 'list': [[1, 2, 3]], 'float': [-2.5]}
Вложения
types.py
(364 байт) 45 скачиваний

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 06 дек 2021, 23:44

Проталкивание
Нужно определить, какие коробки можно протолкнуть в окно. Считаем, что это можно сделать, если одна из граней коробки – прямоугольного параллелепипеда – имеет оба размера не больше 2-х размеров окна.
Напишите функцию extruding(), отбирающую такие коробки.
Функции передается произвольное число кортежей из трех размеров коробок и именованный аргумент window – кортеж размеров окна.
Функция возвращает объемы проходящих в окно коробок без повторений.
Используйте filter, map и/или lambda.
Вариант:

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def extruding(*dim, window):
   window = tuple(sorted(window))
   def sqwer(t):
      t = tuple(sorted(t))
      if (t[0] <= window[0]) and (t[1] <= window[1]):
         return t[0] * t[1] * t[2]
      else:
         return -1
   return filter(lambda x: x > 0, set(map(sqwer, dim)))

   
data = [(1, 2, 3), (1, 1, 1), (2, 2, 1), (3, 2, 2), (4, 1, 1)]
print(*extruding(*data, window=(2, 1)))

data = [(5, 2, 3), (1, 2, 4), (2, 2, 2), (5, 2, 2)]
print(*extruding(*data, window=(2, 2)))
Выполнение:

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./extrud.py 
1 4 6
8 20
Вложения
extrud.py
(528 байт) 43 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 07 дек 2021, 00:12

Olej писал(а):
04 дек 2021, 17:04
Решение "в лоб" по описанной схеме может выглядеть так:
А вот решение (поиск следующего простого числа) в духе Python, используя генератор вместо вызова функции, построенного на принципе ленивых вычислений:

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def next_prime_number(n=10):
   lst=[]
   for i in range(n):
      if len(lst) != 0:
         m = lst[-1] + 1
         while (sum(list(map(lambda x: int(m % x != 0), lst))) != len(lst)):
            m += 1
      else:
         m = 2      
      lst.append(m)
      yield lst[-1]

prime = []
for n in next_prime_number(25):
   prime.append(n)
print(prime)
Теперь next_prime_number, при внешнем сходстве, не функция, а итератор (такой же как для списка или кортежа):

Код: Выделить всё

olej@R420:~/2021/DASHA$ ./primey.py
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
Или даже так:

Код: Выделить всё

#!/usr/bin/python3
# -*- coding: utf-8 -*-

def next_prime_number(n=10):
   lst=[]
   for i in range(n):
      if len(lst) != 0:
         m = lst[-1] + 1
         while (sum(list(map(lambda x: int(m % x != 0), lst))) != len(lst)):
            m += 1
      else:
         m = 2      
      lst.append(m)
      yield lst[-1]

print(*next_prime_number(25))
Про ленивые вычисления см.:
Генераторы в Python. Ленивые вычисления
Ленивые вычисления в Python
Вложения
primey.py
(354 байт) 42 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 09 дек 2021, 18:53

Комплексная математика.
На комплексной математике основаны все расчёты в электротехнике, радиотехнике, теории цифровых фильтров, спектральном анализе… Этим определяется то, что комплексная математика есть столь важный практический раздел (что совсем не очевидно не сталкивающимся с этой областью).

По комплексной математике есть несколько хороших публикаций (в документации этому предмету уделено минимум внимания) ... вот некоторые из интересных и обстоятельных: Комплексные числа — complex
Комплексные числа в Python. Бонус: фрактал

Запишите в коде инициализацию переменных, показанных на рисунке на комплексной плоскости:
complex.jpg
complex.jpg (46.17 КБ) 1408 просмотров
Код:

Код: Выделить всё

#!/usr/bin/python3
from cmath import sqrt

z = (0, -3, 2.0, 1j, -sqrt(3j), 4j,
     2 + 3j, 4.0 + 1j, -3 - 3j, sqrt(2) - 1j )

print(*map(lambda n, z: "z" + str(n + 1) + "=" + str(z), range(len(z)), z))
P.S. Обращаем внимание :-o на то, что функцию sqrt() экспортируем из модуля cmath, а не math :!:

Выполнение:

Код: Выделить всё

$ ./complex.1.py 
z1=0 z2=-3 z3=2.0 z4=1j z5=(-1.224744871391589-1.2247448713915892j) z6=4j z7=(2+3j) z8=(4+1j) z9=(-3-3j) z10=(1.4142135623730951-1j)
Вложения
complex.1.py
(204 байт) 43 скачивания

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Осваиваем Python по-быстрому №2

Непрочитанное сообщение Olej » 09 дек 2021, 19:17

Olej писал(а):
09 дек 2021, 18:53
Комплексная математика.
Покажите несколько не очевидных примеров создания комплексных значений в результатах вычислений или преобразований в целочисленных или вещественных операциях.

Код:

Код: Выделить всё

#!/usr/bin/python3
from cmath import sqrt

z = []
z.append(sqrt(-5))
z.append((-0.5)**0.5)
c = 0 + 0j
z.append(c**c)

print(*z)
Результаты могут на первый взгляд казаться не очевидными:

Код: Выделить всё

olej@R420:~/2021/own.BOOKs/tasks-Python/DRAFT$ ./complex.2.py 
2.23606797749979j (4.329780281177467e-17+0.7071067811865476j) (1+0j)
Вложения
complex.2.py
(127 байт) 39 скачиваний

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 12 гостей