How to align output in columns?

I have the following script:

println("n \t n! \t\t Approximation \t\t Ratio")

for n in 1:10
    fact  = factorial(big(n))
    stir  = n^n * exp(-n) * sqrt(2 * Ο€ * n )
    ratio = Float32(fact/stir)
    println("$n \t $fact \t $stir \t $ratio")
end

This results in the following output:


n 	 n! 		 Approximation 		 Ratio
1 	 1 	 0.9221370088957891 	 1.0844376
2 	 2 	 1.9190043514889832 	 1.0422071
3 	 6 	 5.836209591345864 	 1.0280645
4 	 24 	 23.50617513289329 	 1.0210083
5 	 120 	 118.01916795759008 	 1.016784
6 	 720 	 710.0781846421849 	 1.0139729
7 	 5040 	 4980.395831612461 	 1.0119678
8 	 40320 	 39902.3954526567 	 1.0104656
9 	 362880 	 359536.87284194824 	 1.0092984
10 	 3628800 	 3.598695618741036e6 	 1.0083654

Which is the better approach for cases like this one when I want to print outputs in columns?

Perhaps:

using DataFrame

df = DataFrame(n = Int[], n! = Int[], Approximation = Float64[], Ratio = Float64[])

for n in 1:10
    fact  = factorial(big(n))
    stir  = n^n * exp(-n) * sqrt(2 * Ο€ * n )
    ratio = Float32(fact/stir)
    push!(df, [n, fact, stir, ratio])
end

strwidths = [maximum(strwidth.(string.([df[:, i]; names(df)[i]]))) for i in 1:size(df, 2)]

io = IOBuffer()

# Print headers
for (i, header) in enumerate(names(df))
	print(io, rpad(header, strwidths[i]), "\t")
end
println(io)

for j in 1:size(df, 1)
	for i in 1:size(df, 2)
		print(io, rpad(df[j,i], strwidths[i]), "\t")
	end
	println(io)
end

print(String(take!(io)))

giving

n 	n!     	Approximation      	Ratio             	
1 	1      	0.9221370088957891 	1.084437608718872 	
2 	2      	1.9190043514889832 	1.04220712184906  	
3 	6      	5.836209591345864  	1.028064489364624 	
4 	24     	23.50617513289329  	1.0210082530975342	
5 	120    	118.01916795759008 	1.0167839527130127	
6 	720    	710.0781846421849  	1.0139728784561157	
7 	5040   	4980.395831612461  	1.0119677782058716	
8 	40320  	39902.3954526567   	1.0104656219482422	
9 	362880 	359536.87284194824 	1.0092984437942505	
10	3628800	3.598695618741036e6	1.0083653926849365	

The code is not very well polished but might give you a start.

7 Likes

Thank you… I am sorry, I didn’t want you to write the whole code for me… I was just thinking there was something more concise… thank you for the the code and the many ideas on it…

1 Like

You might find it easier to use something like GitHub - JuliaString/StringLiterals.jl: Implement improved string literals with Swift-style syntax for interpolation, hex, & unicode characters, plus C & Python style formatting and Unicode, HTML, LaTeX, and Emoji entities,
and I think it gives cleaner, easier to read output than the other solution.

It is not registered, so you need to load it and it’s dependencies the first time as follows:

const loc = "https://github.com/JuliaString/"
for pkg in ("StrTables",
            "HTML_Entities", "LaTeX_Entities", "Unicode_Entities", "Emoji_Entities",
            "Format", "StringLiterals")
    Pkg.clone(string(loc, pkg, ".jl"))
end

Then you can write formatted output very succintly:

using StringLiterals

function out()
    pr"""n   \%8s("n!")   \%16s("Approximation")   \%10s("Ratio")\n"""
    for n in 1:10
        fact  = factorial(big(n))
        stir  = n^n * exp(-n) * sqrt(2 * Ο€ * n )
        ratio = Float32(fact/stir)
        pr"\%-3d(n) \%8d(fact)   \%16.8f(stir)   \%10.8f(ratio)\n"
    end
end

The output is:

n         n!      Approximation        Ratio
1          1         0.92213701   1.08443761
2          2         1.91900435   1.04220712
3          6         5.83620959   1.02806449
4         24        23.50617513   1.02100825
5        120       118.01916796   1.01678395
6        720       710.07818464   1.01397288
7       5040      4980.39583161   1.01196778
8      40320     39902.39545266   1.01046562
9     362880    359536.87284195   1.00929844
10   3628800   3598695.61874104   1.00836539
5 Likes

Yeah, using seven packages and hard coding the alignments will indeed make the code shorter.

5 Likes

Another option might be to use @printf

Many packages depend on others - the only issue is that the packages are not yet registered.
No need to be snide.

3 Likes

Using @printf as suggested:

julia> using Printf

julia> function justified()
           @printf("%10s %10s  %-20s   %s \n", "n", "n!", "Approximation", "Ratio")

           for n in 1:10
               fact  = factorial(big(n))
               stir  = n^n * exp(-n) * sqrt(2 * Ο€ * n )
               ratio = Float32(fact/stir)
               @printf("%10d %10d  %-20s   %f \n", n, fact, string(stir), ratio)
           end
       end
justified (generic function with 1 method)

julia> justified()
         n         n!  Approximation          Ratio
         1          1  0.9221370088957891     1.084438
         2          2  1.9190043514889832     1.042207
         3          6  5.836209591345864      1.028064
         4         24  23.50617513289329      1.021008
         5        120  118.01916795759008     1.016784
         6        720  710.0781846421849      1.013973
         7       5040  4980.395831612461      1.011968
         8      40320  39902.3954526567       1.010466
         9     362880  359536.87284194824     1.009298
        10    3628800  3.598695618741036e6    1.008365
        
2 Likes

There is also the wonderful PrettyTables package…

julia> using PrettyTables
julia> pretty_table(df;formatter=ft_printf(["%10d","%10d","%5.6f","%5.6f"],[1,2,3,4]),alignment=[:r,:r,:l,:l])
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          n β”‚         n! β”‚ Approximation  β”‚ Ratio    β”‚
β”‚      Int64 β”‚      Int64 β”‚ Float64        β”‚ Float64  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚          1 β”‚          1 β”‚ 0.922137       β”‚ 1.084438 β”‚
β”‚          2 β”‚          2 β”‚ 1.919004       β”‚ 1.042207 β”‚
β”‚          3 β”‚          6 β”‚ 5.836210       β”‚ 1.028064 β”‚
β”‚          4 β”‚         24 β”‚ 23.506175      β”‚ 1.021008 β”‚
β”‚          5 β”‚        120 β”‚ 118.019168     β”‚ 1.016784 β”‚
β”‚          6 β”‚        720 β”‚ 710.078185     β”‚ 1.013973 β”‚
β”‚          7 β”‚       5040 β”‚ 4980.395832    β”‚ 1.011968 β”‚
β”‚          8 β”‚      40320 β”‚ 39902.395453   β”‚ 1.010466 β”‚
β”‚          9 β”‚     362880 β”‚ 359536.872842  β”‚ 1.009298 β”‚
β”‚         10 β”‚    3628800 β”‚ 3598695.618741 β”‚ 1.008365 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
6 Likes