string formatting specifications

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
0
Gribouillis Gribouillis is offline Offline | Oct 24th, 2009
Partial formatting.
Normally, when you call format on a template string like "{x:<15.{precision}e}{y:<15.{precision}e}" , all the template's arguments must be passed to format, otherwise, a KeyError is raised (or IndexError for positional arguments). Here we need to pass 3 keyword arguments x, y and precision.
Using a subclass of string.Formatter, one can implement a partial formatting, with missing arguments. For example in the above example, we could instantiate first the precision to get the template "{x:<15.3e}{y:<15.3e}" , and then format this string with a pair of values x and y. Here is the code
  1. #!/usr/bin/env python
  2. from string import Formatter
  3.  
  4. class MissingField (object ):
  5. "Helper class to implement partial formatting"
  6. def __init__ (self ,name ):
  7. self .name =name
  8.  
  9. class MissingDict (dict ):
  10. "Helper class to implement partial formatting"
  11. def __missing__ (self ,key ):
  12. return MissingField (key )
  13.  
  14. class PartialFormatter (Formatter ):
  15. "Formatter class which allows missing keys in formatting"
  16. def format (self ,format_string ,*args ,**kwd ):
  17. return self .vformat (format_string ,args ,MissingDict (**kwd ))
  18. def format_field (self ,value ,format_string ):
  19. if isinstance (value ,MissingField ):
  20. s =":"+format_string if format_string else ""
  21. result ="{"+value .name +s +"}"
  22. else :
  23. result =Formatter .format_field (self ,value ,format_string )
  24. return result
  25.  
  26. def atest ():
  27. "Testing partial formatting"
  28. from math import sin
  29. template ="{x:<15.{precision}e}{y:<15.{precision}e}"
  30. print ("Initial template: "+template )
  31. pf =PartialFormatter ()
  32. ptemplate =pf .format (template ,precision =3 )
  33. print ("Partial template: "+ptemplate )
  34. print ("")
  35. for i in range (5 ):
  36. x =0.1 *i
  37. print (ptemplate .format (x =x ,y =sin (x )))
  38.  
  39. atest ()
  40. """ my output --->
  41. Initial template: {x:<15.{precision}e}{y:<15.{precision}e}
  42. Partial template: {x:<15.3e}{y:<15.3e}
  43.  
  44. 0.000e+00 0.000e+00
  45. 1.000e-01 9.983e-02
  46. 2.000e-01 1.987e-01
  47. 3.000e-01 2.955e-01
  48. 4.000e-01 3.894e-01
  49. """
Last edited by Gribouillis; Oct 24th, 2009 at 5:34 am.
 
