All streams
Search
Write a publication
Pull to refresh
0
0
JustAndrei @JustAndrei

User

Send message
$50 / 3 затраченных дня * 22 рабочих дня в месяце = $366,(6)
Это тот пороговый уровень зарплаты, после достижения которого сабж не имеет материального смысла, один лишь интерес.
Судя по скринам, автор для начала обрабатывал кадр фильтром, определяющим зоны высокого контраста (переходы от ярких (белых) пикселей к тёмным (чёрным) и наоборот), т.к. именно так выглядит текст. Порог задавался довольно высокий, например, скачок на 200 единиц.
А потом отфильтрованному кадру давалась оценка, например, просто по количеству чёрных пикселей, которые обозначают зоны высокого контраста. В кадрах без серийника таких пикселей относительно мало.
К тому же автор учитывал зону размещения текста в кадре, оценивая только эту область.
Не всё так однозначно.
1. Условия действительно не равные, но о равенстве должен был позаботиться организатор халявной раздачи и никто другой.
2. С первого взгляда вы очень красиво сказали. Со второго вдруг замечаешь подмену понятий: вы заменили «непрограммист» на «тупой бездельник».
В данный момент человеческая цивилизация опирается на принцип разбивки работы на большое множество узких специальностей. Умные и работящие программисты почему-то покупают хлеб в магазине, а не выпекают самостоятельно. Каждый занят своим узкоспециализированным делом. А дома и программист и пекарь одинаково хотят поиграть в Дьябло.
Мне кажется, что со мной несогласны те, кто почему-то априори считает, что сабжевая задача — единственная приятная задача, попавшаяся автору за последнее время.

А вот представьте себе такую ситуацию:
1. На работе все задачи — как минимум не менее интересные, чем сабж.
2. На работе за выполнение задач ещё и деньги платят, притом значительно большие, чем профит от сабжа.

И вот в такой ситуации почему не купить? Все дела не переделаешь.
Неправда ваша :)
Просто…
1. Я уделяю программированию немало времени и в рабочее время, причём встречаются и интересные задачи, поэтому желание сделать дома что-то «вкусненькое» для себя — не очень сильное и реализуется редко.
2. Я семейный человек, у меня сын есть, а этот шустрый фактор несомненно сокращает свободное время.

Поэтому, будь я любителем Дьябло, немногие свободные часы я бы потратил скорее на саму игру, чем на добычу ключа.
И тем не менее, на самом деле я вас прекрасно понимаю. Просто хотелось сказать, что надо всего лишь отдавать себе отчёт в том, каковы трудозатраты по сравнению с профитом. Понятное дело, что после обдуманного сравнения трудозатрат с профитом (в т.ч. полученным от программирования удовольствием) вы с чистой совестью можете предаваться объектно-ориентированным утехам.
Ключ, насколько я заметил в гугле, можно купить за $50.
А 20 часов программирования — это около трёх рабочих дней.
Скажите, вы получаете больше $370 в месяц? :)

P.S. Я понимаю, что задача сама по себе может быть весьма интересной, что и является определяющим моментом. Это несомненно ваше личное дело как тратить своё время.
Вы правы, я не учёл *11-*19. Исправленный вариант:

RU
base = «минут»
@"^\d*1\d$" => "*" // числа, заканчивающиеся на 10, 11, ..., 19 => $ минут
@"^\d*1$" => "*а" // число заканчивается на 1 => 321 минута
@"^\d*[2-4]$" => "*ы" // число заканчивается на 2, 3 или 4 => 2 минуты
@"^\d*[5-9]$" => "*" // иначе 38 минут

Регулярные выражения тут простейшие, можете заодно слегка прокачаться.
^ и $ — начало и конец строки. указываются для того, чтобы выражение соответствовало всей строке в целом, а не искало подстроки
1 — просто цифра 1
[2-4] — одна цифра из указанного диапазона, т.е. либо 2, либо 3, либо 4
\d — любая цифра, синоним для [0-9]
\d* — строка любой длины (в т.ч. нулевой), состоящая из любых цифр
\d+ — как минимум одна любая цифра

^\d*1\d$ = любое количество цифр, потом единица, потом в конце одна любая цифра
^\d*1$ = любое количество цифр, потом в конце единица
^\d*[2-4]$ = любое количество цифр, потом в конце цифра 2, 3 или 4
^\d*[5-9]$ = любое количество цифр, потом в конце цифра 5, 6, 7, 8 или 9

Я ни сколько не отрицаю, что ваше решение рабочее, но он требует некоторых технических знаний, для расширения «словаря».
Да, требуется маломальское знание регулярных выражений, однако для внесения поправки или добавления нового слова или нового языка не требуется ничего, кроме редактирования текстового файла конфигурации (xml). Ненадобность компиляции — большой плюс.
К сожалению, предложенное вами решение, например, в русском языке, не справится с нахождением правильной формы для слова «день». Если, конечно, не брать «базой» для него «д» ).
А почему не брать базой «д», собственно? База — вообще вещь необязательная, без неё можно обойтись в принципе, определив слова целиком в мэппинге. Она нужна лишь тем, кто любит находить и выделять общее, и позволяет определить в единственном месте порядок следования числа и слова. Но вы не обязаны делать это именно так.

