[ID CS4-CS6] Заполнение фрейма числами с шагом (проблема с нулем)

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
Вопрос от скрипто-чайника.

Задача: заполнить выбранный текстовой фрейм числами от Y1 до Y2 с заданным шагом.
Кусочек скрипта про заполнение выглядит так:

JavaScript:
var myDoc = app.activeDocument.selection[0];
var mySel = myDoc.parentStory;

// Заполняем фрейм
var y1 = myY1; // число 1
var y2 = myY2; // число 2 (y2 < y1)
var yS = myY3; // шаг

for (i = y1; i >=y2; i -= yS){
    mySel.contents += i + "\r";
    }
// end

С целыми переменными y1 и y2 проблем не обнаружено, а если переменная с точкой, то редко получается "правильный" ноль и часто теряется последнее значение.
Что не так? Как это можно исправить?

JavaScript:
var myDoc = app.activeDocument.selection[0];
var mySel = myDoc.parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right"; 
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
 // end
 
// Заполняем фрейм
var y1 = myY1;
var y2 = myY2;
var yS = myY3; // шаг

for (i = y1; i >=y2; i -= yS){
    mySel.contents += i + "\r";
    }
// end
 

Вложения

  • переход_через_ноль.jpg
    переход_через_ноль.jpg
    149.6 КБ · Просм.: 192

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 138
Реакции
10 835
Откройте для себя toFixed
 
  • Спасибо
Реакции: Masia

_MBK_

Пикирующий бомбардировщик
15 лет на форуме
Сообщения
33 138
Реакции
10 835

Oleg Butrin

20 лет на форуме
Сообщения
1 989
Реакции
1 213
JavaScript:
var myDoc = app.activeDocument;
if (!myDoc.selection.length) {
    exit()
};
var mySel = myDoc.selection[0].parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right";
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
 // end
 
// Заполняем фрейм
var y1 = parseFloat(myY1);
var y2 = parseFloat(myY2);
var yS = Math.abs(parseFloat(myY3)); // шаг

var content = [];
switch (true) {
    case y2 > y1:
        while (y1 <= y2) {
            content.push(y1);
            y1 += yS
        }
    break;
    case y2 < y1:
        while (y1 >= y2) {
            content.push(y1);
            y1 -= yS
        }
    break;
    default:
        content.push(y1);
    break;
}

mySel.contents = content.join("\n");
// end

Нужно объяснять, в чем разница?
 
  • Спасибо
Реакции: Gad и Masia

Gad

Сообщения
2 971
Реакции
1 405
Остановится на максимальном кратном
Угу :) Соответственно Y2 достигнуто не будет и задача будет не выполнена :)
JavaScript:
var myDoc = app.activeDocument;
if (!myDoc.selection.length) {
    exit()
};
var mySel = myDoc.selection[0].parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right";
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
// end

// Заполняем фрейм
var y1 = parseFloat(myY1);
var y2 = parseFloat(myY2);
var yS = Math.abs(parseFloat(myY3)); // шаг

var content = [];
switch (true) {
    case y2 > y1:
        while (y1 <= y2) {
            content.push(y1);
            y1 += yS
        }
    break;
    case y2 < y1:
        while (y1 >= y2) {
            content.push(y1);
            y1 -= yS
        }
    break;
    default:
        content.push(y1);
    break;
}

mySel.contents = content.join("\n");
// end

Нужно объяснять, в чем разница?
Код:
var myDoc = app.activeDocument;
if (!myDoc.selection.length) {
    exit()
};
var mySel = myDoc.selection[0].parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right";
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
 // end
 
// Заполняем фрейм
var y1 = parseFloat(myY1.replace(",", "."));
var y2 = parseFloat(myY2.replace(",", "."));
var yS = Math.abs(parseFloat(myY3.replace(",", "."))); // шаг
var cf = String(yS).split('.')[1].length
var i = Math.abs((y2 - y1)/yS)
var content = [];
switch (true) {
    case y2 > y1:
        for (i ; i >=0; i--){
            content.push(y1.toFixed(cf));
            y1 += yS
        }
    break;
    case y2 < y1:
        for (i ; i >=0; i--){
            content.push(y1.toFixed(cf));
            y1 -= yS
        }
    break;
    default:
        content.push(y1);
    break;
}

