×Закрыть

Оптимальный код

Всем привет. Думаю есть люди которым приходилось работать с кодом, доставшимся в наследство от какого-нибудь индуса всенародного умельца. Хотелось бы увидеть примеры кода с комментами, которые на ваш взгляд выглядят наиболее смешно.

Вот пару примеров от меня:


1) Метод для определения является ли строка целым числом > 0


bool IsNumber (string str)

{
return (str.Replace ( «0», «„).Replace ( „1“, “»).Replace ( «2», «„).Replace ( „3“, “»).Replace ( «4», «„).Replace ( „5“, “»).Replace ( «6», «„).Replace ( „7“, “»).Replace ( «8», «„).Replace ( „9“, “»).Length == 0);
}


2) Определяем является ли число > 0 и < 10


uint i;
...

if (i.ToString ().Length == 1)

{
...
}


3) проверяем на true или false


bool b;
...

if (b.ToString ().Length == 4)

{
...
}


Ну и напоследок самый оптимальный код (рыдали от смеха всем офисом)

Находим дробную часть от умножения 2-х float, при этом проверяем 1 млрд значений:)


double rest (float a, float b)

{
float res=a*b;
for (int i; i< 999999999; i++)
if (i< =res && i+1> res)
{
res = res-i; break;
}
return res;
}

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Иногда бывает сложно понять какой именно экземпляр класса используется для работы

Используя generic классы все проверки делаются на этапе компиляции, поэтому программисту вообще не нужно париться... Создает класс SomeClass< long> и работает с типом long который лежит в классе (аналогично для всех других типов). Поэтому это намного прозрачнее чем делать 5 классов для каждого типа. Представте, что нужно будет изменить что-либо или, еще хуже, дописать функционал, и что тогда? Менять все 5 классов?

Или написание 5 классов для разных типов с именами XXString, XXInt, XXFloat вместо написание 1-го шаблона класса...

Если исходить из примера, то у string’ов не может быть деления и умножения, бинарных операций, у float нет бинарных операций, есть исключительные ситуации, типа бесконечности и NAN. У обоих int и float не может быть деления на ноль. Это как раз тот случай, когда унификация вредна, опять же если исходить из примера.

В этом случае лучше использовать конечный автомат.

Не спорю, можно. Но тогда нужно было бы делать сквозной проход через case’ы без break’ов, если машина не поменяла своё состояние и продолжает выполняться линейный код (я не люблю такие конструкции), либо делать состояния на каждое действие. goto тогда мне показалось меньшим злом:)

Или написание 5 классов для разных типов с именами XXString, XXInt, XXFloat вместо написание 1-го шаблона класса.

Иногда бывает сложно понять какой именно экземпляр класса используется для работы. По этой же причине рекомендуют не увлекаться перегрузкой функций. Яркий пример это перегрузка операторов сдвига («<< » и «>> ») в С++, иногда приходиться делать явное приведение типов, чтоб явно указать компилятору с каким именно вариантом ты хочешь работать.
2cyber
Я бы на всякий случай, в конце каждого case, ставил break;, а то мало ли в какие дебри забредет алгоритм. Один раз наступил на такие грабли, причем сам же эти грабли и положил! =)

З.Ы. Я бы очень аккуратно критиковал любое решение, не факт что Вы в той ситуации написали бы код лучше, может компилятор на момент написания кода был немного «кривоват», может стояла проблема совместимости с чем-то, может просто была плохая погода на Марсе которая негативно повлияла на программиста. А считать что ты один умный, а все остальные пишут херню, это как-то слишком самоуверенно.

Mike, по поводу разных ситуаций и подходов решения все понятно. Но ты хочешь сказать, что проверка 1 млрд значений для нахождения дробной части вместо того чтобы написать примерно так: double x = y — (int) y; это оптимальное решение задачи? Или приведение bool к string и проверка на количество символов это тоже оптимальное решение? Или написание 5 классов для разных типов с именами XXString, XXInt, XXFloat вместо написание 1-го шаблона класса... Я же говорю о безнадежных примерах...

2 Аноним: за ссылки спасибо, очень позитивно:)