0
Gribouillis Gribouillis is offline Offline | Oct 24th, 2009
Displaying tabular data
Here we use format to display tabular data. Consider reusing the Tabular class in your programs, as shown in the function 'test_func' below
  1. #!/usr/bin/env python
  2. from os import linesep as LS
  3.  
  4. class Tabular (object ):
  5. def __init__ (self ,columns ,gen_data ):
  6. """Create a Tabular object for formatting a table.
  7. @ columns is a sequence of triples (col_title, col_align, tpdata)
  8. - col_title is the string at the top of the column. It's width
  9. determines the column witdth
  10. - col align is "<" or "^" or ">"
  11. - tpdata is a template to format the column entries, with a single
  12. positional argument 0.
  13. @ gen_data is a generator of the table rows, which are tuples of
  14. values to be formatted.
  15. """
  16. self .gen_data =gen_data
  17. columns =list (columns )
  18. self .titles =[]
  19. self .templates =[]
  20. for col_title ,col_align ,tpdata in columns :
  21. tpcell ="{{0:{a}{w}.{w}}}".format (a =col_align ,w =len (col_title ))
  22. self .titles .append (col_title )
  23. self .templates .append ((tpcell ,tpdata ))
  24. self .width =sum (len (x )for x in self .titles )+len (self .titles )-1
  25. def delimit (self ,msg ):
  26. return "|"+msg +"|"
  27. def top (self ):
  28. return "-"*(self .width +2 )
  29. bottom =top
  30. def lines (self ):
  31. yield self .top ()
  32. yield self .delimit ("|".join (self .titles ))
  33. yield self .top ()
  34. for line_data in self .gen_data :
  35. line =[]
  36. for (tpcell ,tpdata ),data in zip (self .templates ,line_data ):
  37. s =tpcell .format (tpdata .format (data ))
  38. line .append (s )
  39. yield self .delimit ("|".join (line ))
  40. yield self .bottom ()
  41. def __format__ (self ,format_spec ):
  42. if format_spec :
  43. template ="{0:"+format_spec +"}"
  44. return LS .join (template .format (line )for line in self .lines ())
  45. else :
  46. return LS .join (self .lines ())
  47.  
  48. def test_func ():
  49. "Test the formatting of tables using Tabular"
  50. from math import sin
  51. dx =0.05
  52. table =Tabular (
  53. [("{0:^5}".format ("i"),"<"," {0}"),
  54. ("{0:^13}".format ("parameter"),"^","{0:.3e}"),
  55. ("{0:^20}".format ("value"),"^","{0:.3e}"),],# columns
  56. ((i ,i *dx ,sin (i *dx ))for i in range (5 ))# rows
  57. )
  58. # formatting and printing the table
  59. # Look how the table is centered in a field of 72 characters.
  60.  
  61. print "{ls}{title:^{width}}{ls}{tbl:^{width}}".format (
  62. tbl =table ,title ="Table of sines.",width =72 ,ls =LS )
  63. test_func ()
  64. """ my output --->
  65.  
  66. Table of sines.
  67. ------------------------------------------
  68. | i | parameter | value |
  69. ------------------------------------------
  70. | 0 | 0.000e+00 | 0.000e+00 |
  71. | 1 | 5.000e-02 | 4.998e-02 |
  72. | 2 | 1.000e-01 | 9.983e-02 |
  73. | 3 | 1.500e-01 | 1.494e-01 |
  74. | 4 | 2.000e-01 | 1.987e-01 |
  75. ------------------------------------------
  76. """
Last edited by Gribouillis; Oct 24th, 2009 at 10:57 pm.
 
