Pull to refresh

Comments 33

а еще проще можно было бы сделать на веб-странице, и еще проще можно было бы это сделать вообще на статической странице .html на языке JavaScript

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

Ага, вместо дистрибутивов ставь ноду ,обеспечивай доступность жаваскрипта. Следи за сертификатами. Безопасностью. Совет на 5 баллов)

На codepen код выкладывается и ссылкой шарится.

Я бы вообще в Excel или Гугл-таблицах сделал. Задачка-то примитивная.

А почему не веб сервис с "нарисуйте где резать красной линией толщиной 4"?

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

И можно придать расчётам вид любой формы для визуализации/печати, хранить калькуляцию для клиентов и т.п.

да, ты прав! в гугл.табицах это было бы проще и удобней! но как это помогло бы в закреплении знаний в python.....

Да, здесь надо разделить задачи. Как освоение Питона - пример хороший. Как практически нужная штука - нет, в бизнесе (смотрим заголовок) такие решения скорее вредны чем полезны.

Можно через сниппет кода, закладку в браузере

У вас "Маталла" вместо "Металла" на скриншоте

    t_list=[ 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 20]
    price_list_100=[27, 36, 57, 64, 76, 87, 111, 154, 191, 224, 360, 519]
    price_list_101=[20, 28, 43, 50, 58, 68, 84, 125, 144, 186, 298, 432]
    for i in range(len(t_list)):
        if t == t_list[i] and rezka <= 100:
            rezka_price= price_list_100[i]
        elif t == t_list[i] and rezka >100:
            rezka_price= price_list_101[i]

аплодисменты в студию!!

Надо бы вам разузнать о словарях, а то как-то неловко получается.

Я.Практикум, зачем так халтурите?

Для того, чтобы этот код стал питоновским, заменить: for i in range(len(t_list)):

на

for i, t_list_item in enumerate(t_list):

И вынести константы:

REZKA_LIMIT = 100

CUTTING_LIMIT = 5000

Вот твоя "программа" на Делфи, которую я написал за 10 минут и в 60 строк кода

var
  Form4: TForm4;
  t_list: TArray<Integer> = [1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 20];
  price_list_100: TArray<Integer> = [27, 36, 57, 64, 76, 87, 111, 154, 191, 224, 360, 519];
  price_list_101: TArray<Integer> = [20, 28, 43, 50, 58, 68, 84, 125, 144, 186, 298, 432];

implementation

{$R *.fmx}

procedure TForm4.metal_params;
begin
  var metal_square :=(StrToFloat(ent_length.Text) * StrToFloat(ent_width.Text) * 0.000001) * StrToFloat(ent_number_of_pieces.Text);
  lbl_metal_square.Text := 'Площадь металла: ' + FloatToStr(metal_square) + ' m^2';
  var metal_massa := StrToFloat(ent_length.Text) * StrToFloat(ent_width.Text) * StrToFloat(ent_t.Text) * StrToFloat(ent_number_of_pieces.Text) * 0.0000078;
  lbl_metal_massa.Text := 'Масса металла: ' + FloatToStr(metal_massa) + ' кг';
  metal_money := metal_massa * 100;
  lbl_metal_money.Text := 'Стоимость металла: ' + CurrToStr(Round(metal_money)) + ' рублей';
end;

procedure TForm4.cutting_cost;
begin
  var cutting_price := 0;
  var cutting_length := StrToFloat(ent_rezka.Text);
  for var i := 0 to Length(t_list) - 1 do
    if (StrToInt(ent_t.Text) = t_list[i]) and (cutting_length <= 100) then
      cutting_price := price_list_100[i]
    else if (StrToInt(ent_t.Text) = t_list[i]) and (cutting_length > 100) then
      cutting_price := price_list_101[i];
  cutting_money := cutting_length * cutting_price;
  if cutting_money < 5000 then cutting_money := 5000;
  lbl_cutting_money.Text := 'Стоимость лазерной резки: ' + CurrToStr(cutting_money) + ' рублей';
end;

procedure TForm4.insert_cost;
begin
  insert_money := StrToFloat(ent_vstavki.Text) * 5;
  lbl_insert_money.Text := 'Стоимость вставок: ' + CurrToStr(insert_money) + ' рублей';
end;

procedure TForm4.bending_cost;
begin
  var bending_price := 0.0;
  var bending_count := StrToFloat(ent_gibov.Text);
  if bending_count < 20 then bending_price := 200 else bending_price := 100;
  bending_money := bending_count * bending_price;
  lbl_bending_money.Text := 'Стоимость гибки: ' + CurrToStr(bending_money) + ' рублей';
end;