mySel.contents = content.join("\n");
// end
Чуток поменял:)
 

Gad

Сообщения
2 971
Реакции
1 405
Хотя нет... :( идея ограничивать точность вычислений числом знаков после запятой шага приращения не прокатит, шаг может быть целочисленным, а диапазон задан дробными числами, нужно либо вычислять число знаков после запятой для всех 3-х задаваемых чисел и брать максимальное, либо просто задавать как переменную, иначе переход через 0 так и дает ошибку :(
 
Последнее редактирование:

Gad

Сообщения
2 971
Реакции
1 405
В итоге задал точность вычисления константой, вроде результат вывода приемлемый :)
Код:
var myDoc = app.activeDocument;
if (!myDoc.selection.length) {
    exit()
};
var mySel = myDoc.selection[0].parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right";
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
// end

// Заполняем фрейм
var y1 = parseFloat(myY1.replace(",", "."));
var y2 = parseFloat(myY2.replace(",", "."));
var yS = Math.abs(parseFloat(myY3.replace(",", "."))); // шаг
var    c = 16 // точность вычислений (знаков после запятой)
var i = Math.abs((y2 - y1)/yS)
var content = [];
switch (true) {
    case y2 > y1:
        for (i ; i >=0; i--){
            content.push(parseFloat(String(y1.toFixed(c))));
            y1 += yS
        }
    break;
    case y2 < y1:
        for (i ; i >=0; i--){
            content.push(parseFloat(String(y1.toFixed(c))));
            y1 -= yS
        }
    break;
    default:
        content.push(y1);
    break;
}

mySel.contents = content.join("\n");

// end

Не по теме:
Интересно, есть ли более правильный способ привести число вида "1.0000" к виду "1" чем переводить его в строку, а потом назад в число?
 
Последнее редактирование:
  • Спасибо
Реакции: Masia

~RA~

Одарённая.
12 лет на форуме
Сообщения
11 808
Реакции
3 434
Интересно, есть ли более правильный способ привести число вида "1.0000" к виду "1" чем переводить его в строку, а потом назад в число?
В приличных языках есть (int), toInt() etc.
 

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
Хотя нет... :( идея ограничивать точность вычислений числом знаков после запятой шага приращения не прокатит, шаг может быть целочисленным, а диапазон задан дробными числами, нужно либо вычислять число знаков после запятой для всех 3-х задаваемых чисел и брать максимальное, либо просто задавать как переменную, иначе переход через 0 так и дает ошибку :(
Как раз хотела написать, что эксперименты показали, что с целочисленными не работает.

Последний вариант работает (если добавить в трех местах кучу скобочек ;) ), ноль отражает уверенно. Но последнее число все равно теряется.
 

Вложения

  • screenshot-341.jpg
    screenshot-341.jpg
    111.8 КБ · Просм.: 142

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
@Gad , в коде вроде смайликов не появлялось. Вот в этих строках не хватило.

Код:
var yS = Math.abs(parseFloat(myY3.replace(",", ".");
content.push(parseFloat(String(y1.toFixed(c));
 

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
Да тут собственно parseFloat() это делает :) Перевод в строку и не нужен, сам затупил :)
Это про это место:
Код:
content.push(parseFloat(String(y1.toFixed(c))));
? Здесь не нужен string внутри parseFloat?


Осталась странность с шагом 0,1 / 0,2 / 0,4 - последнее число теряется.
 

Вложения

  • screenshot-341 (2).jpg
    screenshot-341 (2).jpg
    81.3 КБ · Просм.: 144

Gad

Сообщения
2 971
Реакции
1 405
Здесь не нужен string внутри parseFloat
угу
Код:
var myDoc = app.activeDocument;
if (!myDoc.selection.length) {
    exit()
};
var mySel = myDoc.selection[0].parentStory;

// диалоговое окно ввода
    var myWindow = new Window ("dialog", "Числа");

    // группа со строками ввода
    var myInputGroup1 = myWindow.add ("group");
    myInputGroup1.add ("statictext", undefined, "Число 1:");
    var myY1 = myInputGroup1.add ("edittext", undefined, "");
    myY1.characters = 10;
    myY1.active = true;

    var myInputGroup2 = myWindow.add ("group");
    myInputGroup2.add ("statictext", undefined, "Число 2:");
    var myY2 = myInputGroup2.add ("edittext", undefined, "");
    myY2.characters = 10;

    var myInputGroup3 = myWindow.add ("group");
    myInputGroup3.add ("statictext", undefined, "Шаг:");
    var myY3 = myInputGroup3.add ("edittext", undefined, "");
    myY3.characters = 10;
    myWindow.alignChildren = "right";

    // группа кнопок
    var myButtonGroup = myWindow.add ("group");
    myButtonGroup.alignment = "right";
    myButtonGroup.add ("button", undefined, "OK");
    myButtonGroup.add ("button", undefined, "Cancel");

    // проверка нажатия кнопок
    if (myWindow.show () == 1) {
        var myY1 = myY1.text;
        var myY2 = myY2.text;
        var myY3 = myY3.text;
        } else {exit ();}
// end

// Заполняем фрейм
var y1 = parseFloat(myY1.replace(",", "."));
var y2 = parseFloat(myY2.replace(",", "."));
var yS = Math.abs(parseFloat(myY3.replace(",", "."))); // шаг
var    c = 16 // точность вычислений (знаков после запятой)
var i = Math.abs((y2 - y1)/yS)+1
var content = [];
switch (true) {
    case y2 > y1:
        for (i ; i >0; i--){
            content.push(parseFloat(y1.toFixed(c)));
            y1 += yS
        }
    break;
    case y2 < y1:
        for (i ; i >0; i--){
            content.push(parseFloat(y1.toFixed(c)));
            y1 -= yS
        }
    break;
    default:
        content.push(y1);
    break;
}

mySel.contents = content.join("\n");

function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}
// end
Вот так должно все правильно работать:)
Вот в этих строках не хватило
:) когда вставлял все там было, принципа не понял, или при заключении в спойлер потерялись или при правке поста... срабатывает автозамена :(

Не по теме:
P.S. ну вот опять'))'
 
Последнее редактирование:
  • Спасибо
Реакции: Masia

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
Вот так должно все правильно работать:)

:) когда вставлял все там было, принципа не понял, или при заключении в спойлер потерялись или при правке поста... срабатывает автозамена :(

Не по теме:
P.S. ну вот опять'))'
Сегодня уже не потестирую. Завтра обязательно посмотрю. И пара вопросов есть ;]=
Спасибо!
 

