Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sprintf equivalent in Mathematica?

I don't know why Wikipedia lists Mathematica as a programming language with printf. I just couldn't find the equivalent in Mathematica.

My specific task is to process a list of data files with padded numbers, which I used to do it in bash with

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

The closest function I found in Mathematica is PaddedForm. And after some trial and error, I got it with

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

It is very odd that I have to use the number 4 to get the result similar to what I get from "%05d". I don't understand this behavior at all. Can someone explain it to me?

And is it the best way to achieve what I used to in bash?

like image 443
jxy Avatar asked Sep 07 '25 16:09

jxy


1 Answers

I wouldn't use PaddedForm for this. In fact, I'm not sure that PaddedForm is good for much of anything. Instead, I'd use good old ToString, Characters and PadLeft, like so:

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

Then you can use StringForm and ToString to make your file name:

toNumberedFileName[n_Integer] :=
  ToString@StringForm["filename_``", toFixedWidth[n, 5]]

Mathematica is not well-suited to this kind of string munging.

EDIT to add: Mathematica proper doesn't have the required functionality, but the java.lang.String class has the static method format() which takes printf-style arguments. You can call out to it using Mathematica's JLink functionality pretty easily. The performance won't be very good, but for many use cases you just won't care that much:

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

You need to do a little more work, because JLink is a bit dumb about Java functions with a variable number of arguments. The format() method takes a format string and an array of Java Objects, and Mathematica won't do the conversion automatically, which is what the MakeJavaObject is there for.

like image 187
Pillsy Avatar answered Sep 10 '25 05:09

Pillsy