[Java vs C#] Прикладная задача - расчеты аля Excel

6yrop

Java нацелена но то, чтобы быть простой. Когда за строчкой a = 5; стоит чёрти-чего (set {...}) - это не по-Javaвски.
простой для кого? Мне как-то пришлось кодировать большое количество арифметических расчетов. В тех задании формулы были напечатаны в Word-е. Составитель тех. задания не был обременен "простотой" Java-ы и писал формулы как ему было удобно. Нам повезло, что кодировать надо было на C#. Использовав такие "сложные" вещи как перегрузку операторов, неявное преобразование, индексеры и т.п., кодирование удалось свести практически к copy-paset из Word-а.
Потом я задумывался, как бы это выглядело на Java -- выглядело бы ужасно, и очень плохо читаемо.

enochka1145

// Мне как-то пришлось кодировать большое количество арифметических расчетов

Ещё раз, для тупых, в который раз: гвозди забивают молотком, а не микроскопом. Своей задаче - свой инструмент. Когда же вы это поймёте?

6yrop

какой инструмент для этой задачи надо было использовать?
Java не предназначена для выполнения арифметических расчетов?

enochka1145

// какой инструмент для этой задачи надо было использовать?
Не знаю, какая у тебя была задача. Наверно, я бы сделал, как ты. Если бы была критична скорость, сделал бы на C++.
// Java не предназначена для выполнения арифметических расчетов?
Именно! Java лучше использовать в других областях. Например, хороший пример использования Java - платформа Eclipse. Или OSGi, на которой основан Eclipse.

6yrop

лол , получается Java даже считать не умеет
уже несколько человек, на вопрос, назовите хоть оду сложную широко распространенную программу написанную на Java, ответили Eclipse. Это забавно Может так и будите там сами для себя писать. И не лезьте в бизнес, там же считать надо

enochka1145

Вообще-то я решил, что если у тебя проблемы с арифметикой, то наверно, речь идёт о комплексных числах. И где они в бизнесе? Разве что в актуарных расчётах, да и то вряд ли - наверняка только в теории для детишек.
Кроме Eclipse можно назвать IDEA (тоже для нас - Java-еров, правда). Но Eclipse - это, мягко говоря, не только Java. Зайди сам на www.eclipse.org. Потом, есть много задач для J2EE (про это я толком не знаю - у меня более интересная работа, чем бизнес-приложения).

6yrop

Вообще-то я решил, что если у тебя проблемы с арифметикой, то наверно, речь идёт о комплексных числах.
нет, речь идет о действительных числах

6yrop

у меня более интересная работа, чем бизнес-приложения
жаль. Хотелось бы пообщаться с Java-фанатом, который пишет бизнес-приложения.

Hastya

Очевидно, FORTRAN.

enochka1145

// нет, речь идет о действительных числах
Замечательно! Можно пример?

kokoc88

Хотелось бы пообщаться с Java-фанатом, который пишет бизнес-приложения.
Ну я не фанат, но пишу очень дорогое и хорошо спонсируемое бизнес приложение на технологии J2EE.

6yrop

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

6yrop

>>FORTRAN
1. точно утверждать сейчас не буду, но возможно, на C# получилось даже лучше.
2. А всё остальное на чем? имхо, сшивание разных языков (платформ принесло бы свои проблемы.

enochka1145

Не надо выкладывать в форум ТЗ, особенно если оно для внутреннего пользования . Мне для повышения образованности достаточно пары строчек расчётов в действительных числах на C#, которые, будучи переведены на Java, приобретают кошмарный вид.

Hastya

как это интересно на C# может получиться лучше, учитывая поддержку массивов, матриц, огромное количество матбиблиотек для Фортрана?
А всё остальное на чем?
Я так понял, проект - математический. Тогда что такое "остальное"? Если это остальное важнее, чем математические возможности, то реализовывать можно на любом подходящем языке, хоть на Ruby.

6yrop

Я так понял, проект - математический.
Я конечно понимаю, что тут МГУ, и все знакомы с высшей математикой, но для подсчета денег часто достаточно простой арифметики за 3-ий класс, и ее приходится кодировать.

enochka1145

// ...для подсчета денег часто достаточно простой арифметики за 3-ий класс, и ее приходится кодировать.
Java не даёт по-человечески кодировать арифметику за 3-ий класс?

6yrop

Мне для повышения образованности достаточно пары строчек расчётов в действительных числах на C#,
код тоже собственность фирмы.....

6yrop

Java не даёт по-человечески кодировать арифметику за 3-ий класс?
да

enochka1145

Можно было бы его обфускировать - сделать имена переменных и классов ничего не значащими.

enochka1145

В этот раз примера мы тоже не дождёмся?

Hastya

Java не даёт по-человечески кодировать арифметику за 3-ий класс?
да
Дай-ка вспомню... 3-й класс - это сложение, умножение, вычитание. Может быть даже деление. Тебе не хватает какого-либо из этих действий в Java?

Dasar

кроме действий - есть еще переменные, точки, последовательности (массивы функции, числа - как числа + погрешность, матрицы и т.д.

Hastya

матрицы, массивы? в 3 классе?

enochka1145

Ни фига себе 3-й класс... Правду говорят, сейчас у детей непомерные нагрузки в школе...
Я так понял, на этот раз наезд на Java тоже не будет сопровождаться примером.

Dasar

матриц может и нет, хотя системы уравнений уже есть.
зы
массив - это, например, всего лишь одно из представлений в коде нескольких однотипных переменных X1, X2, X3.

Dasar

Один из примеров:
нам необходимо было сделать арифметику:
1) поддерживающую частично введенные данные (т.е. по ряду переменных возможны нулевые значения - тогда или результат нуль, или такие значения игнорируются - чем-то похоже на арифметику в excel-е)
2) поддерживающую расчет в виде число+погрешность.
при этом была проблема в том, что сами формулы задаются наладчиком при настройке,
а конкретные данные - позже пользователем.
Соответственно, под .Net-ом мы сделали примерно следующее:
формула вводилась в обычном "человеческом" виде,
далее компилировалась C#-компилятором в dll-ку,
через reflection создавалась и
далее проект с ней работал через виртуальные функции.
компиляция удалось сделать потому,что были написаны классы для null-арифметики и арифметики с погрешностями с перегруженными операциями +,-,*,/, которые и использовались при вычислении формулы.
как эта задача решалась бы на Java-е?

sasha79

Все то же самое (только перегруженные операторы стали бы виртуальными методами) + не очень сложная стадия преобразования +, -, /, * в add subtract и т.д.
Да, на C# проще.

Dasar

Что значит не очень сложная?
правильно ли я понял - что под этим подразумевается написание полноценного парсера выражений + генератора Java-кода?

sasha79

Да, с учетом того, что, кроме операций +, -, /, *, синтаксис менять не надо, я наивно предполагаю, что это не очень сложная задача.

Dasar

на вскидку, придется разбираться
1) с приоритетами ( с правильной расстановкой скобок)
2)унарными/бинарные операции придется отличать
с вызовами функций - проблем вроде не должно быть
типы отслеживать вроде тоже не надо (перегрузка функций по типам в Java-е слава богу вроде была)

