Скрипт на Python для новостной ленты

Задача: новостная лента, генерируемая пользователями:

  1. Пользователь выбирает, какой тип данных он хочет добавить

  2. Укажите требуемые данные для типа записи

  3. Запись публикуется в текстовом файле в специальном формате.

Типы данных:

  1. Новости — текст и город в качестве ввода. Дата рассчитывается при публикации.

  2. Частное объявление — вводятся текст и срок действия. Оставшийся день рассчитывается при публикации.

  3. Ваш уникальный с уникальными правилами публикации.

Ожидаемый результат:

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 ответ
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

Тем не менее, если вы вообще можете, отбросьте этот формат даты, как мешок тухлой картошки. ГГГГ-мм-дд можно сортировать и однозначно.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *