[Java vs C#] Прикладная задача - расчеты аля Excel
Ещё раз, для тупых, в который раз: гвозди забивают молотком, а не микроскопом. Своей задаче - свой инструмент. Когда же вы это поймёте?
Java не предназначена для выполнения арифметических расчетов?
Не знаю, какая у тебя была задача. Наверно, я бы сделал, как ты. Если бы была критична скорость, сделал бы на C++.
// Java не предназначена для выполнения арифметических расчетов?
Именно! Java лучше использовать в других областях. Например, хороший пример использования Java - платформа Eclipse. Или OSGi, на которой основан Eclipse.
уже несколько человек, на вопрос, назовите хоть оду сложную широко распространенную программу написанную на Java, ответили Eclipse. Это забавно Может так и будите там сами для себя писать. И не лезьте в бизнес, там же считать надо
Кроме Eclipse можно назвать IDEA (тоже для нас - Java-еров, правда). Но Eclipse - это, мягко говоря, не только Java. Зайди сам на www.eclipse.org. Потом, есть много задач для J2EE (про это я толком не знаю - у меня более интересная работа, чем бизнес-приложения).
Вообще-то я решил, что если у тебя проблемы с арифметикой, то наверно, речь идёт о комплексных числах.нет, речь идет о действительных числах
у меня более интересная работа, чем бизнес-приложенияжаль. Хотелось бы пообщаться с Java-фанатом, который пишет бизнес-приложения.
Очевидно, FORTRAN.
Замечательно! Можно пример?
Хотелось бы пообщаться с Java-фанатом, который пишет бизнес-приложения.Ну я не фанат, но пишу очень дорогое и хорошо спонсируемое бизнес приложение на технологии J2EE.
к сожалению, выложить в форум тех. задание не могу, документ только для внутреннего использования
1. точно утверждать сейчас не буду, но возможно, на C# получилось даже лучше.
2. А всё остальное на чем? имхо, сшивание разных языков (платформ принесло бы свои проблемы.
Не надо выкладывать в форум ТЗ, особенно если оно для внутреннего пользования . Мне для повышения образованности достаточно пары строчек расчётов в действительных числах на C#, которые, будучи переведены на Java, приобретают кошмарный вид.
А всё остальное на чем?Я так понял, проект - математический. Тогда что такое "остальное"? Если это остальное важнее, чем математические возможности, то реализовывать можно на любом подходящем языке, хоть на Ruby.
Я так понял, проект - математический.Я конечно понимаю, что тут МГУ, и все знакомы с высшей математикой, но для подсчета денег часто достаточно простой арифметики за 3-ий класс, и ее приходится кодировать.
Java не даёт по-человечески кодировать арифметику за 3-ий класс?
Мне для повышения образованности достаточно пары строчек расчётов в действительных числах на C#,код тоже собственность фирмы.....
Java не даёт по-человечески кодировать арифметику за 3-ий класс?да
Можно было бы его обфускировать - сделать имена переменных и классов ничего не значащими.
В этот раз примера мы тоже не дождёмся?
Java не даёт по-человечески кодировать арифметику за 3-ий класс?Дай-ка вспомню... 3-й класс - это сложение, умножение, вычитание. Может быть даже деление. Тебе не хватает какого-либо из этих действий в Java?
да
кроме действий - есть еще переменные, точки, последовательности (массивы функции, числа - как числа + погрешность, матрицы и т.д.
матрицы, массивы? в 3 классе?
Я так понял, на этот раз наезд на Java тоже не будет сопровождаться примером.
зы
массив - это, например, всего лишь одно из представлений в коде нескольких однотипных переменных X1, X2, X3.
нам необходимо было сделать арифметику:
1) поддерживающую частично введенные данные (т.е. по ряду переменных возможны нулевые значения - тогда или результат нуль, или такие значения игнорируются - чем-то похоже на арифметику в excel-е)
2) поддерживающую расчет в виде число+погрешность.
при этом была проблема в том, что сами формулы задаются наладчиком при настройке,
а конкретные данные - позже пользователем.
Соответственно, под .Net-ом мы сделали примерно следующее:
формула вводилась в обычном "человеческом" виде,
далее компилировалась C#-компилятором в dll-ку,
через reflection создавалась и
далее проект с ней работал через виртуальные функции.
компиляция удалось сделать потому,что были написаны классы для null-арифметики и арифметики с погрешностями с перегруженными операциями +,-,*,/, которые и использовались при вычислении формулы.
как эта задача решалась бы на Java-е?
Да, на C# проще.
правильно ли я понял - что под этим подразумевается написание полноценного парсера выражений + генератора Java-кода?
Да, с учетом того, что, кроме операций +, -, /, *, синтаксис менять не надо, я наивно предполагаю, что это не очень сложная задача.
1) с приоритетами ( с правильной расстановкой скобок)
2)унарными/бинарные операции придется отличать
с вызовами функций - проблем вроде не должно быть
типы отслеживать вроде тоже не надо (перегрузка функций по типам в Java-е слава богу вроде была)
соответственно добавляются операции для работы с ними, а также константы этих типов.
Все, что между {'+', '-', '/', '*'} парсить не будем вообще. Оно будет вставляться целыми кусками в генерируемый код.
Разумеется, предложенное решение очень плохо расширяется.
P.S. Что такое "дискреты"?
булевские переменные
сильно реже enum-ы
А как выглядит время в выражениях?
Просто, как Java.
> А как выглядит время в выражениях?
временные константы - обычно везде, как строки оформляют или как вызов чего-либо
в данном случае, удобнее будет делать вызов
Date(10, 09, 2005
Time(12, 50)
хотя можно и так Time("12:50:13")
вот есть формула:
-5*A + B *C/ 1000
где A, B, С - имеют какой-нибудь тип NullableDouble
как эту формулу завернуть в функцию?
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");)
Только сейчас понял, что ещё потребуется реализовать классы обертки для встроенных типов (int, double, String поддерживающие наш интерфейс. И все константы в выражении завернуть в эти классы. Нехорошо получилось.
За день-два можно написать.
один только вопрос: а что помешало использовать для всей этой цели эхель?
ps
если по существу, то у excel-я есть очень много проблем:
начиная от невозможности расширения (введения своих типов, поддержки сложных связей, имен и т.д.
кончая сложностью созданания коробки.
ты ТЗ на задачу читал?
в каком виде, в этом случае задает формулу наладчик?
как происходит, в этом случае, обработка, например, нулевых значений?
2. Дописывай их ручками ( if (a == null) { a = "0"; } )
Это несколько менее удобно для наладчика, на мой взгляд.
как? пока я не увидел готового решения.
еще раз замечу, что основные положения ТЗ уже были.
> 2. Дописывай их ручками ( if (a == null) { a = "0"; } )
это будет не стыдно показать другим?
и это будут покупать?
Ну понятно, что такую задачу на Java придётся решать с гемором. Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью повторяющий все поведения окна. Для чего-то хорошо одно, для чего-то другое. А C# вообще делали дольше и видели всё: успех и неудачу разных языков, что тоже надо отметить. А ещё выше писали про арифметику 3-го класса... Как-то приведённое ТЗ этому не соответствует.
ps
в ТЗ даже массивов и матриц нет
зы
> Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API > или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью
> повторяющий все поведения окна.
а в чем была проблема подключить MC++?
Кроме того, я считаю, что при желании детали ты додумаешь сам, а не будешь по каждому пустяку справшивать "Как это реализовать?"
1. наличие жесткой песочницы
2. медленное развитие
а проблемы с синтаксисом можно и потерпеть.
создание dll, подключение и т.д. - да, не сложнее
запись в нормальном виде - намного сложнее, и ты пока до сих пор не привел в каком виде наладчик будет записывать формулу, и как по ней будет формироваться Java-код.
правильно ли я понял, что ты предлагаешь наладчику, вместо:
-A+ 5 * B * C
писать
if (A==null || B == null || C == null)
return null;
return -A.Add(new NullableDouble(5) * B.Mulltiply(C;
?
Хватит тупить. Наладчик (кто это? ) пишет -A+ 5 * B * C. Программа, заменяет в этом выражении буквы на {i} и строит файл как было показано выше. Когда дело дойдёт до конкретных значений, будет вызвана функция с этими значениями в качестве аргументов.
Стоп! Лажа detected.
Может достаточно сделать функцию public static double foo(double A, double B, double C) { return [твоя формула в нормальном виде, зависящая от A, B и C]; } и завернуть её в класс?
есть пользователи, которые что-то каждый день делает
у этих пользователей - есть какие-то входные данные и выходные
как выходные данные формируются на основе входных - как раз и определяет наладчик (это может быть продв. пользователь, бизнес-консультант и т.д.)
есть фиксированный, но большой набор переменных - в том числе доступных через . (например, грузовик.грузоподьемность).
формула должна на основе этого набора данных формировать результат.
каждая из переменных может иметь в том числе и пустое значение, поэтому стандартные типы не подходят.
> Может достаточно сделать функцию public static double foo(double A, double B, double C)
почти достаточно, только типы NullableDouble, и чтобы не парсить выражение - их удобнее делать полями класса.
JEP . Ему там можно совершенно легально подсунуть свою реальзацию числа (тот самый NullableDouble).
А выражение обязательно должно компилироваться в байт-код? Потому что, если нет, то задачу наверное решает да, и byte-код удобнее расширять - своими доп. типами, доп. функциями и т.д.
Janino, который это дело на лету скомпилирует в байт-код... Вот только с маппером геморроиться не охота.
Тогда вся трудность в том, чтоб написать маппер из удобного настройщику языка выражений в нек. подмножество Java. А потом на получившийся код остаётся натравить что-нибудь вроде
Если бы мне такое поручили, я бы переложил все трудности на Eclipse - он бы и дерево (AST) построил, и скомпилировал на ходу. Я уже кстати, стал забывать, что это такое - скомпилировать... в Eclipse-то это уже некий рудимент - так, оставили for backward compatibility.
один только вопрос: а что помешало использовать для всей этой цели эхель?практически использовать в проекте Execl, действительно, не удобно. Удивляет другое, почему в современных языках программирования нет продуманного простого средства выполнения вычислений аля Execel. Обывателю со стороны это вообще кажется странным.
Но это как я уже писал когда-то про свою очень специфичную GUI задачу, которая хорошо решалась на Win32API или том же MFC, а для C# единственное придуманное решение было реализовать контрол, полностью повторяющий все поведения окна. Для чего-то хорошо одно, для чего-то другое.как оказывается арифметика не так уж редко встречается.
Вообще, мы обернули все примитивные типы одним классом и получилось, имхо, красиво. Теперь пользователю не надо задумываться о конкретном примитивном типе значения. Пожертвовали контролем на этапе компиляции (перенесли в runtime но такие ошибки, как оказалось, очень редки.
Что касается проблемы, у нас можно делать примерно такие вызовы Root["Age"], несмотря на то, что Age атрибут User-а.
совсем не понял, как вы решили проблему
Если неопределённость - это просто null, то при наличии в формуле неопределённого инта, например, полетит эксепшен. Нужно только убедить жаву, что у нас инт бокснутый. В шарпе - можно, наверное. Никогда не заморачивался, там действительно проще обёртку навернуть автоматическим макрогенератором.
А вот в вижуал бейсике вообще есть мега-конструкция On Error Resume Next, которая этот эксепшен проигнорирует. Понятия не имею, что произойдёт дальше.
exception - это совсем не аля Excel.
совсем не понял, как вы решили проблемуну не то чтобы решили, она просто решается автоматически в нашем подходе. В ТЗ атрибуты имели уникальные имена, т.е. фактически по имени атрибута можно определить тип сущности, к которой принадлежит арибут. Поэтому мы предоставили возможность пользователю не указывать путь от текущей сущности к сущности, который принадлежит данный атрибут. Это решение пока не идеально, но в том проекте оно сработал хорошо.
т.е. фактически получается, что вы делаете - Root["Config.User.Age"] - но так пропадает возможность Intellisence-а и проверки имен при компиляции.
Настройщика ты бы тоже посадил бы в Eclipse?
скорее мы делаем Root["User.Age"]. У нас атрибутов было много и поэтому в ТЗ у атрибутов были кода, а не осмысленные имена типа "Age". Прописывать все атрибуты как свойства классов было не удобно.
Хочется иметь какие-нибудь удобные правила именования атрибутов. Имена атрибутов должны иметь смысл вне сущности.
Не знаю. Почему бы и нет? Напоминаю, Eclipse - это нечто большее чем IDE для Java. Строго говоря, Java-ой занимается JDT.
Более того, трудно поверить, но некоторые линуксоиды хотят юзать нечто похожее на Visual Studio. Они просто берут Eclipse+CDT и живут припеваючи.
Оставить комментарий
6yrop
простой для кого? Мне как-то пришлось кодировать большое количество арифметических расчетов. В тех задании формулы были напечатаны в Word-е. Составитель тех. задания не был обременен "простотой" Java-ы и писал формулы как ему было удобно. Нам повезло, что кодировать надо было на C#. Использовав такие "сложные" вещи как перегрузку операторов, неявное преобразование, индексеры и т.п., кодирование удалось свести практически к copy-paset из Word-а.Потом я задумывался, как бы это выглядело на Java -- выглядело бы ужасно, и очень плохо читаемо.