Учебные задания по информатике на языке Python
Основные учебные задачи по информатике на Python
В данном разделе рассматриваются типовые задания из курса информатики, которые решаются с помощью Python. Для каждой задачи предложены несколько вариантов решения: от простых до более эффективных. Приведены примеры кода с пояснениями, а также разобраны типичные ошибки.
Как вычислить площадь треугольника по длинам сторон?
Наиболее эффективное решение: используем формулу Герона с проверкой существования треугольника.
import math
def triangle_area(a, b, c):
if a + b > c and a + c > b and b + c > a:
p = (a + b + c) / 2
area = math.sqrt(p * (p - a) * (p - b) * (p - c))
return area
else:
return None
# Пример
print(triangle_area(3, 4, 5))
программы python задачи (задачи по python)
6.0
информатика программа python (программа по информатике на python)
Пояснение: функция проверяет неравенство треугольника, затем вычисляет полупериметр и площадь. Использование math.sqrt обеспечивает точность.
Вариант без модуля math
def triangle_area_simple(a, b, c):
if a + b > c and a + c > b and b + c > a:
p = (a + b + c) / 2
area = (p * (p - a) * (p - b) * (p - c)) ** 0.5
return area
else:
return None
Использование оператора ** для извлечения квадратного корня. Такой подход допустим, но менее читаем.
Вариант с обработкой целых чисел
def triangle_area_int(a, b, c):
if a + b > c and a + c > b and b + c > a:
p = (a + b + c) / 2
s = p * (p - a) * (p - b) * (p - c)
# Если s отрицательное из-за погрешности, берем модуль
area = s ** 0.5 if s >= 0 else None
return area
else:
return None
Проблема: при больших значениях возможно отрицательное подкоренное выражение из-за округления. Решение: использовать abs или проверку.
Типичная ошибка: забыть проверить условие существования треугольника. Если ввести стороны 1, 2, 3, программа может выдать значение, близкое к нулю, или ошибку.
Решение: всегда проверять неравенство треугольника перед вычислением.
Как найти максимальное число в списке без использования встроенной функции max?
Стандартный перебор с линейным поиском.
def find_max(lst):
if not lst:
return None
max_val = lst[0]
for num in lst[1:]:
if num > max_val:
max_val = num
return max_val
nums = [5, 3, 8, 1, 9, 2]
print(find_max(nums))
9
Использование reduce из functools
from functools import reduce
max_reduce = reduce(lambda a, b: a if a > b else b, nums)
print(max_reduce)
Функциональный стиль, подходит для демонстрации reduce.
Сортировка и взятие последнего элемента
sorted_nums = sorted(nums)
print(sorted_nums[-1])
Менее эффективно (O(n log n)), но компактно. Не рекомендуется для больших списков.
Ошибка: использование max в качестве имени переменной, что переопределяет встроенную функцию.
Решение: не называть переменную max.
Как проверить, является ли число простым?
Оптимизированный перебор делителей до sqrt(n).
def is_prime(n):
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
i = 3
while i * i <= n:
if n % i == 0:
return False
i += 2
return True
print(is_prime(17))
print(is_prime(15))
True False
Вариант с решетом Эратосфена (для диапазона)
def sieve(n):
if n < 2:
return []
primes = [True] * (n+1)
primes[0] = primes[1] = False
for i in range(2, int(n**0.5)+1):
if primes[i]:
for j in range(i*i, n+1, i):
primes[j] = False
return [i for i, is_prime in enumerate(primes) if is_prime]
print(sieve(30))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Эффективно для генерации списка простых чисел до n.
Ошибка: не учтено, что 1 не является простым. Проверка n < 2 должна быть первой.
Как определить, является ли строка палиндромом?
Сравнение строки с её реверсом (игнорируя регистр и пробелы).
def is_palindrome(s):
cleaned = ''.join(c.lower() for c in s if c.isalnum())
return cleaned == cleaned[::-1]
print(is_palindrome("А роза упала на лапу Азора"))
True
Вариант с двумя указателями
def is_palindrome_two_pointers(s):
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left += 1
right -= 1
return True
Не требует создания новой строки, эффективно по памяти.
Ошибка: не учитывать пробелы и знаки препинания. Использование isalnum() решает проблему.
Расширенные примеры для продвинутого изучения
Мемоизация чисел Фибоначчи с помощью декоратора
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(50))
12586269025
Декоратор lru_cache автоматически сохраняет результаты рекурсивных вызовов, что позволяет избежать повторных вычислений. Без него fib(50) вычислялось бы очень долго.
Генерация криптостойкого пароля
import secrets
import string
def generate_password(length=12):
alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for _ in range(length))
return password
print(generate_password(16))
b#9KpL@2zQ!aX7y
Использование модуля secrets гарантирует, что пароль будет устойчив к подбору.
Обработка CSV-файла и вычисление среднего
import csv
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
total = 0
count = 0
for row in reader:
total += float(row['value'])
count += 1
average = total / count
print(f'Среднее значение: {average:.2f}')
Предполагается, что файл data.csv содержит столбец 'value'. Данный код читает файл, суммирует значения и выводит среднее.
Для создания примера без файла можно использовать io.StringIO.
Рекурсивный обход каталога с подсчетом файлов по расширению
import os
from collections import defaultdict
def count_files_by_extension(path):
counts = defaultdict(int)
for root, dirs, files in os.walk(path):
for file in files:
ext = os.path.splitext(file)[1].lower()
counts[ext] += 1
return dict(counts)
# Пример для текущей директории
print(count_files_by_extension('.'))
{'.py': 5, '.txt': 3, '.csv': 2}
os.walk рекурсивно обходит все подкаталоги, defaultdict упрощает подсчет.