psilogic: (Default)
psilogic ([personal profile] psilogic) wrote2011-04-05 03:19 pm

Программерам

Задачка: как оптимизировать такой код, чтобы убрать копи-пасты?
Напрашивается заведение двух функций... а, может, кто-нибудь знает другие трюки?


if (undoCase)
{
	if (op & OpBefore)
	{
		uf.read(&hb, sizeof(hb));
		*hNew= hb;
		++hNew;
		++i;
	}
	if (op & OpAfter)
	{
		uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass redo data
		++hOld;
	}
}
else
{
	if (op & OpBefore)
	{
		uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass undo data
		++hOld;
	}
	if (op & OpAfter)
	{
		uf.read(&hb, sizeof(hb));
		*hNew= hb;
		++hNew;
		++i;
	}
}


Upd: Порядок вызова seek/read важен - там в файле два последовательных блока, наличие/отсутствие которых определяется флагами OpAfter/OpBefore.

[identity profile] sfy-y.livejournal.com 2011-04-05 01:15 pm (UTC)(link)
А catch - не канает?

Любой подобный наворот говорит о неправильном дизайне. Просто ловить ошибки и отрабатывать.

[identity profile] psilogic.livejournal.com 2011-04-05 01:16 pm (UTC)(link)
да при чем тут ошибки?
обычный undo/redo в редакторе

[identity profile] sfy-y.livejournal.com 2011-04-05 01:18 pm (UTC)(link)
А в чём разница?

[identity profile] psilogic.livejournal.com 2011-04-05 01:24 pm (UTC)(link)
а при чем тут ошибки? :)

[identity profile] sfy-y.livejournal.com 2011-04-05 02:15 pm (UTC)(link)
Упс. Ну, совсем по-быстрому подробно не объясню.

Любая нештатная ситуация легко обрабатывается катчем. А лучше книжки почитать.

[identity profile] psilogic.livejournal.com 2011-04-05 02:17 pm (UTC)(link)
В этом коде нет никакой нештатной ситуации. Просто юзер в редакторе захотел выполнить команду undo или redo.

[identity profile] sfy-y.livejournal.com 2011-04-05 02:28 pm (UTC)(link)
Где там у Вас в коде выполняется seek+read или read+seek?

[identity profile] sfy-y.livejournal.com 2011-04-05 02:29 pm (UTC)(link)
Ой, мама. Всё, уровень понял.

[identity profile] sfy-y.livejournal.com 2011-04-05 02:55 pm (UTC)(link)
Ну, ох 2 раза.

catch команду Undo {
делать Undo
}

[identity profile] psilogic.livejournal.com 2011-04-05 03:01 pm (UTC)(link)
Команда Undo не является нештатной ситуацией.

[identity profile] psilogic.livejournal.com 2011-04-05 03:01 pm (UTC)(link)
уровень понял :)

[identity profile] sfy-y.livejournal.com 2011-04-05 03:03 pm (UTC)(link)
Ну божешка ты ж мой. Просто event-driving. А по жизни - является.

[identity profile] sfy-y.livejournal.com 2011-04-05 03:06 pm (UTC)(link)
Увидел. Так это ошибка by design.

Пойдете с электронным паспортом через контроль - кивните, стэк драйверов там мой. :)

[identity profile] psilogic.livejournal.com 2011-04-05 03:09 pm (UTC)(link)
а catch не является событием (event)

кроме вас, остальные комментаторы суть ухватили

продОлжите строить из себя умного, или, может, хватит? :)

[identity profile] psilogic.livejournal.com 2011-04-05 03:11 pm (UTC)(link)
"стек драйверов" - какие слова знаете :))))

[identity profile] sfy-y.livejournal.com 2011-04-05 03:28 pm (UTC)(link)
Сути не было. Была ошибка в дизайне.

[identity profile] sfy-y.livejournal.com 2011-04-05 03:33 pm (UTC)(link)
Так случилось. Я и Кнута читал, и Оллонгрена, и Мартина, и много кого ещё. Когда-то писал ЦУПы (6 штук). В 2005-2006 от скуки написал драйверы для электронных паспортов (по заказу ГУП Атлас).

Шли бы Вы со своими редакторами? :)))

[identity profile] http://users.livejournal.com/_stilgar/ 2011-04-05 04:42 pm (UTC)(link)
Копипаста плоха тем, что поддерживать ее намного труднее, поэтому от нее нужно избавляться по возможности.

[identity profile] http://users.livejournal.com/_stilgar/ 2011-04-05 04:45 pm (UTC)(link)
Упустили момент, когда ни read, ни seek не нужны.

[identity profile] 3seemingmonkeys.livejournal.com 2011-04-05 05:02 pm (UTC)(link)
ну еще проверки поставить елси такой случай возможен (мне было видение что ето не надо обрабатывать)

if (s = !u && bef) {
seek;
}
if (u && bef || !u && aft) {
read;
}
if (!s && u && aft) {
seek;
}

[identity profile] http://users.livejournal.com/_stilgar/ 2011-04-05 06:58 pm (UTC)(link)
Итого, копипасту уполовинили, читаемость кода - тоже :)

[identity profile] kindex.livejournal.com 2011-04-05 07:09 pm (UTC)(link)
for (int i = 0; i <= 1; i++)
{
if (!!i != !!undoCase && (op & OpBefore))
{
uf.read(&hb, sizeof(hb));
*hNew= hb;
++hNew;
++i;
}
if (!!i == !!undoCase && (op & OpAfter))
{
uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass redo data
++hOld;
}
}

[identity profile] kindex.livejournal.com 2011-04-05 07:09 pm (UTC)(link)
!! - это приведение к bool.

[identity profile] kindex.livejournal.com 2011-04-05 07:17 pm (UTC)(link)
Вкралась ошибка - OpBefore и OpAfter используется неправильно.
первый (op & OpBefore) надо заменить на (op & (undoCase ? OpBefore : OpAfter)), и второй & аналогично.

[identity profile] os80.livejournal.com 2011-04-05 07:43 pm (UTC)(link)
Я ваш богомерзкий язык знаю плохо, но, если все "логические" переменные считать нормальными булевскими, то будет что-то вроде этого:

void OrFirstOrSecond(boolean First, boolean DoOrNot) {
if (First && DoOrNot) {
uf.read(&hb, sizeof(hb));
*hNew= hb;
++hNew;
++i;
}
else if (DoOrNot) {
uf.seek(sizeof(GHarmonicBase), SEEK_CUR);//pass redo data
++hOld;
}
}

И Ваш код:
OrFirstOrSecond(undoCase, op && OpBefore);
OrFirstOrSecond(!undoCase, op && OpAfter);

(никогда в жизни такого говна в своём коде не напишу, но как решение олимпиадной задачи - почему нет?

Page 2 of 3