Align columns of numbers by decimal point

Started by cormullion, July 20, 2006, 02:11:21 AM

Previous topic - Next topic

cormullion

Is there a clever way to align numbers by the decimal point when using the println and format functions?



205.492  
 201.729  
 201.38  
  -5.38672
  -1.38724
-158.966  
 123.63  


Or do I convert them to strings first, then calculate the amount of leading and trailing spaces to use?

Lutz

#1
format is used for this:



> (map (fn (num) (format "%10.2f" num)) '(1.22 123.456 12345.567))
("      1.22" "    123.46" "  12345.57")
>


The 10 tells the format spec to make the whole field 10 positions long. This includes the decimal point and all leading spaces. The 2 tells it to format for 2 decimals begind the point. As you can see in the example, it also rounds numbers.



This works only when all numbers are formatted for the same amount of decimals after the point. In your case you could make a strings with a high count after the decimal count:

> (map (fn (num) (format "%10.5f" num)) '(1.2 123.45 12345.567))
("   1.20000" " 123.45000" "12345.56700")
>

... and than replace trailing 0's in those strings with some clever regular expression ;)



Lutz

Lutz

#2
.... like this:



> (replace {(0+)$} "12345.567000" (dup " " (length $1)) 0)
"12345.567   "
>


the pattern {(0+)$} finds one or more trailing zeros and replaces them with the same number of spaces. Putting it all together:



(map (fn (num) (replace {(0+)$}
                          (format "%12.5f" num)
                          (dup " " (length $1)) 0) )
          '(1.2 123.45 12345.567))
=>("     1.2    " "   123.45   " " 12345.567  ")


Lutz

cormullion

#3
Of course - now I see you do it it looks natural. For some reason I hadn't thought of trying to capture the results of format and continuing to work on them, I've just been using format in print statements.



Thanks Lutz!

cormullion

#4
I ended up using this:


(replace {(0+)[^0-9|.]} temp (dup " " (length $1)) 0)

hoping to strip 0's if not followed by more digits or decimal point. How long did it take for you guys to become blackbelts in RegExp-Do? :-) Takes me an hour per regex...

m i c h a e l

#5
I only have my yellow belt in regex, so I'm around the same level as you, cormullion.



I remember a quote having to do with someone having a problem that he decided to solve with regular expressions. "Now," as the saying goes, "he has two problems." ;-)



m i c h a e l