0
Gribouillis Gribouillis is offline Offline | Oct 27th, 2009
Formatting with colors in a linux console
The following module combines formatting strings and ansi escape sequences to support printing with color in a linux console. After importing the module, type help(termstyle) for full documentation.
  1. #!/usr/bin/env python
  2. # termstyle.py 0.9 (linux only)
  3. """This module implements a system using ANSI escape codes
  4. to display colors in a terminal.
  5.  
  6. Example:
  7. from termstyle import Style, clear
  8. blue = Style("blue", "underline")
  9. clear()
  10. print( blue("Hello world"))
  11. print( "Velocity: {0:.3e} m/s" .format( blue(2.45589) ))
  12. """
  13. CSI = "\x1b["
  14. COLORS = "black red green yellow blue magenta cyan white".split()
  15. M_DICT = dict((w, str(30 + i))
  16. for (i, w) in enumerate(COLORS)) # foreground colors
  17. M_DICT.update(("-" + w, str(40 + i))
  18. for (i, w) in enumerate(COLORS)) # background colors
  19. EFFECTS = """
  20. reset bold faint italic underline slow fast negative conceal
  21. crossout normal underlineoff blinkoff positive reveal
  22. """ .strip().split()
  23. M_DICT.update((w, str(i)) for i, w in enumerate(EFFECTS))
  24.  
  25. __all__ = ["Style", "clear"]
  26.  
  27. class Style(object):
  28. """Style(*effects) --> a new Style object.
  29. @ effects is a sequence of
  30. -words like "red" (call Style.effects() to see all the words)
  31. -pairs (line, column) describing a terminal position
  32. -other Style objets
  33.  
  34. * If 'effects' contains a Style instance, other effects are ignored
  35. and a copy of the first instance met is built.
  36. * If effects contains position pairs, only the last pair is used.
  37. * Call Style.colors() to see all foreground colors.
  38. * A background color is passed by putting "-" at the beginning of
  39. the color name. For example "-white"
  40.  
  41. Effects can be disabled for all Styles, or for a Style instance
  42. by setting:
  43. Style.enable = False
  44. instance.enable = False
  45. """
  46. enable = True
  47.  
  48. @classmethod
  49. def effects(cls):
  50. "return an iterator over all possible named effects."
  51. return iter(M_DICT)
  52.  
  53. @classmethod
  54. def colors(cls):
  55. "return an iterator over all foreground colors."
  56. return iter(COLORS)
  57.  
  58. def __init__(self, *effects):
  59. "see class documentation"
  60. self.template = self.ansi_template(effects)
  61.  
  62. def ansi_template(self, effects):
  63. "builds an ANSI template string from the sequence of effects"
  64.  
  65. controls = []
  66. position = ""
  67. for a in effects:
  68. if isinstance(a, Style):
  69. return a.template
  70. elif isinstance(a, tuple):
  71. line, column = (str(int(x)) for x in a)
  72. position = ''.join((CSI, line, ";", column, "H"))
  73. else:
  74. controls.append(M_DICT[a])
  75. if controls:
  76. template = ''.join(
  77. (position, CSI, ';'.join(controls), "m", "{text}", CSI, "0m"))
  78. else:
  79. template = ''.join((position, "{text}"))
  80. if position:
  81. template = ''.join((CSI, "s", template, CSI, "u"))
  82. return template
  83.  
  84. def __call__(self, content):
  85. """Calling a Style instance creates a StyledContent instance
  86. which can be printed in a terminal.
  87. If self.enable is False, content is returned instead"""
  88. return StyledContent(self, content) if self.enable else content
  89.  
  90. class StyledContent(object):
  91. """StyleContent(style, content) --> a StyleContent instance.
  92. This is the type returned by Style.__call__.
  93. """
  94. def __init__(self, style, content):
  95. "See class documentation"
  96. self.content = content
  97. self.style = style
  98.  
  99. def __format__(self, format_spec):
  100. """Formatting a StyleContent instance is equivalent to
  101. formatting the content, with ANSI escape sequences added
  102. for terminal output"""
  103. return self.style.template.format(
  104. text = ("{0:" + format_spec + "}").format(self.content))
  105.  
  106. def __str__(self):
  107. """Calling str() on a StyleContent instance is equivalent to
  108. calling str() on the content, with ANSI escape sequences added
  109. for terminal output"""
  110. return self.style.template.format(text = self.content)
  111.  
  112. def clear():
  113. "clear the teminal"
  114. print(CSI + "2J")
  115.  
  116. if __name__ == "__main__":
  117. def test_code():
  118. "test function for module termstyle"
  119. from datetime import datetime
  120. from math import cos
  121.  
  122. green = Style("-white", "green", "underline")
  123. blue = Style("blue", "bold")
  124. yellow = Style("yellow")
  125. cyan = Style("cyan")
  126. middle = Style((10, 20))
  127.  
  128. clear()
  129. print( "The current time is {0:%H:%M:%S}.".format(blue(datetime.now())))
  130. print("")
  131. for i in range(5):
  132. x = 0.1 * i
  133. print("{0:12.3e}{1:12.3e}".format(yellow(x), cyan(cos(x))))
  134. print( middle("This is a {w} of terminal styles." .format(
  135. w = green("test"))))
  136.  
  137.  
  138. test_code()
  139. """ my output (without the colors) --->
  140.  
  141. This is a test of terminal styles.
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148. The current time is 16:18:01.
  149.  
  150. 0.000e+00 1.000e+00
  151. 1.000e-01 9.950e-01
  152. 2.000e-01 9.801e-01
  153. 3.000e-01 9.553e-01
  154. 4.000e-01 9.211e-01
  155. """
Last edited by Gribouillis; Oct 27th, 2009 at 12:37 pm.
 
 

Tags
format, string

Message:


Thread Tools Search this Thread



Tag cloud for format, string
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC