Files
2026-10-07 13:06:47 +05:00

116 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""Лабораторная 0: проверка готовности окружения.
Запуск из корня курса:
python lab00_intro/check_env.py
Скрипт проверяет версию Python, библиотеки, число ядер и работоспособность
threading / multiprocessing / asyncio. Все проверки должны напечатать [OK].
"""
import os
import sys
# делаем доступным импорт common.* при запуске из корня курса
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
FAILED = []
def check(name: str, fn):
try:
detail = fn()
print(f"[OK] {name}{(': ' + str(detail)) if detail else ''}")
except Exception as e: # noqa: BLE001
FAILED.append(name)
print(f"[FAIL] {name}: {type(e).__name__}: {e}")
def check_python_version():
v = sys.version_info
assert v >= (3, 10), f"нужен Python 3.10+, у вас {v.major}.{v.minor}"
return f"Python {v.major}.{v.minor}.{v.micro}"
def check_modules():
import numpy
import matplotlib
import pytest
return (f"numpy {numpy.__version__}, matplotlib {matplotlib.__version__}, "
f"pytest {pytest.__version__}")
def check_cpu_count():
import multiprocessing
n = multiprocessing.cpu_count()
assert n >= 2, "нужно минимум 2 логических ядра"
return f"{n} логических ядер"
def check_threading():
from concurrent.futures import ThreadPoolExecutor
results = []
with ThreadPoolExecutor(max_workers=4) as pool:
results = list(pool.map(lambda x: x * x, range(8)))
assert results == [i * i for i in range(8)]
return "ThreadPoolExecutor работает"
def _double(x):
"""Функция модульного уровня — Pool требует пиккелируемость."""
return x * 2
def check_multiprocessing():
import multiprocessing
ctx = multiprocessing.get_context() # spawn на Windows, fork на macOS/Linux
with ctx.Pool(2) as pool:
res = pool.map(_double, [1, 2, 3, 4])
assert res == [2, 4, 6, 8], res
return f"метод запуска: {ctx.get_start_method()}"
def check_asyncio():
import asyncio
async def main():
await asyncio.sleep(0.01)
return 42
assert asyncio.run(main()) == 42
return "event loop работает"
def check_common_tasks():
from common.tasks import get_variant
v = get_variant(1)
assert "task_name" in v and "io" in v
return f"вариант 1: {v['describe']}"
def main():
print("=" * 60)
print("Проверка окружения для курса «Технология параллельного программирования»")
print("=" * 60)
check("Версия Python", check_python_version)
check("Библиотеки", check_modules)
check("Число ядер CPU", check_cpu_count)
check("Потоки (threading)", check_threading)
check("Процессы (multiprocessing)", check_multiprocessing)
check("Асинхронность (asyncio)", check_asyncio)
check("Банк задач (common.tasks)", check_common_tasks)
print("-" * 60)
if FAILED:
print(f"ПРОБЛЕМЫ: {', '.join(FAILED)}")
print("Разберитесь по методичке lab00_intro/методичка.md — без этого")
print("следующие лабораторные не будут работать.")
sys.exit(1)
print("Всё готово. Запомните свой вариант из common/варианты.md.")
if os.name == "nt":
print("(Кириллица отображается кракозябрами? Выполните: chcp 65001)")
if __name__ == "__main__":
main()