Подтвердить что ты не робот

Эквивалент Sprintf в Mathematica?

Я не знаю, почему Wikipedia перечисляет Mathematica как язык программирования с printf. Я просто не мог найти эквивалент в Mathematica.

Моя специальная задача - обработать список файлов данных с заполненными номерами, которые я использовал для этого в bash с помощью

fn=$(printf "filename_%05d" $n)

Ближайшая функция, найденная в Mathematica, PaddedForm. И после некоторых проб и ошибок, я получил его с

"filename_" <> PaddedForm[ [email protected]#, 4, NumberPadding -> {"0", ""} ]&

Очень странно, что я должен использовать число 4, чтобы получить результат, аналогичный тому, что я получаю от "% 05d". Я вообще не понимаю этого поведения. Может кто-нибудь объяснить это мне?

И лучший способ добиться того, что я использовал в bash?

4b9b3361

Ответ 1

Я бы не использовал PaddedForm для этого. На самом деле, я не уверен, что PaddedForm хорош для большей части всего. Вместо этого я бы использовал старые добрые ToString, Characters и PadLeft, например:

toFixedWidth[n_Integer, width_Integer] := 
  StringJoin[PadLeft[Characters[ToString[n]], width, "0"]]

Затем вы можете использовать StringForm и ToString, чтобы создать свое имя файла:

toNumberedFileName[n_Integer] :=
  [email protected]["filename_``", toFixedWidth[n, 5]]

Mathematica не подходит для такого рода перекручивания строк.

РЕДАКТИРОВАТЬ, чтобы добавить:. Соответственно, у Mathematica нет требуемых функций, но класс java.lang.String имеет статический метод format(), который принимает аргументы printf -style. Вы можете легко обращаться к нему с помощью функции Mathematica JLink. Производительность будет не очень хорошей, но для многих случаев использования вам просто все равно не будет:

Needs["JLink`"];
LoadJavaClass["java.lang.String"];
LoadJavaClass["java.util.Locale"];
sprintf[fmt_, args___] :=
 String`format[Locale`ENGLISH,fmt,
  MakeJavaObject /@
   Replace[{args},
    {x_?NumericQ :> [email protected],
     x : (_Real | _Integer | True | 
         False | _String | _?JavaObjectQ) :> x,
     x_ :> MakeJavaExpr[x]},
    {1}]]

Вам нужно немного поработать, потому что JLink немного тупо о функциях Java с переменным числом аргументов. Метод format() принимает строку формата и массив Java Object s, и Mathematica не будет делать преобразование автоматически, что и есть MakeJavaObject.

Ответ 2

Я столкнулся с одной и той же проблемой совсем немного и решил записать свою собственную функцию. Я не делал этого в Java, а вместо этого использовал только строковые операции в Mathematica. Это оказалось довольно продолжительным, так как я действительно нуждался в функциональности% f, но он работает, и теперь у меня есть пакет, который я могу использовать в любое время. Здесь ссылка на проект GitHub:

https://github.com/vlsd/MathPrintF

Он поставляется с инструкциями по установке (на самом деле просто копирует каталог где-то в $Path).

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

Ответ 3

Вы также можете определить функцию, которая передает все аргументы в StringForm [] и использовать IntegerString или функции заполнения, как было упомянуто ранее:

Sprintf[args__] := StringForm[args__] // ToString;
file = Sprintf["filename_``", IntegerString[n, 10, 5]];

Ответ 4

IntegerString делает именно то, что вам нужно. В этом случае это будет

IntegerString[x,10,5]

Ответ 5

Я согласен с Пиллси. Вот как я это сделаю. Обратите внимание на удобную функцию cat, которая, как я полагаю, похожа на sprintf (за исключением тех, которые используются в StringForm), поскольку она работает как Print (вы можете распечатать любую конкатенацию выражений без преобразования в String), но генерирует строку вместо отправка на стандартный вывод.

cat = [email protected]@(ToString/@{##})&;

pad[x_, n_] := If[[email protected][x]>=n, cat[x], 
                                          [email protected]@PadLeft[[email protected][x],n,"0"]]

cat["filename_", pad[#, 5]]&

Это очень похоже на ответ Pillsy, но я думаю, что cat делает его немного чище. Кроме того, я считаю, что безопаснее иметь это условное значение в функции пэда - лучше иметь неправильное заполнение, чем неправильное число.