В этом случае лучше использовать конечный автомат.
while (state! = END_STATE) {
switch (state) {
case STEP5: blablabla
if (endcondition) state = END_STATE
case STEP6: blablabla
if (condition) state = STEP13
case STEP11: blablabla
if (condition) state = STEP6
case STEP13: blablabla
if (condition) state = STEP11
case STEP14: blablabla
if (condition) state = STEP11
if (condition) state = STEP5
} }
Эксклюзивный пример индусского кода на Java с индусскими комментариями
public void setStfBackbone (StfBackbone stfBackbone) {
this.backboneStudy = backboneStudy; //WTF? I’m scared to change this}

При этом this.backboneStudy и stfBackbone имеют разные типы, никак между собой не связанные (кроме Object)

В этом случае лучше использовать конечный автомат.
while (state! = END_STATE) {
switch (state) {
case STEP5: blablabla
if (endcondition) state = END_STATE
case STEP6: blablabla
if (condition) state = STEP13
case STEP11: blablabla
if (condition) state = STEP6
case STEP13: blablabla
if (condition) state = STEP11
case STEP14: blablabla
if (condition) state = STEP11
if (condition) state = STEP5
} }
Эксклюзивный пример индусского кода на Java с индусскими комментариями
public void setStfBackbone (StfBackbone stfBackbone) {
this.backboneStudy = backboneStudy; //WTF? I’m scared to change this}

При этом this.backboneStudy и stfBackbone имеют разные типы, никак между собой не связанные (кроме Object)

или класс с 2000 строк, в котором имена переменных не несли никакой смысловой нагрузки, например: x1, xx, abc, a11, mx и это по всему классу

Вот мне когда-то тоже говорили, что имена переменных у меня неговорящие, вспомнил глядя на mx. Для примера:
mxu32 a0, a1, a2, a3, a4, a5;
mxu32 b0;
тут же сразу предупрежу вопрос, почему бы не засунуть «a» в массив a [6]. В данном случае «a» — это фракции числа и обращение идёт к ним все равно напрямую, например a [3], что никак не меняет смысл.
И
mxu2048 _mx_Q;
mxu2048* _mx_y;
mxu2048 _mx_Y;
mxu2048 _mx_yconst;
mxu2048 _mx_c;
mxu2048 _mx_N;
mxu2048 _mx_k;
Для человека, который знаком с матчастью (в данном примере это ГОСТ 34.310−95), имена именно этих переменных скажут больше, чем какое-либо другое их написание. Поэтому не стоит сразу рубить с плеча.
То же и про методы в 500 строк. Если ты реализовываешь сложный алгоритм, то передавать 20 временных переменных в другой метод ты не будешь, чтобы читающих этот код не улыбало. Рефакторинг ради рефакторинга — это глупо.
Когда-то я смеялся с тех, кто использует goto в С/C++, до тех пор пока самого не прижало с его использованием:
step5:
< вычисления>
step6:
< вычисления> возможен переход goto step13;
step11:
< вычисления> возможен переход goto step6;
step 13:
< вычисления> возможен переход goto step11;
step 14
< вычисления> возможен переход goto step11; и goto step5;

Использовать стуктурное программирование ради структурного тоже глупо, так же как и ржать всем офисом над чужим кодом, как и слепо следовать каким-то правилам, не опираясь на здравый смысл.

Глубокоуважаемый Аноним, стырить можно только то, что имеет цену (Луркморов не читаю).

А Вы бы почитали, тогда знали бы, что этому коду лет сто...

P.S. Вот еще подборка прикольных комментариев — msug.vn.ua/...ithumor/54.aspx

Глубокоуважаемый Аноним, стырить можно только то, что имеет цену (Луркморов не читаю). Примеры привел максимально простые, чтобы наглядно было видно, что код далеко не оптимальный. Думаю, что не один здравый программист так бы не написал.
В большинстве случаев «некоторые» умельцы решают задачи экстенсивным способом — за счет увеличения количества кода. Встречались приложения в которых существовали 5 абсолютно одинаковых класса с разными именами, или класс с 2000 строк, в котором имена переменных не несли никакой смысловой нагрузки, например: x1, xx, abc, a11, mx и это по всему классу и т.д.

Также улыбают методы в классах размером в 500 строк... Думаю слово «рефакторинг» этим программистам ни о чем не говорит вообще.

Я недавно у себя замелил что вместо

dataGridView1.Rows[i].Cells[j].Value

проще писать

dataGridView1[j, i].Value

А еще когда-то давно, когда я не знал о существовании атрибута readonly в

<input type="text" />

я предложил решение

<input type="text" onfocus="this.blur()" />

более того, я предложил еще один альтернативный вариант — использовать для поля, где что-то нужно выводить, кнопку (

<input type="button" />), текст на кнопке изменять было «просто», а чтобы это поле не было похоже на кнопку, фон и бордер убирался.

Естественно, правильным вариантом была модификация значения какого-то DOM-елемента, типа span или td, но в то время я не был с таким знаком, да и встречалось тогда такое реже чем во времена аякса.

Причем выражения вроде «рыдали от смеха всем офисом» за километр выдают офисный планктон с башорка...

Не, ну это круто конечно, стырить все примеры с Луркмора и выдать их за свои...

Подписаться на комментарии