procedure TForm4.cost_out;
begin
  metal_params();
  cutting_cost();
  insert_cost();
  bending_cost();
  lbl_out_cost.Text := 'Если металл наш: ' + IntToStr(Round(metal_money + cutting_money + insert_money + bending_money));
  lbl_out_cost2.Text := 'Если метал НЕ наш: ' + IntToStr(Round(cutting_money + insert_money + bending_money));
end;

procedure TForm4.btn_goClick(Sender: TObject);
begin
  cost_out;
end;

Плюс, она не требует зависимостей и прям сейчас могу нажать кнопу и собрать её под Андроид, иОС, мак или линукс. Более я не писал ни строчки

Брависсимо! Жаль не могу лайк поставить

После небольшого кол-ва кликов мышкой, мы получаем вот такое

А ну и я ещё немного оптимизировал и улучшил код
function TForm4.GetMetalCost(ALength, AWidth, ADepth, ANoP: Int64; out AMetalSquare, AMetalMassa: Extended): Extended;
begin
  AMetalSquare := (ALength * AWidth * 0.000001) * ANoP;
  AMetalMassa := ALength * AWidth * ADepth * ANoP * 0.0000078;
  Result := AMetalMassa * 100;
end;

function TForm4.GetCuttingCost(ACuttingLength, ANoP: Int64): Int64;
begin
  Result := 0;
  if FPriceList.ContainsKey(ANoP) then Result := ACuttingLength * FPriceList.Items[ANoP][Ord(ACuttingLength > 100)];
  if Result < 5000 then Result := 5000;
end;

function TForm4.GetInsertCost(AInsertCount: Int64): Int64;
begin
  Result := AInsertCount * 5;
end;

function TForm4.GetBendingCost(ABendingCount: Int64): Int64;
begin
  Result := IfThen(ABendingCount < 20, ABendingCount * 200, ABendingCount * 100);
end;

procedure TForm4.ButtonCalcClick(Sender: TObject);
begin
  var ALength := StrToInt64(EditLength.Text);
  var AWidth := StrToInt64(EditWidth.Text);
  var ADepth := StrToInt64(EditDepth.Text);
  var ANoP := StrToInt64(EditNumberOfPieces.Text);
  var ACuttingLength := StrToInt64(EditCutting.Text);
  var AInsertCount := StrToInt64(EditInsert.Text);
  var ABendingCount := StrToInt64(EditBending.Text);

  var AMetalSquare: Extended;
  var AMetalMassa: Extended;

  try
    var MetalCost := GetMetalCost(ALength, AWidth, ADepth, ANoP, AMetalSquare, AMetalMassa);
    var CuttingCost := GetCuttingCost(ACuttingLength, ANoP);
    var InsertCost := GetInsertCost(AInsertCount);
    var BendingCost := GetBendingCost(ABendingCount);

    LabelDate.Text := FormatDateTime('dd.mm.yyyy h:NN:ss', Now);
    lbl_metal_money.Text := Format('%d рублей', [Round(MetalCost)]);
    lbl_metal_square.Text := Format('%f m^2', [AMetalSquare]);
    lbl_metal_massa.Text := Format('%f кг', [AMetalMassa]);
    lbl_cutting_money.Text := Format('%d рублей', [CuttingCost]);
    lbl_insert_money.Text := Format('%d рублей', [InsertCost]);
    lbl_bending_money.Text := Format('%d рублей', [BendingCost]);
    lbl_out_cost.Text := Format('%d р.', [Round(MetalCost + CuttingCost + InsertCost + BendingCost)]);
    lbl_out_cost2.Text := Format('%d р.', [CuttingCost + InsertCost + BendingCost]);
  except
    ShowMessage('Ошибка расчетов');
  end;
end;

Теперь он устойчив к ошибкам ввода и считает огромные числа

Если нужно, я могу скинуть проект. Для его сборки достаточно поставить бесплатную версию среды Delphi. Открыть проект и нажать кнопку "Play". Сейчас в релизе ехе выходит 8мб

да я к тому, что Вы быстро набросали прогу, хотя сам проверить не могу (не спец в Delphi), но почти уверен что можно запустить после компиляции достаточно легко на ... На винде?

На чем угодно можно запустить (собрать). Выглядеть будет одинаково. И работать

Можно еще для подобных простых утилит использовать Terminal UI — например так примерно будет выглядеть с библиотекой tview для Go:



Размер бинарника будет примерно 3-4мб.

Ну, если собрать на vcl, а не на fmx, как я. Это ограничит, конечно, виндой, но бинарник будет весь мб 2. Или меньше. Но при этом выглядеть могут примерно так же. Может чуть хуже

Отлично, но на джаве еще проще, никаких зависимостей, собирать ничего не надо, лишь бы виртуальная машина стояла в системе

