python — оценка на основе нескольких точек данных

#python #scoring

#питон #подсчет очков #python #оценка

Вопрос:

нужно руководство по простому способу сделать это. у меня есть несколько активов, каждый с несколькими точками данных. Я хочу присвоить значение каждому активу на основе решений по каждой из этих точек данных. В качестве примера, каждый актив, являющийся домом, и точки данных, включая количество окон, гаражных ворот, сломанный забор и т.д., Каждый дом будет иметь оценку.

Есть ли рекомендуемый способ кодирования этого, помимо сотен операторов if и добавления / вычитания из оценки?

Пример того, как я планирую это сделать

 def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): score  = 10
    if (house.garage): score  = 10
    if (house.fence == 'broken'): score  = 80
    return score
  

Комментарии:

1. Вы ищете существенные изменения?

2. Больше просто нужно убедиться, что является наиболее эффективным и питоническим.

Ответ №1:

Я думаю, вы также можете использовать шаблон «цепочка ответственности» здесь:

Шаблон позволяет нескольким объектам обрабатывать запрос без привязки класса отправителя к конкретным классам получателей. Цепочка может быть составлена динамически во время выполнения с помощью любого обработчика, который следует стандартному интерфейсу обработчика.

Что хорошо в использовании этого шаблона, так это то, что вы можете определять и расширять различные оценки в отдельных модулях и динамически комбинировать их во время выполнения на основе проблемных условий. Вот как вы можете это сделать. Сначала определите родительский класс score:

 from functools import reduce


class BaseScorer(object):

    def __init__(self):
        self._next_scorer = None

    def set_next(self, scorer):
        self._next_scorer = scorer

        return scorer

    def _call_next(self, house, score):

        if self._next_scorer is None:
            return score

        return self._next_scorer.score(house, score)

    def score(self, house, score=0):
        raise NotImplementedError

    @staticmethod
    def chain(scorers):
        reduce(lambda x, y: x.set_next(y), scorers)

        return scorers[0]
  

Затем определите различные классы оценщиков, например:

 class WindowScorer(BaseScorer):

    def score(self, house, score=0):

        if house.windows > 2:
            score = score   10

        return self._call_next(house, score)


class GarageScorer(BaseScorer):

    def score(self, house, score=0):

        if house.garage:
            score = score   10

        return self._call_next(house, score)


class FenceScorer(BaseScorer):

    def score(self, house, score=0):

        if house.fence == 'broken':
            score = score - 5

        return self._call_next(house, score)
  

И вот как это можно использовать:

 scorer = BaseScorer.chain([
    WindowScorer(),
    GarageScorer(),
    FenceScorer()
])

house = House(windows=4, garage=True, fence='nice')
score = scorer.score(house)
  

Комментарии:

1. Учитывая, что существует два уникальных вычисления для каждого атрибута (сравнение, оценка), это самый чистый метод.

Ответ №2:

Я думаю, что ваш метод хорош, и не стоит пытаться сделать что-то еще. Возможно, вы захотите упорядочить его, определив функцию следующим образом:

 def add_score(x, score): 
    score  = x
    return score
  

И dictionary тому подобное:

 sdict = {windows: 10, garage: 10, broken_fence: 10}
  

Чтобы вы могли вызывать свою функцию следующим образом:

 def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): add_score(sdict[windows])
    if (house.garage): add_score(sdict[garage])
    if (house.fence == 'broken'): add_score(sdict[broken_fence])
    return score
  

И легко иметь возможность изменять оценку с одной dictionary .

Вы также можете (и теперь, когда думаете об этом, вероятно, должны) использовать Enums :

 from enum import Enum
class Scoring(Enum):
   WINDOWS = 10
   ...

def score_house(house):
    # score house
    score = 0
    if (house.windows > 2): add_score(Scoring.WINDOWS)
    ...

  

Комментарии:

1. Мне нравится простота. Спасибо