Содержание
python — Добавление функционала в программу с turtle
При запуске кода и нажатии на копку паузы, черепашка рисует 3 кнопки, к которым привязаны функции и строку «PAUSES».
Помогите сделать так, чтобы при выполнении одной из функций, связанных с кнопками, кнопки стирались, и игра либо продолжалась без кнопок и строки «PAUSES», либо перезапустилась (тоже без кнопок и без строки «PAUSES»), либо завершилась и закрыла окно.
import turtle sc = turtle.Screen() sc.bgcolor("black") sc.setup(width=1000, height=600) pause1 = turtle.Turtle() pause1.speed(0) pause1.shape("square") pause1.color("white") pause1.shapesize(stretch_wid=2, stretch_len=2) pause1.penup() pause1.goto(-470, 270) pause2 = turtle.Turtle() pause2.speed(0) pause2.shape("square") pause2.color("black") pause2.shapesize(stretch_wid=1.5, stretch_len=1.5) pause2.penup() pause2.goto(-470, 270) pause3 = turtle.Turtle() pause3.speed(0) pause3.shape("square") pause3.color("white") pause3.shapesize(stretch_wid=1, stretch_len=0. 25) pause3.penup() pause3.goto(-464, 270) pause4 = turtle.Turtle() pause4.speed(0) pause4.shape("square") pause4.color("white") pause4.shapesize(stretch_wid=1, stretch_len=0.25) pause4.penup() pause4.goto(-477, 270) def pauses(x, y): if -490 < x < -450 and 250 < y < 290: text = turtle.Turtle() text.speed(10) text.color("white") text.penup() text.hideturtle() text.goto(0, 120) text.write("PAUSE", align="center", font=("Courier", 24, "normal")) restart = turtle.Turtle() restart.speed(10) restart.shape("square") restart.color("orange") restart.shapesize(stretch_wid=2, stretch_len=2) restart.penup() restart.goto(-80, 40) restart2 = turtle.Turtle() restart2.speed(10) restart2.shape("square") restart2.color("black") restart2.shapesize(stretch_wid=1.5, stretch_len=1.5) restart2.penup() restart2. goto(-80, 40) restart3 = turtle.Turtle() restart3.speed(10) restart3.shape("circle") restart3.color("white") restart3.shapesize(stretch_wid=1, stretch_len=1) restart3.penup() restart3.goto(-80, 40) restart4 = turtle.Turtle() restart4.speed(10) restart4.shape("circle") restart4.color("black") restart4.shapesize(stretch_wid=0.75, stretch_len=0.75) restart4.penup() restart4.goto(-80, 40) restart5 = turtle.Turtle() restart5.left(90) restart5.speed(10) restart5.shape("triangle") restart5.color("white") restart5.shapesize(stretch_wid=0.6, stretch_len=0.45) restart5.penup() restart5.goto(-88, 40) resume1 = turtle.Turtle() resume1.speed(10) resume1.shape("square") resume1.color("orange") resume1.shapesize(stretch_wid=2, stretch_len=2) resume1.penup() resume1.goto(0, 40) resume2 = turtle. Turtle() resume2.speed(10) resume2.shape("square") resume2.color("black") resume2.shapesize(stretch_wid=1.5, stretch_len=1.5) resume2.penup() resume2.goto(0, 40) resume3 = turtle.Turtle() resume3.speed(10) resume3.shape("square") resume3.color("white") resume3.shapesize(stretch_wid=1, stretch_len=1) resume3.penup() resume3.goto(0, 40) resume4 = turtle.Turtle() resume4.speed(10) resume4.shape("triangle") resume4.color("black") resume4.shapesize(stretch_wid=0.75, stretch_len=0.75) resume4.penup() resume4.goto(-2, 40) home1 = turtle.Turtle() home1.speed(10) home1.shape("square") home1.color("orange") home1.shapesize(stretch_wid=2, stretch_len=2) home1.penup() home1.goto(80, 40) home2 = turtle.Turtle() home2.speed(10) home2.shape("square") home2.color("black") home2. shapesize(stretch_wid=1.5, stretch_len=1.5) home2.penup() home2.goto(80, 40) home3 = turtle.Turtle() home3.speed(10) home3.shape("square") home3.color("white") home3.shapesize(stretch_wid=0.8, stretch_len=0.8) home3.penup() home3.goto(80, 36) home4 = turtle.Turtle() home4.speed(10) home4.shape("square") home4.color("black") home4.shapesize(stretch_wid=0.5, stretch_len=0.5) home4.penup() home4.goto(80, 36) home5 = turtle.Turtle() home5.left(90) home5.speed(10) home5.shape("triangle") home5.color("white") home5.shapesize(stretch_wid=0.8, stretch_len=0.5) home5.penup() home5.goto(80, 48) home6 = turtle.Turtle() home6.left(90) home6.speed(10) home6.shape("triangle") home6.color("black") home6.shapesize(stretch_wid=0.4, stretch_len=0.25) home6.penup() home6. goto(80, 47) def home(): sys.exit() def resume(): text.clear() restart.clear() restart2.clear() restart3.clear() restart4.clear() restart5.clear() resume1.clear() resume2.clear() resume3.clear() resume4.clear() home1.clear() home2.clear() home3.clear() home4.clear() home5.clear() home6.clear() def restart1(): right_player = 3 left_player = 3 up_player = 3 sketch.clear() sketch2.clear() sketch3.clear() sketch.write("Left player : 3", align="center", font=("Courier", 20, "normal")) sketch2.write("Right player : 3", align="center", font=("Courier", 20, "normal")) sketch3.write("Up player : 3", align="center", font=("Courier", 20, "normal")) text. clear() restart.clear() restart2.clear() restart3.clear() restart4.clear() restart5.clear() resume1.clear() resume2.clear() resume3.clear() resume4.clear() home1.clear() home2.clear() home3.clear() home4.clear() home5.clear() home6.clear() sc.listen() sc.onkeypress(home, "h") sc.onkeypress(resume, "p") sc.onkeypress(restart1, "r") sc.listen() turtle.onscreenclick(pauses, 1) while True: sc.update()
Django REST. Реализация функционала добавления в «избранное» с возможностью расширения типов добавляемого контента / Хабр
Допустим у нас есть зарегистрированные пользователи и какая-то модель, например «Компании», которую пользователь может добавлять в избранное. Обычно такая задача решается путем создания третьей таблицы Favorite
, являющейся связующим звеном, для реализации ManyToManyField связи между пользователем и компанией
from django. db import models from django.contrib.auth.models import User class Company(models.Model): name = models.CharField(max_length=100) class Favorite(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) company = models.ForeignKey(Company, on_delete=models.CASCADE) class Meta: unique_together = ('user', 'company')
Однако, если мы захотим в будущем добавлять в «избранное» другие модели, например «Заявки», то придется писать много лишнего кода.
С помощью инструментов Django можно реализовать функционал добавления в «избранное» с возможностью расширения типов добавляемого контента.
Django ContentType и GenericForeignKey — это мощные инструменты, которые позволяют создавать универсальные и многополюсные модели в Django.
ContentType — это модель, которая позволяет определять тип модели во время выполнения, а не во время создания. Она сохраняет информацию о модели, включая ее приложение и имя, в базе данных и позволяет ссылаться на эту модель в других моделях, используя полиморфные отношения.
GenericForeignKey — это свойство модели, которое позволяет создавать отношения между моделями, не зная точного типа связываемой модели на момент создания. Вместо того, чтобы ссылаться на связываемую модель напрямую, вы ссылаетесь на ContentType и ID модели, которую вы хотите связать.
Для того чтобы использовать GenericForeignKey, вы должны определить два поля в вашей модели — поле ContentType и поле Object ID. Поле ContentType хранит тип связываемой модели, а поле Object ID хранит ID этой модели. Вы также должны определить GenericForeignKey свойство, указывающее на поля ContentType и Object ID.
Описание моделей
Добавляем универсальную модель Favorite
.
from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType class Favorite(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models. CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey('content_type', 'object_id') class Meta: verbose_name = 'Избранное' verbose_name_plural = 'Избранные' ordering = ['-id'] constraints = [ models.UniqueConstraint( fields=['user', 'object_id', 'content_type'], name='unique_user_content_type_object_id' ) ]
При необходимости в модели, которые будут добавляться пользователем в избранное,
можно добавить поле favorites = GenericRelation('Favorite')
. По обращению к полю favorites
есть возможность получать все связанные объекты модели Favorite
.
from django.contrib.contenttypes.fields import GenericRelation class Application(models.Model): name = models.CharField(max_length=100) favorites = GenericRelation('Favorite') class Company(models.Model): name = models.CharField(max_length=100) favorites = GenericRelation('Favorite')
Добавление/Удаление в избранное
Каждому Вью-сету контента, который можно добавлять в избранное, будем добавлять путь . ../<id>/favorite/
. Путь url
только для авторизированных, принимает GET-запрос. В методе мы получаем объект контента, который пользователь хочет добавить/удалить из избранных. Если объект уже добавлен этим пользователем в избранное, то мы удаляем из избранных, если его еще нет в избранных, до добавляем в избранное. Для удобства масштабирования пишем класс ManageFavorite
, в котором описываем метод favorite
, добавляющий данный функционал.
from django.contrib.contenttypes.models import ContentType class ManageFavorite: @action( detail=True, methods=['get'], url_path='favorite', permission_classes=[IsAuthenticated, ] ) def favorite(self, request, pk): instance = self.get_object() content_type = ContentType.objects.get_for_model(instance) favorite_obj, created = Favorite.objects.get_or_create( user=request.user, content_type=content_type, object_id=instance.id ) if created: return Response( {'message': 'Контент добавлен в избранное'}, status=status. HTTP_201_CREATED ) else: favorite_obj.delete() return Response( {'message': 'Контент удален из избранного'}, status=status.HTTP_200_OK )
Добавляем этот класс ManageFavorite
в родители Вью-класса контента, который
хотим добавлять в избранное
class ApplicationViewSet(viewsets.ModelViewSet, ManageFavorite): ... class CompanyViewSet(viewsets.ModelViewSet, ManageFavorite): ...
Например, мы хотим добавить Заявку с id=2 в избранное.
{ "message": "Контент добавлен в избранное" }
Удалить Заявку с id=2 из избранного.
{ "message": "Контент удален из избранного" }
Просмотр контента, с включением поля is_favorite для текущего пользователя
В нашем классе ManageFavorite
добавляем метод annotate_qs_is_favorite_field
, который принимает queryset
и добавляет к каждому объекту модели контента булево поле is_favorite
, отражающее добавлял ли текущий юзер данный экземпляр контента в избранное.
from django.contrib.contenttypes.models import ContentType from django.db.models import Exists, OuterRef class ManageFavorite: ... def annotate_qs_is_favorite_field(self, queryset): if self.request.user.is_authenticated: is_favorite_subquery = Favorite.objects.filter( object_id=OuterRef('pk'), user=self.request.user, content_type=ContentType.objects.get_for_model(queryset.model) ) queryset = queryset.annotate(is_favorite=Exists(is_favorite_subquery)) return queryset
Во Вью-сете контента описываем метод get_queryset
, в котором применяем данную
аннотацию для queryset.
class ApplicationViewSet(viewsets.ModelViewSet, ManageFavorite): serializer_class = ApplicationSerializer def get_queryset(self): queryset = Application.objects.all() queryset = self.annotate_qs_is_favorite_field(queryset) return queryset
В сериалайзер добавляем одноименное аннотированное поле только для чтения.
class ApplicationSerializer(serializers.ModelSerializer): is_favorite = serializers.BooleanField(read_only=True) class Meta: model = Application fields = '__all__'
Например, запрашиваем список Заявок.
[ { "id": 5, "is_favorite": false, "name": "Заявка 5" }, { "id": 4, "is_favorite": true, "name": "Заявка 4" }, { "id": 3, "is_favorite": true, "name": "Заявка 3" }, { "id": 2, "is_favorite": false, "name": "Заявка 2" } ]
Просмотр только избранного
В нашем классе ManageFavorite
добавляем метод favorites
, который формирует путь .../favorites/
. Путь url
только для авторизированных, принимает GET-запрос. Фильтрует queryset
контента, аннотированный полем is_favorite
, выбираем только значения True
.
class ManageFavorite: . .. @action( detail=False, methods=['get'], url_path='favorites', permission_classes=[IsAuthenticated, ] ) def favorites(self, request): queryset = self.get_queryset().filter(is_favorite=True) serializer_class = self.get_serializer_class() serializer = serializer_class(queryset, many=True) return Response(serializer.data, status=status.HTTP_200_OK)
Например, запрашиваем список Заявок добавленных в избранное.
[ { "id": 4, "is_favorite": true, "name": "Заявка 4" }, { "id": 3, "is_favorite": true, "name": "Заявка 3" } ]
Заключение
В целом, использование ContentType и GenericForeignKey может помочь вам создавать более универсальные и гибкие модели в Django, позволяющие создавать многополюсные отношения и уменьшающие количество кода, который необходимо написать для работы с различными типами моделей.
добавлена функциональность словосочетания | значение и примеры использования
словосочетание на английском языке
значения слова добавлено и функциональность
Эти слова часто используются вместе. Нажмите на ссылки ниже, чтобы изучить значения. Или посмотрите другие словосочетания с функциональностью.
добавлено
прилагательное
великобритания
Ваш браузер не поддерживает аудио HTML5
/ˈæd.ɪd/нас
Ваш браузер не поддерживает аудио HTML5
/ˈæd.ɪd/
дополнительный:
См. больше на добавлено
функциональность
существительное [C или U]
uk
Ваш браузер не поддерживает аудио HTML5
/ˌfʌŋk.ʃənˈæl.ə.ti/us
Ваш браузер не поддерживает аудио HTML5
/ˌfʌŋk.ʃənˈæl.ə.t̬i/
любая или все операции, выполняемые частью оборудования или …
Примеры добавленного функционала
Эти примеры взяты из корпусов и источников в Интернете. Любые мнения в примерах не отражают мнение редакторов Кембриджского словаря, издательства Кембриджского университета или его лицензиаров.
Специализированные агенты находятся в пространстве и предлагают добавил пользователю функциональность , абстрагировав типичные потребности пользователя в функциональности и, следовательно, упростив взаимодействие с клиентом.
Из Кембриджского корпуса английского языка
Обеспечивает добавленную функциональность для анализа и картирования преступлений.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Эти добавили функциональность , оптимизацию и повышение скорости компиляции.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
В добавлена функциональность призвана дать пользователям возможность выбирать лучший контент на сайте.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Они могут иметь добавленную функциональность записи изменений на загрузочный носитель.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Для достижения этой цели команда разработчиков добавила функционал с ракурсами и крупными планами во время выступлений.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Некоторые инструменты могут быть удалены, чтобы освободить место для других инструментов, которые могут делать то же самое, но с добавлением функциональность и более высокая эффективность.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Многие авторы программных плагинов добавили функциональность для эмуляции звуков более ранних аналоговых устройств.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Большинство компьютерных языков и платформ обычно добавляют функциональные возможности, которые не могут быть выражены в модели вызова/возврата функции.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Некоторые инструменты имеют добавленную функциональность из предыдущей игры.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Каждый слой добавлял функциональность к ранее составленным слоям, а разные композиции слоев создавали разные программы.
From
Wikipedia
Этот пример взят из Википедии и может быть повторно использован по лицензии CC BY-SA.
Эти примеры взяты из корпусов и источников в Интернете. Любые мнения в примерах не отражают мнение редакторов Кембриджского словаря, издательства Кембриджского университета или его лицензиаров.
Хотите узнать больше?
Архитектура
. Каков наиболее эффективный способ добавления функциональности в незнакомый, структурно ненадежный код?
Я работаю над сложной кодовой базой уже больше года. Посмотрите, могут ли мои идеи помочь вам:
Ваши догадки верны, к тому времени, как вы доберетесь до другой части кода, вы забудете о предыдущей части. Это может быть бесконечный цикл. Важный урок, который следует усвоить, заключается в том, что продукт не может работать, если все его части не работают должным образом. Даже если одна часть выходит из строя, продукт не работает. Посмотрите на это под другим углом: если вы резко улучшите одну часть, это все равно НЕ МОЖЕТ привести к улучшению работы продукта, что является вашей главной целью здесь.
Итак, во-первых: не будь разработчиком. Будьте тестировщиком.
Не пытайтесь понять по частям. Поймите весь продукт и его работу, когда все части вместе. В производственной среде (т. е. в среде, отличной от разработки, без точек отладки) протестируйте продукт. Затем, как это делает каждый тестировщик, регистрируйте проблемы, с которыми вы сталкиваетесь, в систему отслеживания ошибок. Назначьте ему серьезность и приоритет. Поскольку это программное обеспечение существовало довольно давно, проверьте, не создано ли уже средство отслеживания ошибок. Если он уже есть, вам повезло. Добавьте к ним и найдите время и проверьте каждый из существующих. В конце этого цикла вы понимаете продукт с точки зрения пользователя (вы определенно не должны его пропустить), а также с точки зрения контроля качества. Со временем вы можете даже понять, что строка кода исправит ошибку, а те, кто ее кодировал, этого не сделали, потому что тогда в этом не было реальной необходимости.
Второй шаг: Наденьте дизайнерскую накидку
Разбейте изделие на несколько частей (не буквально и не по своему усмотрению, а по тому, как они работают вместе). Может быть, ваша работа до сих пор или существующие знания могут вступить в игру. Затем попытайтесь понять, как они работают друг с другом, а также с 10 зависимыми библиотеками. Затем для каждой отслеживаемой ошибки напишите свои заметки, идентифицирующие объекты кода (например: это изменение включает изменение классов X, Y, Z и т. д.). Вероятно, к концу этого шага у вас будет НЕСКОЛЬКО намеков на то, какие проблемы с текущей архитектурой и что можно улучшить.
Затем вы можете решить, достаточна ли текущая архитектура/дизайн, и вы можете приступить к улучшению программного обеспечения ИЛИ если продукт нуждается в улучшении дизайна или изменениях в существующем дизайне.
Карточный домик
Кроме того, поскольку сложные продукты содержат много кода, у нас может не оказаться возможности взять некоторые вещи и настроить или улучшить их. Это потому, что вся система может быть переплетена таким образом, что внесение изменений в один из классов эквивалентно изменению положения одной карты в карточном домике, никогда не знаешь, какой конец может сломаться. По моему опыту, это было правдой. Я выбрал часть, улучшил ее код, не зная о ее контрактах с другими частями кода, и в итоге отказался от кода и осознал свою ошибку. Итак, вместо того, чтобы пытаться понять части, попытайтесь понять, что это целое.
Расставьте приоритеты в своих проблемах
Вы должны помнить о том, что вы пытаетесь улучшить:
Хотите, чтобы продукт работал быстрее?
Конечно. Но разве это основная проблема? Это медленно? Если да, создайте критерии эффективности, определите узкие места и улучшите эти части. Протестируйте снова.
Вы хотите улучшить удобство использования?
Тогда это в значительной степени сторона API/UI.
Вы хотите улучшить безопасность?
Тогда вам следует исследовать границы.
Я привел только 3 примера, но их гораздо больше.
Последняя и лучшая документация
Я прочитал здесь в одном из постов, что самая последняя и лучшая документация — это сам код.