А в чем сложность собрать? Кнопку одну нажать только надо) Ладно, две кнопки. Одну чтоб выбрать платформу, вторую, чтоб собрать приложение)

После вашего поста тоже захотел переписать на близкую к душе кроссплатформенную технологию.

Поэтому вот приложение на Avalonia, которое запускается на Windows, Linux, MacOS, Android, IOS и WebAssembler (запускается в браузере)

Исходный код на гитхаб для посмотреть

Столько кода ради 7 полей и одного вычисления. Собственно я как раз для обратного показывал пример. ВебАсм мы кстати тоже ждём для Делфи. А пока, если надо для веб, то через отдельный фреймворк. Но принцип тот же - меньше лишнего кода. Основное сосредоточение на функциональной части, а не на том как и где отображать

Да там большинство кода это шаблон.Но всё равно кода можно намного меньше было, просто я не стал всё писать в Code-behind в MVVM freandly фреймоворке.
Столько кода, потому что вычисления вынесены в отдельный сервис, а сама приложение разбито на Model, ViewModel и View. Поэтому View такое жирное, т.к. живёт само по себе. И в принципе его без проблем можно оторвать от всего остального и безболезненно переписать.
А сами ViewModel и Model там из нескольких строк состоят (равному количеству полей конечно же). Зато очень всё удобно и масштабируемо и хорошо разделяет ответственность. Конечно в данном конкретном случае это овернженеринг, но например к этому с 1 тычка прикручивается генератор PDF отчётов (с помощью PDF.Quest), т.к. модель отдельно существует.

А так, если всю логику поместить во View, напрямую биндиться к эвентам и забирать напрямую значения из контролов, то выйдет примерно столько же.

У меня, на самом деле, пропущен только Model этап и контроллер не отделен от View model. Но это сделать, если надо можно легко. И так же все масштабировать. В делфи по умолчанию используется MVC/MVVM (там тонкая грань). Просто тогда ещё не было таких понятий, но уже принцип был похожий.

Т.е. у нас код представления отделен от кода контроллера/модели предоставления. Обычно, мы ещё сильнее его отделяем функциональный код в контроллеры, чтоб можно было на одних данных работать с разных представления (форм/фреймов).

Так что с масштабированием проблем тоже нет.

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

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

Помимо всего этого, есть такая штука, как "стили". Что является не просто скиндвижком, а системой, которая позволяет применить вариант отображения для любого отображаемого контрола. Т.е. мы можем создать стиль кнопки, которая содержит внутри себя ещё кнопку или даже текстовое поле и применить этот стиль к кнопке в окне или вообще к любому контроля и он будет отображаться так, как мы сделали стиль. Можем создать стиль, в который поместим прямоугольник, настроим его цвет и другие параметры, настроим анимацию при наведении или нажатии, поместим текст и картинку слева и можем применить этот стиль к чему угодно. Да хоть модем кнопку отражать как таблицу (толку правда от такого мало). И все это опять же без кода. Как видим, так и настраиваем. Все применяется в дизайнтайме (в режиме реального времени).

Ну и это только верхушка айсберга)

Там ещё куча всякого по типу шейдеров, эффектов, 3д, анимации любых свойств по триггерами или без и т.д.

Хочу уметь также, но с Делфи опыта нет. Как на VBnet писать приложение с возможностью сборки по Вин и Андроид (если конечно возможно)? FMX это что-то, что позволяет вот это все?
UPDATE:
Вопрос снят.
Нашел - FireMonkey Cross-Platform Framework.

Сейчас учу тему по ООП, хз делать V 4.0 или что то более масштабное сообразить

Если интересно развиваться дальше как программист, то стоит продолжить улучшать эту программу. Это хороший тренировачный полигон.

ООП штука хорошая, но слишком большая. Советую для начала посмотреть что такое dataclass, а потом, перечитав тему Функции, переделать код ещё раз:

1. Нужно разделить всё на две части - одна исключительно рисует форму и получае данные, а другая считает площадь и стоимость.

2. Взаимодействие между ними должно сводиться к одной строчке: estimate = cost_out(order). 3. Ключеное слово global не использовать.

4. В рассчётной части не должно быть ни одной русской буквы, кроме комментариев.

Changes requested :-)

Я не на что не притендую я начинающий. Но может убрать слово посчитать вовсе? У питона развен нет слушателей? Пока ничего не ввел все в звездочках, и просчитывает калькулятор при вводе данных.
Увеличить шрифт для быстрейшего понимания.

Ютуб- наглядный помошник #1

Когда-то пытался стать оператором на лазерной резке TCL-3030, а сейчас в айтишке, и зп больше 100. Не думал, что до такого в родном екб доживу. Поставил автору лайк за статью, и+ в карму, - за замах.

Sign up to leave a comment.

Articles