Задача: новостная лента, генерируемая пользователями:
Пользователь выбирает, какой тип данных он хочет добавить
Укажите требуемые данные для типа записи
Запись публикуется в текстовом файле в специальном формате.
Типы данных:
Новости — текст и город в качестве ввода. Дата рассчитывается при публикации.
Частное объявление — вводятся текст и срок действия. Оставшийся день рассчитывается при публикации.
Ваш уникальный с уникальными правилами публикации.
Ожидаемый результат:
News -------------------------
Something happened
London, 03/01/2021 13.45
------------------------------
News -------------------------
Something other happened
Minsk, 24/01/2021 20.33
------------------------------
Private Ad ------------------
I want to sell a bike
Actual until: 01/03/2021, 21 days left
------------------------------
Joke of the day ------------
Did you hear about the claustrophobic astronaut?
He just needed a little space
Funny meter – three of ten
------------------------------
Мой код:
from datetime import datetime, date
from sys import exit
class Article:
def __init__(self, title, text, line_width):
self.title = title
self.text = text
self.line_width = line_width
@staticmethod
def publish_article(formatted_text):
with open("all_news.txt", "a") as file:
file.write(formatted_text)
class News(Article):
def __init__(self, title, text, city, date, line_width):
Article.__init__(self, title, text, line_width)
self.city = city
self.date = date
def format_text(self):
return f"{self.title}{(self.line_width - len(self.title)) * '-'}n"
f"{self.text} n"
f"{self.city}, {self.date.strftime('%d/%m/%Y %H:%M:%S')} n"
f"{'-'*self.line_width}nnn"
class Ad(Article):
def __init__(self, title, text, end_date, line_width):
Article.__init__(self, title, text, line_width)
self.end_date = end_date
def format_text(self):
day, month, year = map(int, self.end_date.split("https://codereview.stackexchange.com/"))
days_left = (date(year, month, day) - date.today()).days
return f"{self.title}{(self.line_width - len(self.title)) * '-'}n"
f"{self.text} n"
f"Actual until: {date(year, month, day).strftime('%d/%m/%Y')}, {days_left} days left n"
f"{'-'*self.line_width}nnn"
class PersonalNews(Article):
def __init__(self, title, text, line_width):
Article.__init__(self, title, text, line_width)
def format_text(self):
return f"{self.title}{(self.line_width - len(self.title)) * '-'}n"
f"{self.text} n"
f"{'-'*self.line_width}nnn"
while True:
user_input = input('Enter a number: '
'1 - Publish news;n'
'2 - Publish ad; n'
'3 - Publish personal newsn'
'q - Exitn')
if user_input == "1":
new_news = News("News",
input('Print your textn'),
input('Print city for the newsn'), datetime.now(), 30)
new_news.publish_article(new_news.format_text())
elif user_input == "2":
new_news = Ad("Private Ad",
input("Input your textn"),
input('Print endDate of ad in format DD/MM/YEARn'), 30)
new_news.publish_article(new_news.format_text())
elif user_input == "3":
new_news = PersonalNews(input("Input your titlen"),
input("Input your textn"), 30)
new_news.publish_article(new_news.format_text())
elif user_input == "q":
exit(0)
else:
print("Incorrect input. Please enter a number (1, 2, 3) or 'q' for exit")
1 ответ
Затенение
Ваш date
параметр конструктора News
плохо назван, потому что он затеняет встроенный date
что вы импортировали из datetime
.
супер
Ваш звонок Article.__init__()
следует использовать super()
вместо.
Классы данных
Article
может быть просто @dataclass
с его явным __init__
удаленный.
Статические методы
publish_article
не имеет смысла как статический метод. В своих призывах вы всегда звоните format_text()
в дочернем экземпляре, а затем передать его статическому методу родительского. Вместо:
- Определять
format_text(self) -> str: raise NotImplementedError()
наArticle
объявить это абстрактным - Изменять
publish_article(self)
простоfile.write(self.format_text())
Продолжение обратной косой черты
Измените это:
return f"{self.title}{(self.line_width - len(self.title)) * '-'}n"
f"{self.text} n"
f"{self.city}, {self.date.strftime('%d/%m/%Y %H:%M:%S')} n"
f"{'-'*self.line_width}nnn"
чтобы убрать обратную косую черту и использовать вместо нее скобки:
return (
f"{self.title}{(self.line_width - len(self.title)) * '-'}n"
f"{self.text} n"
f"{self.city}, {self.date.strftime('%d/%m/%Y %H:%M:%S')} n"
f"{'-'*self.line_width}nnn"
)
Разбор даты
Это зло:
day, month, year = map(int, self.end_date.split("https://codereview.stackexchange.com/"))
Вместо этого вы должны использовать реальный метод разбора datetime
чтобы получить тебе date
пример; затем обращаясь к своим членам. Поскольку вы ищете DD/MM/YEAR
, это будет:
end_date = datetime.strptime(self.end_date, '%d/%m/%Y').date()
# Use end_date.day, end_date.month, end_date.year
Тем не менее, если вы вообще можете, отбросьте этот формат даты, как мешок тухлой картошки. ГГГГ-мм-дд можно сортировать и однозначно.