Merge pull request 'pupkov_alexey_lab_2' (#164) from pupkov_alexey_lab_2 into main

Reviewed-on: #164
This commit is contained in:
Alexey 2024-11-28 23:36:03 +04:00
commit 6f95e51011
7 changed files with 212 additions and 0 deletions

View File

@ -0,0 +1,78 @@
# Лабораторная работа №2 - Разработка простейшего распределённого приложения
## Задание
Цель: Разработать два приложения, результат работы первого из которых становится входными данными для второго.
Задачи:
1. Разработать два приложения:
- search max lines: Ищет в каталоге /var/data файл с наибольшим количеством строк и копирует его содержимое в /var/result/data.txt.
- search max number: Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt/
2. Разработать файлы сборки Docker для каждого приложения.
3. Собрать файл docker-compose.yml для запуска обоих приложений.
4. Настроить монтирование директорий для обмена данными между контейнерами.
5. Правильно закоммитить решение с использованием .gitignore для исключения лишних файлов.
## Варианты задания:
1. search max lines:
- Ищет файл с наибольшим количеством строк в каталоге /var/data.
- Копирует содержимое этого файла в /var/result/data.txt.
2. search max number:
- Читает файл /var/result/data.txt.
- Ищет набольшее число и сохраняет его вторую степень в /var/result/result.txt.
### Требования:
1. Docker: Платформа для контейнеризации приложений.
2. Docker Compose: Инструмент для управления многоконтейнерными приложениями на основе файла docker-compose.yml.
### Сборка и запуск:
В директории, где находится файл docker-compose.yml, выполним команду для сборки и запуска всех контейнеров:
docker-compose up --build
Эта команда:
1. Собирает все Docker-образы для сервисов.
2. Запускает контейнеры.
3. Автоматически подготавливает данные и выполняет приложения последовательно.
### Результаты:
После успешного завершения работы контейнеров можно проверить результаты в папке result:
- data.txt — файл, полученный после выполнения первого приложения (содержит копию файла с наибольшим количеством строк из папки data).
- result.txt — файл, полученный после выполнения второго приложения (содержит вторую степень наибольшего числа из файла data.txt).
## Описание работы
### Программы:
1. search_max_lines/main.py:
- Ищет файл с наибольшим количеством строк в каталоге /var/data.
- Копирует содержимое этого файла в /var/result/data.txt.
2. search_max_number/main.py:
- Читает файл /var/result/data.txt.
- Ищет наибольшее число в файле и возводит его в вторую степень.
- Сохраняет результат в файл /var/result/result.txt.
### Генерация данных:
Для создания случайных данных был написан скрипт generate_data.py:
- Создает несколько файлов с целыми числами в каталоге /var/data.
- Каждый файл содержит случайные числа, которые будут использоваться первым приложением.
### Dockerfile:
Каждое приложение имеет собственный Dockerfile, где указаны шаги для сборки Python-образов и запуска программ.
## Вывод
В результате лабораторной работы было создано простейшее распределенное приложение, которое использует Docker и Docker Compose для запуска двух программ, обрабатывающих данные в контейнерах.
## Видео ВК
[Ссылка на демонстрацию работы программы](https://vk.com/video547368103_456239600?list=ln-YscnzBfpyobmc7eiKl)

View File

@ -0,0 +1,7 @@
FROM python:3.9-slim
WORKDIR /app
COPY . /app
CMD ["python", "generate_data.py"]

View File

@ -0,0 +1,32 @@
import os
import random
def generate_random_files(directory, num_files, min_value, max_value,min_lines_per_file,max_lines_per_file):
os.makedirs(directory, exist_ok=True)
for i in range(num_files):
file_path = os.path.join(directory, f"file_{i + 1}.txt")
num_lines_per_file = random.randint(min_lines_per_file,max_lines_per_file)
with open(file_path, 'w') as f:
for _ in range(num_lines_per_file):
random_number = random.randint(min_value, max_value)
f.write(f"{random_number}\n")
print(f"Generated file: {file_path}")
def main():
data_directory = '/var/data'
max_lines_per_file = 20
min_lines_per_file = 8
num_files = 10
min_value = 1
max_value = 100
generate_random_files(data_directory, num_files, min_value, max_value,min_lines_per_file,max_lines_per_file)
print(f"Generated {num_files} files in {data_directory}")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,7 @@
FROM python:3.9-slim
WORKDIR /app
COPY . /app
CMD ["python", "main.py"]

View File

@ -0,0 +1,41 @@
import os
import shutil
def find_file_with_most_lines(directory):
max_lines = 0
target_file = None
# Проходим по всем файлам в указанном каталоге
for filename in os.listdir(directory):
filepath = os.path.join(directory, filename)
# Проверяем, является ли это файлом
if os.path.isfile(filepath):
with open(filepath, 'r') as file:
lines = file.readlines()
line_count = len(lines)
# Если текущее количество строк больше максимального, обновляем
if line_count > max_lines:
max_lines = line_count
target_file = filepath
return target_file
def copy_file_content(source_file, destination_file):
if source_file:
# Копируем содержимое файла в новый файл
shutil.copy(source_file, destination_file)
print(f'Содержимое файла {source_file} скопировано в {destination_file}.')
else:
print('Не найдено файлов в указанном каталоге.')
if __name__ == "__main__":
source_directory = '/var/data'
destination_file = '/var/result/data.txt'
# Находим файл с наибольшим количеством строк
file_with_most_lines = find_file_with_most_lines(source_directory)
# Копируем его содержимое в целевой файл
copy_file_content(file_with_most_lines, destination_file)

View File

@ -0,0 +1,7 @@
FROM python:3.9-slim
WORKDIR /app
COPY . /app
CMD ["python", "main.py"]

View File

@ -0,0 +1,40 @@
import os
def find_maximum_number(file_path):
try:
with open(file_path, 'r') as file:
numbers = [int(line.strip()) for line in file if line.strip().isdigit()]
if not numbers:
raise ValueError("Файл не содержит чисел.")
max_number = max(numbers)
return max_number
except FileNotFoundError:
print(f"Файл {file_path} не найден.")
return None
except ValueError as e:
print(e)
return None
def save_to_file(file_path, value):
try:
with open(file_path, 'w') as file:
file.write(str(value))
print(f'Наибольшее число в квадрате ({value}) сохранено в {file_path}.')
except Exception as e:
print(f"Ошибка при записи в файл: {e}")
if __name__ == "__main__":
input_file = '/var/result/data.txt'
output_file = '/var/result/result.txt'
# Находим наибольшее число
max_number = find_maximum_number(input_file)
if max_number is not None:
# Возводим в квадрат
result = max_number ** 2
# Сохраняем результат в файл
save_to_file(output_file, result)