Здравствуйте, Sharov, Вы писали:
S>Я про удобность питона для подобных задач не спорю. Но рано или поздно эти наработки должны уйти в продакшн, или работать на компилируемом языке. И чем тут C# кроме отсутствия библиотек хуже?
Прямо сейчас ему явно не хватает кроссплатформенности. Я его плохо знаю, но написание кода должно быть удобно для непрограммистов, математиков или статистиков. Такое возможно? При всей моей любви к С++ я точно знаю, что на нём неспециалист писать не сможет. Можно ли на C# писать в чисто процедурном стиле? Чтобы не думать о классах, их иерархии и архитектуре приложения? Это тоже не нужно. Язык должен быть простым, чтобы на нём могли писать все.
Про нехватку библиотек уже говорили. Кто их будет писать? Или хотя бы удобные биндинги? Например, я использовал OpenCV из С, из С++, из C# (через Emgu CV) и через Питон. В С было слишком многословно и муторно, в С++ удобно, в Питоне очень удобно и кратко, а в С# я испытывал проблемы чисто языковые (
вот пример): using, new, бесконечное указание типов матриц. Зачем это?!! Почему в С++ и Питоне всё это не нужно?
Вот кусочек кода:
Bgr[] colors = new Bgr[] {
new Bgr(0, 0, 255),
new Bgr(0, 255, 0),
new Bgr(255, 0, 0)};
Создаётся статический массив из трёх структур. Зачем тут 4 раза вызывается new? Мне непонятно. Да, я не программирую на C#, но такие конструкции выглядят дикостью на фоне современного прогресса в С++. С таким подходом никто в здравом уме пользоваться C# не будет.
Добавлю кусочек из того же примера:
// display the original training samples
for (int i = 0; i < (trainSampleCount / 3); i++)
{
PointF p1 = new PointF(trainData1[i, 0], trainData1[i, 1]);
img.Draw(new CircleF(p1, 2.0f), colors[0], -1);
PointF p2 = new PointF(trainData2[i, 0], trainData2[i, 1]);
img.Draw(new CircleF(p2, 2.0f), colors[1], -1);
PointF p3 = new PointF(trainData3[i, 0], trainData3[i, 1]);
img.Draw(new CircleF(p3, 2.0f), colors[2], -1);
}
На С++ будет так:
for (int i = 0; i < (trainSampleCount / 3); i++)
{
cv::circle(img, cv::Point(trainData1[i, 0], trainData1[i, 1]), 2, colors[0]);
cv::circle(img, cv::Point(trainData2[i, 0], trainData2[i, 1]), 2, colors[1]);
cv::circle(img, cv::Point(trainData3[i, 0], trainData3[i, 1]), 2, colors[2]);
}
На Питоне примерно также, но можно cv::Point не писать, а отправить туда тупл.
Разница колоссальная и по объёму кода и по идеологии. Не надо создавать точки, создавать окружности и у картинки вызывать метод Нарисовать Окружность. Подход будет: нарисовать Окружность с таким-то цетром и радиусом такого цвета. Как по мне, это логичнее.