Dasar

вспомнил, кроме чисел, есть еще дискреты, строки и время.
соответственно добавляются операции для работы с ними, а также константы этих типов.

sasha79

Ну так грамматики калькуляторов для любых более-менее популярных средств генерации парсеров доступны в качестве примеров.
Все, что между {'+', '-', '/', '*'} парсить не будем вообще. Оно будет вставляться целыми кусками в генерируемый код.

sasha79

Да, задача усложняется.
Разумеется, предложенное решение очень плохо расширяется.
P.S. Что такое "дискреты"?

Dasar

> Что такое "дискреты"?
булевские переменные
сильно реже enum-ы

sasha79

Операции со строками в Java устроены (кроме строковых констант с @ в начале имхо, так же, как и в C# - здесь ничего менять не нужно.
А как выглядит время в выражениях?

enochka1145

А нельзя ли эту формулу завернуть в функцию, её - в класс, а класс подать на javac?
Просто, как Java.

Dasar

наличие строковых констант - усложняет парсер.
> А как выглядит время в выражениях?
временные константы - обычно везде, как строки оформляют или как вызов чего-либо
в данном случае, удобнее будет делать вызов
Date(10, 09, 2005
Time(12, 50)
хотя можно и так Time("12:50:13")

Dasar

что значит завернуть в функцию?
вот есть формула:
-5*A + B *C/ 1000
где A, B, С - имеют какой-нибудь тип NullableDouble
как эту формулу завернуть в функцию?

enochka1145

cu.println("public class Temp { public double foo { return -5*{0} + {1} * {2} / 1000"; } } ", A, B, C); где cu (compilation unit) - выходной поток для записи в файл (типа Temp.java который ты затем подашь на вход javac (например, Runtime.getRuntime.exec("javac.exe Temp.java");)

sasha79

Да, выходит все куда сложнее, чем я сначала наивно предполагал.
Только сейчас понял, что ещё потребуется реализовать классы обертки для встроенных типов (int, double, String поддерживающие наш интерфейс. И все константы в выражении завернуть в эти классы. Нехорошо получилось.
За день-два можно написать.

maggi14

один только вопрос: а что помешало использовать для всей этой цели эхель?

Dasar

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

Dasar

> cu.println("public class Temp { public double
ты ТЗ на задачу читал?
в каком виде, в этом случае задает формулу наладчик?
как происходит, в этом случае, обработка, например, нулевых значений?

enochka1145

1. В виде Java. Вполне вменяемый вид.
2. Дописывай их ручками ( if (a == null) { a = "0"; } )

sasha79

Это несколько менее удобно для наладчика, на мой взгляд.

Dasar

> В виде Java. Вполне вменяемый вид.
как? пока я не увидел готового решения.
еще раз замечу, что основные положения ТЗ уже были.
> 2. Дописывай их ручками ( if (a == null) { a = "0"; } )
это будет не стыдно показать другим?
и это будут покупать?

kokoc88

Ну понятно, что такую задачу на Java придётся решать с гемором. Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью повторяющий все поведения окна. Для чего-то хорошо одно, для чего-то другое. А C# вообще делали дольше и видели всё: успех и неудачу разных языков, что тоже надо отметить. А ещё выше писали про арифметику 3-го класса... Как-то приведённое ТЗ этому не соответствует.

Dasar

и где ты в ТЗ увидел сложную арифметику?
ps
в ТЗ даже массивов и матриц нет
зы
> Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API > или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью
> повторяющий все поведения окна.
а в чем была проблема подключить MC++?

enochka1145

По-моему, ты цепляешься к словам и мелочам. Ты говоришь, что пришлось вводить формулу в нормальном виде, делать DLL, затем как-то юзать. Я говорю, на Java это точно не сложнее. Если это решение не соответствует ТЗ, то может ты просто ТЗ недостаточно понятно изложил?
Кроме того, я считаю, что при желании детали ты додумаешь сам, а не будешь по каждому пустяку справшивать "Как это реализовать?"

Dasar

у меня к Java - только следующие претензии:
1. наличие жесткой песочницы
2. медленное развитие
а проблемы с синтаксисом можно и потерпеть.

Dasar

> Я говорю, на Java это точно не сложнее
создание dll, подключение и т.д. - да, не сложнее
запись в нормальном виде - намного сложнее, и ты пока до сих пор не привел в каком виде наладчик будет записывать формулу, и как по ней будет формироваться Java-код.
правильно ли я понял, что ты предлагаешь наладчику, вместо:
-A+ 5 * B * C
писать

if (A==null || B == null || C == null)
return null;
return -A.Add(new NullableDouble(5) * B.Mulltiply(C;

?

enochka1145

Конечно! Что может быть удобнее?
Хватит тупить. Наладчик (кто это? ) пишет -A+ 5 * B * C. Программа, заменяет в этом выражении буквы на {i} и строит файл как было показано выше. Когда дело дойдёт до конкретных значений, будет вызвана функция с этими значениями в качестве аргументов.
Стоп! Лажа detected.

enochka1145

Можно рассказать поподробнее, как просходит набор формулы и конкретных значений?
Может достаточно сделать функцию public static double foo(double A, double B, double C) { return [твоя формула в нормальном виде, зависящая от A, B и C]; } и завернуть её в класс?

Dasar

> Наладчик (кто это? )
есть пользователи, которые что-то каждый день делает
у этих пользователей - есть какие-то входные данные и выходные
как выходные данные формируются на основе входных - как раз и определяет наладчик (это может быть продв. пользователь, бизнес-консультант и т.д.)

Dasar

> Можно рассказать поподробнее, как просходит набор формулы и конкретных значений?
есть фиксированный, но большой набор переменных - в том числе доступных через . (например, грузовик.грузоподьемность).
формула должна на основе этого набора данных формировать результат.
каждая из переменных может иметь в том числе и пустое значение, поэтому стандартные типы не подходят.
> Может достаточно сделать функцию public static double foo(double A, double B, double C)
почти достаточно, только типы NullableDouble, и чтобы не парсить выражение - их удобнее делать полями класса.

psm-home

А выражение обязательно должно компилироваться в байт-код? Потому что, если нет, то задачу наверное решает JEP . Ему там можно совершенно легально подсунуть свою реальзацию числа (тот самый NullableDouble).

Dasar

удобнее, конечно, когда компилируется в byte-код, тогда у нас меньше будет ограничений по производительности
да, и byte-код удобнее расширять - своими доп. типами, доп. функциями и т.д.

psm-home

Тогда вся трудность в том, чтоб написать маппер из удобного настройщику языка выражений в нек. подмножество Java. А потом на получившийся код остаётся натравить что-нибудь вроде Janino, который это дело на лету скомпилирует в байт-код... Вот только с маппером геморроиться не охота.

enochka1145

Если бы мне такое поручили, я бы переложил все трудности на Eclipse - он бы и дерево (AST) построил, и скомпилировал на ходу. Я уже кстати, стал забывать, что это такое - скомпилировать... в Eclipse-то это уже некий рудимент - так, оставили for backward compatibility.

6yrop

один только вопрос: а что помешало использовать для всей этой цели эхель?
практически использовать в проекте Execl, действительно, не удобно. Удивляет другое, почему в современных языках программирования нет продуманного простого средства выполнения вычислений аля Execel. Обывателю со стороны это вообще кажется странным.
Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью повторяющий все поведения окна. Для чего-то хорошо одно, для чего-то другое.
как оказывается арифметика не так уж редко встречается.

6yrop

2: у нас была почти такая же задача, и почти такое же решение Да, с NULL-ами реально приходится работать. На первый взгляд (подробно еще не смотрел) в Framework 2.0 не самое удобное решение.
Вообще, мы обернули все примитивные типы одним классом и получилось, имхо, красиво. Теперь пользователю не надо задумываться о конкретном примитивном типе значения. Пожертвовали контролем на этапе компиляции (перенесли в runtime но такие ошибки, как оказалось, очень редки.
Что касается проблемы, у нас можно делать примерно такие вызовы Root["Age"], несмотря на то, что Age атрибут User-а.

Dasar

> Что касается этой проблемы, у нас можно делать примерно такие вызовы Root["Age"], несмотря на то, что Age атрибут User-а.
совсем не понял, как вы решили проблему

bleyman

> Удивляет другое, почему в современных языках программирования нет продуманного простого средства выполнения вычислений аля Execel.
Если неопределённость - это просто null, то при наличии в формуле неопределённого инта, например, полетит эксепшен. Нужно только убедить жаву, что у нас инт бокснутый. В шарпе - можно, наверное. Никогда не заморачивался, там действительно проще обёртку навернуть автоматическим макрогенератором.
А вот в вижуал бейсике вообще есть мега-конструкция On Error Resume Next, которая этот эксепшен проигнорирует. Понятия не имею, что произойдёт дальше.

Dasar

exception - это совсем не аля Excel.

6yrop

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

Dasar

т.е. фактически получается, что вы делаете - Root["Config.User.Age"] - но так пропадает возможность Intellisence-а и проверки имен при компиляции.

Dasar

> Если бы мне такое поручили, я бы переложил все трудности на Eclipse - он бы и дерево (AST) построил, и скомпилировал на ходу
Настройщика ты бы тоже посадил бы в Eclipse?

6yrop

скорее мы делаем Root["User.Age"]. У нас атрибутов было много и поэтому в ТЗ у атрибутов были кода, а не осмысленные имена типа "Age". Прописывать все атрибуты как свойства классов было не удобно.

6yrop

Хочется иметь какие-нибудь удобные правила именования атрибутов. Имена атрибутов должны иметь смысл вне сущности.

enochka1145

// Настройщика ты бы тоже посадил бы в Eclipse?
Не знаю. Почему бы и нет? Напоминаю, Eclipse - это нечто большее чем IDE для Java. Строго говоря, Java-ой занимается JDT.
Более того, трудно поверить, но некоторые линуксоиды хотят юзать нечто похожее на Visual Studio. Они просто берут Eclipse+CDT и живут припеваючи.
Оставить комментарий
Имя или ник:
Комментарий: