Общая логика программирования: определение диапазонов почасовой оплаты - PullRequest
1 голос
/ 11 июля 2010

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

Я хотел быкак метод, чтобы взять строку текста, скажем "Default(0-100)=20", а затем извлечь из нее почасовую заработную плату по умолчанию, равную 20 для часов от 0 до 100. Затем ее можно использовать, например, для слова «По умолчанию (101-245) = 25».что почасовая заработная плата по умолчанию для часов с 101 по 245 будет 25. Также позвольте ему определить «Brian (0-29) = 15», что у пользователя «Brian» будет почасовая заработная плата, отличная от 15 по умолчанию для часов с 0 по 29.

Мое первое впечатление - запустить строку через регулярное выражение, которое говорит что-то вроде ^(\w*)\((\d*)-(\d*)\)$, где оно может взять текст и меньший и более высокий конец диапазона.

Как лучше всего хранить эту информацию, чтобы ее можно было использовать позже?многомерный массив?хэши?

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

Как бы вы рассчитали общую заработную плату, если, скажем, мы использовали "Default(0-100)=20" & "Default(101-245)=25", а количество отработанных часов составило 150.

Ответы [ 5 ]

1 голос
/ 11 июля 2010

Я не очень опытный, но я пытаюсь ответить на него сам, может быть, это может помочь вам.

К первой части вашего вопроса, для такой строки, как этот идентификатор, просто разбейте данную строку насоответствующие позиции.большинство фреймворков имеют классы для этого.в вашем случае, например, это будет () - и =

результат:

По умолчанию, (, 0, -, 100,), =, 20

  1. По умолчанию
  2. (
  3. 0
  4. -
  5. 100
  6. )
  7. =
  8. 20

Ваши значения всегда имеют одинаковый индекс при использовании согласованного строкового формата.выберите их, преобразуйте, если необходимо, и сохраните в переменных;

, если вы говорите об объектно-ориентированном программировании, я бы сделал что-то подобное в вашем случае:

создайте сотрудника класса с именем и ежечаснозаработная плата как переменные экземпляра.этот класс также имеет метод CalculayWageForHours (int hours).почасовая оплата может храниться в словаре или аналогичном - в зависимости от вашей структуры.Вы берете в качестве начального часа ключ к диктовке, а в качестве значения - заработную плату.вам не нужны часы окончания, поскольку одна ставка состоит до достижения следующего «этапа».

метод расчета заработной платы может выглядеть примерно так: (конечно, есть лучший способ в зависимости от конкретной ситуации)

calculateWageForHours(int hours) {
for (int i = 0, i < dict.count - 1, i++) {
if (hours < dict[i + 1].key /* the int-value for the hour */ -1) {
float wage;
for (int j = 0, j < i, j++) {
wage += (dict[j + 1].key - 1) * dict[j].value;
}
wage += (hours - dict[i].key - 1) * dict[i].value;
return wage;
}
return calculateWageForHours(dict.lastkey - 1)
 + (hours - dict.lastkey) * dict.lastkey.value;

Часть по умолчанию может быть установлена ​​в любом месте вашей программы, где вы создаете экземпляр класса employee.просто напишите метод, который создает словарь по умолчанию для сотрудника.(это также можно сделать при инициализации объекта, и вы передаете несущественные аргументы из класса контроллера)

0 голосов
/ 11 июля 2010

Почему бы не отбросить все, что не нужно в строке, и использовать что-то вроде функции разнесения в PHP (как, например, упоминается @Tobi)?

Таким образом, ваши строки будут "Brian,0,100,20" и "Brian,101,245,25"

function get_wages_array($the_string) {
    return explode(',', $the_string);
}

$wages = get_wages_array('Brian,0,40,14.75');

$ wages теперь выглядит следующим образом:

Array(
    [0] => 'Brian',
    [1] => '0',
    [2] => '40',
    [3] => '14.75'
)

Я бы сохранял результаты в многомерном массиве, а затем просматривал их циклически, чтобы получить все времена и зарплаты.

0 голосов
/ 11 июля 2010

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

Default(0-100)=20
Default(50-100)=25

поскольку система не знает, как рассчитать заработную плату за 50-100 часов, поскольку существует два варианта. Под полными я подразумеваю, что правила должны быть в состоянии вычислить заработную плату, данную любому сотруднику, и количество часов, которые они отработали. Возьмите другой пример:

Default(0-100)=20
Default(125-150)=25

Если работник проработал 150 часов, система не знает заработанную заработную плату за часы 101-125. Так что неполнота - это еще одна проблема.

Предполагая, что правила являются полными и детерминированными, мы можем приступить к моделированию. Если отработанные часы могут быть дробными, то решение должно будет пропорционально разделить почасовую заработную плату. Похоже, что есть зарплата по умолчанию, а затем зарплаты, специфичные для сотрудника. Заработная плата, специфичная для работника, всегда имеет приоритет над зарплатой по умолчанию. Так что в простом псевдокоде if-else это будет выглядеть так:

get-wages (employee, hours-worked)
    total-wage = 0

    for each ith hour worked
        hourly-wage = get-hourly-wage (employee, ith-hour)
        fraction-of-hour-worked = get-fraction-of-hour-worked(ith-hour, hours-worked)
        total-wage += hourly-wage * fraction-of-hour-worked

    return total-wage
end

get-hourly-wage (employee, hour-number)
    if employee has specific wage for hour number
        return that
    else if there is default wage for hour number
        return that
    else
        throw error("no wage available for hour number [hour-number]")
end

get-fraction-of-hour-worked (hour-number, hours-worked)
    difference = hours-worked - hour-number
    if difference >= 1
        return 1
    else
        return difference
end

Оформление заказа эта статья , которая дает один подход к написанию механизма правил и, что интересно, использует в качестве примера сотрудников и заработную плату, поэтому она может быть полезна

Еще несколько интересных статей о механизмах правил, которые могут оказаться полезными:

0 голосов
/ 11 июля 2010

Хотя по информации в вашем вопросе трудно понять, похоже, что вы, по сути, пытаетесь реализовать Domain Specific Language (или DSL), чтобы определить некоторые правила для вашей системы.

Возможно, вам следует рассматривать реализации DSL как способ решения вашей проблемы.

0 голосов
/ 11 июля 2010

Очень трудно увидеть преимущества такого подхода по сравнению с традиционной конфигурацией в базе данных или чем-то более явным, например, XML-файлом конфигурации.

Одной из проблем будет обеспечение того, чтобы выражения были действительными по отдельности.и между собой (непротиворечиво - то есть как насчет "Default (0-40) = 40, Default (38-100) = 60")

Разрешение представления в виде простого текста допускает некоторую воспринимаемую гибкость, но вам все равно потребуетсячтобы убедиться, что вы можете справиться с этим в любом представлении, в которое вы анализируете.Вполне может быть ложной экономией перестраивать движок, чтобы иметь возможность «обрабатывать что угодно» (становясь компилятором), по сравнению с простым добавлением опций и рефакторингом по мере расширения вариантов использования.

Если вы хотите разрешитьвыражений, мне может показаться, что вы можете использовать real выражений - например, некоторые языки имеют функцию Eval, которая может вычислять выражение.Или разрешите пользователям писать сценарии.

Для оценки выражений см .: http://flee.codeplex.com/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...