Gad

Сообщения
2 971
Реакции
1 405
А, еще, если (y2 - y1)/yS не целое число задача таки не имеет решения и если нужно чтобы список не выходил за пределы заданных значений, после var i = Math.abs((y2 - y1)/yS)+1 нужно добавить например такое i = i.toFixed(16).split(".")[0]
 
Последнее редактирование:

Masia

Топикстартер
15 лет на форуме
Сообщения
127
Реакции
47
Вот так должно все правильно работать:)
У меня пара вопросов, если не затруднит:
1. Для чего в самом конце искать максимальный элемент в массиве?
JavaScript:
function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}
2. Зачем в этой строке parseFloat() (//принимает строку и возвращает десятичное число)? Т.е. я поняла, что он нам делает число уже из строки y1.toFixed(c), но пока не могу понять зачем. И разве y1.toFixed(c) само по себе не число?
JavaScript:
content.push(parseFloat(y1.toFixed(c)));

Попробовала без него и с заменой на "+" (//унарный оператор), вроде тоже работает. Разницу, что выводит по разному уловила, если что 8*).
JavaScript:
var c = 2;
content.push(+y1.toFixed(c));
Без "+" даже интересней, можно задавать количество знаков после запятой в диалоговом окне ))
 
  • Спасибо
Реакции: Gad