Python - оценка на основе нескольких точек данных - PullRequest
1 голос
/ 22 апреля 2019

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

Есть ли рекомендуемый способ кодирования этого, кроме сотен операторов 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

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

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

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

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

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 голос
/ 22 апреля 2019

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

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)
    ...

...