2

I have an array of floats x and would like to print the last row to screen as integers. The following code does not work and yields ArgumentError: @printf: first or second argument must be a format string. How can I print with a variable format string?

using Printf
@printf("%i "^length(x[end,:]), x[end,:]...)
Nathan Boyer
  • 1,412
  • 1
  • 6
  • 20

2 Answers2

2

Using @eval to compile a simple print statement every time is really a bad approach. There's no functionality for dynamic format strings etc. because Julia has a wide range of other nice tools to achieve the same things:

julia> join(stdout, (round(Int, y) for y in x[end, :]), " ")
1 0 1

And printing an array is really not what printf is made for (not even in C).

That is not to say that a printf function taking a runtime format string wouldn't be a nice thing, but see here for the reasoning behind making it a macro. I've never missed printf, but in case you really do, there's Formatting.jl, which provides all functinality you can imagine.

phipsgabler
  • 20,535
  • 4
  • 40
  • 60
  • Could you include a list of other tools available for printing in Julia? – Nathan Boyer May 29 '20 at 12:18
  • I ended up implementing the equivalent `join(stdout, round.(Int, x[end,:]), " ")`. Formatting.jl seems helpful if a bit overwhelming. – Nathan Boyer May 29 '20 at 15:34
  • It's more a generally rich infrastructure of helper functions, like in Python. And that strings are handled more easily as data structure. – phipsgabler May 30 '20 at 08:04
0

Our "constants" are still run-time values – they are write-once rather than compile-time constants like in C.

As a hack until julia gets real support for runtime format strings, this works:

using Printf
const fmt = "%i "^length(x[end,:])
@eval @printf($fmt, x[end,:]...)
San
  • 453
  • 3
  • 14
  • try it now please – San May 28 '20 at 15:22
  • That works. This works too `@eval @printf($("%i "^length(x[end,:])), x[end,:]...)`. I don't understand why I need the `$` though since `fmt` is already a string. – Nathan Boyer May 28 '20 at 15:39
  • 1
    The catch here is we are tricking the Julia compiler to evaluate the format string at compile-time, rather than runtime. – San May 28 '20 at 15:41
  • This answer is technically correct, but not a good recommendation. `@eval` should not just be randomly used to circumevent appearent "restrictions" of macros. You already wrote "hacky", but I still will downvote, until you add an explanation what the hack really does and what the consequences are. – phipsgabler May 29 '20 at 07:02