я могу добавлять в ресурсы вариации числительных форм для любого слова языка, и использовать их в правильной форме повсеместно в приложении.
А я не могу разве? :-)
Знак $ не несёт большей смысловой нагрузки, чем место для подстановки простого числа. Т.е. эта конфигурация описывает только две простых вещи:
1. Варианты склонения любого слова-единицы измерения в зависимости от сопутствующего числа.
2. Формат записи (порядок элементов, разделители между ними).
Само собой, это могут быть не только дни или минуты, но так же рубли и копейки, евро и центы, метры и дюймы, etc.
Возможно, я ошибаюсь, но мне кажется, что раз уж вы решили писать по одному классу для каждого языка, код был бы проще, если бы вы предоставляли один-единственный виртуальный метод типа string GetString( TimeSpan value ), который в каждой конкретной реализации делал бы простейшие вычисления типа (EN): value.Minutes == 1? «minute»: «minutes», т.е. без нагромождения абстракций.

Другое дело, как можно было бы попытаться решить эту задачу в рамках одного класса + текстовой (xml) конфигурации. Не берусь утверждать, что такой подход «прокатит» для любого языка, но посмотрите, к примеру, на EN и RU:

Алгоритм на базе Regex.
В конфигурации для каждого языка и каждого слова (час, минута, секунда и т.п.) задано:
1. Базовая строка, являющаяся общей подстрокой для всех вариантов склонения. Может содержать условный знак подстановки числа (например, $).
2. Набор правил её дополнения, представляющий собой мэппинг регулярного выражения, тестирующего преобразуемое число (в виде строки), в простую строку вида «префикс*постфикс», где знак * будет заменен базовой строкой, а знак $ (если есть) — на число.

EN:
base = "$ minute" // общая часть

Правило #1:
@"^1$" => "*"
Т.е. единица заменяется на base без каких-либо дополнений, получается "$ minute", а после подстановок — «1 minute»

Правило #2 (всё остальное):
@"^\d+$" => "*s"
Т.е. в остальных случаях к base добавляется «s», получается "$ minutes"

RU
base = минут
@"\d*1$" => "*а" // число заканчивается на 1 => 321 минута
@"\d*[2-4]$" => "*ы" // число заканчивается на 2, 3 или 4 => 2 минуты
@"\d*[5-9]$" => "*" // иначе 38 минут
Да, вариант кэширования в мэппинге хорош, я об этом уже тоже думал.
Почему «привесить одну строку»? Как ваш атрибут можно расширять свойствами, так и мэппинг можно делать не в строку, а в сложный класс, имеющий все небходимые свойства, либо делать набор мэппингов — по вкусу.
Что касается неизменяемости словаря, что вас смущает, если он скрыт, а доступ организован через метод?
У вас есть конкретный enum DGA, к которому вы добавили конкретные extensions DGAExt. Зачем использовать медленный reflection, когда можно было просто сделать в классе DGAExt
private Dictionary<DGA, string> attributeNames = new Dictionary<DGA, string>
{
{ DGA.RegDate, «doc_RegCard/rc_Index/date_Дата_регистрации» },
{ DGA.RegNum, «doc_RegCard/rc_Index/text_Регистрационный_номер» },

};

public static string GetAttribName(this DGA attrib)
{
return this.attributeNames[ attrib ];
}

Либо вообще сделать attributeNames public и обойтись без метода, хотя метод позволяет добавить валидацию в случае необходимости.

Без reflection скорость выше, понятность в худшую сторону не меняется, весь мэппинг аналогично находится в одном месте, просто не в декларации самого enum.
Как я себе это представляю:

Хэш-коллекцию просят найти данные по ключу A.
Вычисляется хэш ha = H(A).
В наборе хэшей ищется ha.
Обнаруживается, что с этим хэшем ассоциирован один элемент.
На всякий случай делается проверка, что ключ этого элемента совпадает с ключом A (этого можно не делать, если достоверно известно, что при поиске значений используются только те же ключи, что при наполнении коллекции).
Найденный элемент — результат поиска (если его ключ == A).

В том случае, если элементов очень много (и ключей соответственно тоже), возрастает вероятность того, что H(A) == H(P) == H(Q) ==… == H(Z). В этом случае с ha будет ассоциировано несколько элементов. Когда это обнаруживается, приходится делать перебор по этим элементам и обязательно сравнивать каждый ключ с искомым. Cравнение ключей менее эффективно, чем сравнение их хэшей.
Под false cache sharing, я полагаю, имелся в виду false hash sharing, т.е. ложное совпадение хэшей == совпадение хэшей для различающихся значений. Думаю, дальше пояснять детали не обязательно?
По новостям мира IT давно стало понятно, что патентное законодательство морально устарело. Реформа, которая первая приходит в голову, — сокращение срока монопольных прав с 50 лет до, скажем, 10, что в мире IT более чем достаточно.
Уровень шума 78 дБ?!
Может быть, имелось ввиду соотношение сигнал/шум?
2

Information

Rating
Does not participate
Location
Минск, Минская обл., Беларусь
Date of birth
Registered
Activity