Форум сайта python.su
0
Привет.
Устраиваюсь в одну контору на Junior Python 40 тыс.р до вычета. Сегодня ответили: “Бла бла бла…На данный момент не готовы сотрудничать по этой вакансии: есть замечания к тестовому”.
Выполнил тестовое за полтора дня - итого часов 8, учитывая, что ранее вообще на питоне не писал.
Прилагаю ТЗ и написанный скрипт + пояснения. Там плевое дело.
Опытные товарищи, посмотрите пожалуйста, где же я наделал “замечаний”. Может действительно это никуда не потянет.
Отредактировано xahotaf452@hxqmail.com (Март 18, 2020 15:28:50)
Прикреплённый файлы:
ТЗ+скрипт+мои пояснения.zip (4,6 KБ)
Офлайн
568
xahotaf452@hxqmail.com
Ну, как вам сказать, я бы вас наверное тоже не взял, и это действительно никуда не потянет.
Конечно, позиция джуниорская и много отвас не ожидают, но ваш код слишком наивен даже для джуна.
У вас реализована только одна функция. Это функция error. В которой вы захардкодили способ отображения ошибки с помошью функции print. Полезность этой функции сомнительна, чем это лучше простого использования print - не понятно. Очевидно, что вы подгоняете решение под ТЗ, типа это у вас такое повторное использование кода. Вы считаете, что остальной код не надо инкапсулировать в функции или методы, и вас больше нет подзадач которые можно повторно использовать? Очевидно, что вы не знакомы с концепцией разработки сверху вниз, не знаете что такое принцип единичной отвественности, никогда в жизни не слышали про юнит-тестирование. Алгоритм странный, зачем вам два цикла? Первым циклом вы собираете некий список словарей и тут же вторым циклом его перебираете. А зачем? Какой смысл во втором цикле? Это бы работало, если бы у вас был словарь с ключом ‘username’, а у вас список, который вы не изменяете. Я подозреваю, что ТЗ вы вообще не выполнили. На каких данных вы это тестировали? Каким образом?
Офлайн
44
В АРХИВЕ xahotaf452@hxqmail.com
————————————
ПОЯСНЕНИЯ
Скрипт для получения задач пользователей
Позволяет получить задачи по пользователям и сохранить инфу в файлы. Похож на генерацию файлов sitemap.xml для сайтов. Подразумевается использование с периодическим запуском на фоне как демона.
Требования и использование
Для работы скрипта необходим интерпретатор Python 3
Запуск python /path/to/script/get_users_tasks.py
Вариант 2 - актуализация всех файлов пачкой
Если требуется чтобы файлы актуализировались все пачкой или никак. Если юзеров и задач будет огромное кол-во, лучше не хранить в памяти все данные для создания файлов, а брать по несколько и записывать на диск, дабы не поймать out of memory.
Возможный алгоритм
Копируем боевую директорию DIR1 в DIR2. Генерируем файлы по актуальным данным в DIR2. По завершении создаем симлинк TASKS на DIR2 ln -s /path/dir2 /path/tasks. Теперь внешняя программа (человек) будет тянуть свежие файлы из DIR2. После первой итерации скрипта как демона предусматриваем смену симлинка, также после генерации rm /path/tasks.
Преимущества:
изолированность версий, на бою будут все актуальные файлы одной версии.
Недостатки:
возможен простой внешней программы, которая использует файлы, если сервер упадет между выполнением команд rm /path/tasks …server down… ln -s /path/dir{n} /path/tasks. Нивелируется автоматической проверкой и исправлением после подъема сервера.
требует больше места на харде, т.к. полностью копируется текущая актуальная директория.
Вариант 3 - используем СУБД
Храним данные в BLOB полях, весь процесс строим на транзакциях. Можно организовать динамическую генерацию файлов по запросу скриптом-прокладкой. Например GoogleBot пришел за /path/sitemap_1.xml, /path/sitemap_2.xml, а статичных файлов нет, там запросы обрабатывает дежурный скрипт, который генерирует сайтмап на лету и отдает.
Преимущества:
лучший вариант для данного рода задач.
Недостатки:
придется переделать прием входных данных у внешней программы с файлов на БД, в том числе скриптом обрабочиком.
————————————
ТЗ
Есть API для получения списка задач и api для получения списка юзеров:
https://jsonplaceholder.typicode.com/todos
https://jsonplaceholder.typicode.com/users
Используя только эти API составить отчёты по всем юзерам в отдельных текстовых файлах.
После запуска скрипта, рядом должна появиться директория “tasks” с текстовыми файлами. Файл называть по username пользователя в формате “Antonette.txt”
Внутри файла на первой строке писать полное имя, и рядом в < > записывать email. Через пробел от email записывать время составления отчёта в формате 23.09.2020 15:25
На второй строке записывать название компании, в которой работает юзер.
Третья строка должна быть пустой.
На четвёртой строке “Завершённые задачи:” и далее список названий завершённых задач.
После завершённых задач через пустую строку записать “Оставшиеся задачи:” и вывести остальные задачи.
Если название задачи больше 50 символов, то обрезать до 50 символов и добавить троеточие.
Пример файла:
```
Ervin Howell <Shanna@melissa.tv> 23.09.2020 15:25
Deckow-Crist
Завершённые задачи:
distinctio vitae autem nihil ut molestias quo
Оставшиеся задачи:
suscipit repellat esse quibusdam voluptatem incidu…
laborum aut in quam
```
Если файл для пользователя уже существует, то существующий файл переименовать, добавив в него время составления этого старого отчёта в формате “Antonette_2020-09-23T15:25.txt”
Таким образом, актуальный отчёт всегда будет без даты в названии. Старые отчёты не удаляются, а переименовываются.
Код должен быть чистым, без необоснованных повторений, с выделенем функций, где это уместно, с говорящими именами.
Код сделать максимально эффективным, но не в ущерб читабельности. Подсказка: следует избегать частых записей на диск.
Предусмотреть возможные сбои в сети или при записи на диск. Не должно быть наполовину сформированных файлов. Либо файл есть и он целиком корректный, либо его нет.
Если по юзеру однажды был создан отчёт, то всегда должен существовать актуальный отчёт без даты в названии. Не должно быть такого, что из-за сбоя в сети или т.п. остались только файлы с датами в названиях.
Если какие-то моменты не обговорены в задаче, то продумайте плюсы и минусы возможных вариантов, и выберите наиболее подходящий на ваш взгляд, чтобы потом можно было обосновать своё решение.
Предусмотреть крайние случаи (у пользователя нет задач, и т.п.).
Код должен быть оформлен по pep8.
Использовать местное время.
Программа должна корректно работать на linux (Debian, Ubuntu).
Можно использовать любые библиотеки.
————————————
КОД
# -*- coding: utf-8 -*- import os import requests import json import time TASKS_DIR = os.path.dirname(__file__) + '/tasks' USERS_GET_LINK = 'https://jsonplaceholder.typicode.com/users' TASKS_GET_LINK = 'https://jsonplaceholder.typicode.com/todos' def error(text, is_exit=True): print(text) if is_exit: exit(0) if not os.path.isdir(TASKS_DIR): try: os.mkdir(TASKS_DIR) except Exception: error(u'Не удалось создать боевую директорию') try: users_data = requests.get(USERS_GET_LINK) except Exception: error(u'Не удалось получить пользователей | get_http_error') users_data = users_data.text try: users_data_json = json.loads(users_data) except Exception: error(u'Не удалось получить пользователей | json_error') try: tasks_data = requests.get(TASKS_GET_LINK) except Exception: error(u'Не удалось получить задачи | get_http_error') tasks_data = tasks_data.text try: tasks_data_json = json.loads(tasks_data) except Exception: error(u'Не удалось получить задачи | json_error') files_arr = [] for user in users_data_json: file_data = user['name'] + '<' + user['email'] + '> ' +\ time.strftime('%d.%m.%Y %H:%M', time.localtime()) + '\n' +\ user['company']['name'] + '\n\n' compl_tasks = '' uncompl_tasks = '' for task in tasks_data_json: if task['userId'] == user['id']: if len(task['title']) > 50: task_title = task['title'][:50] + '...' else: task_title = task['title'] if task['completed']: compl_tasks += task_title + '\n' else: uncompl_tasks += task_title + '\n' file_data += u'Завершённые задачи:\n' + compl_tasks + '\n' file_data += u'Оставшиеся задачи:\n' + uncompl_tasks files_arr.append({'username': user['username'], 'data': file_data}) old_files_c = 0 new_files_c = 0 for file in files_arr: username = file['username'] data = file['data'] file_path = TASKS_DIR + '/' + username + '.txt' if os.path.isfile(file_path): new_path = TASKS_DIR + '/' + username + '_' +\ time.strftime('%Y-%m-%dT%H:%M', time.localtime(os.path.getctime(file_path))) + '.txt' try: os.rename(file_path, new_path) old_files_c += 1 except Exception: error(u'Не удалось переименовать старый файл ' + file_path + ' в ' + new_path + '\n', False) try: with open(file_path, 'w') as f: f.write(data.encode('utf-8')) new_files_c += 1 except Exception: error(u'Не удалось создать актуальный файл ' + file_path + '\n', False) print(u'Успешно создано новых файлов ' + str(new_files_c) + u'\nПереименованно старых: ' + str(old_files_c))
и вставьте ссылку на его url Офлайн
857
xahotaf452@hxqmail.comДа довольно сложная задача. Ты должен написать код, который можно всегда перестроить под изменения в API. И с этим ты не справился. Если в API хоть что-то поменять (формат пользователей, например, или типы задач новые добавить), то твой код, который ты написал, можно только выкинуть. В нём нельзя следом за изменением в API поменять лишь маленький кусочек, чтобы всё продолжало работать правильно. И вот если представить, что ты не один такой код написал, а тысячу таких кодов написал, то сразу становится ясно, что после этого API нельзя менять, потому что все эти коды сломаются и их нужно будет выбрасывать и писать новые. А бизнес - это такая вещь, которая может потребовать резкого изменения API, из-за постоянно меняющихся, динамичных условий на рынке, где куча конкурентов сидит.
Прилагаю ТЗ и написанный скрипт + пояснения. Там плевое дело.
xahotaf452@hxqmail.comУ тебя не в питоне проблема, ты в программировании не понимаешь. Тебе нужно программирование изучать. То есть питон - это кисточка и краски, а программирование - это изобразительное искусство. Вот если у тебя есть кисточка и краски, то ты всё равно нарисовать картину не сможешь, потому что рисовать не умеешь. А если художнику дать карандаш и бумагу, он нарисует такое, что ты и близко не повторишь.
учитывая, что ранее вообще на питоне не писал.
Отредактировано py.user.next (Март 18, 2020 19:58:03)
Офлайн
44
> записывать email. Через пробел от email записывать время составления отчёта в формате 23.09.2020 15:25
На второй строке записывать название компании, в которой работает юзер.
Третья строка должна быть пустой.
и вставьте ссылку на его url Отредактировано AD0DE412 (Март 18, 2020 20:26:29)
Офлайн