@@ -543,85 +543,77 @@ def wrapped_f(*wargs):
543543
544544 return wrap
545545
546-
547546def bill_of_materials (csv = False ):
548- res = ''
549- res += "%8s\t %8s\t %8s\t %8s" % ("Desc." , "Count" , "Unit Price" , "Total Price" )
550- for x in g_bom_headers :
551- res += '\t ' + x
552- res += '\n '
553-
547+ field_names = ["Description" , "Count" , "Unit Price" , "Total Price" ]
548+ field_names += g_bom_headers
549+
550+ rows = []
551+
554552 all_costs = {}
555553 for desc , elements in g_parts_dict .items ():
556554 count = elements ['Count' ]
557555 currency = elements ['currency' ]
558- if not csv :
559- currency += ' '
560556 price = elements ['Unit Price' ]
561557
562558 if count > 0 :
563559 if price :
564560 total = price * count
565- try :
566- all_costs [currency ] += total
567- except :
568- all_costs [currency ] = total
569-
570- res += ("%8s\t %8d\t %s%8f\t %s%8.2f"
571- % (desc , count , currency , price , currency , total ))
561+ if currency not in all_costs :
562+ all_costs [currency ] = 0
563+
564+ all_costs [currency ] += total
565+ unit_price = _currency_str (price , currency )
566+ total_price = _currency_str (total , currency )
572567 else :
573- res += "%8s\t %8d\t \t " % (desc , count )
568+ unit_price = total_price = ""
569+ row = [desc , count , unit_price , total_price ]
574570
575571 for key in g_bom_headers :
576572 value = elements [key ]
577- # String formatting just converts everything via str() anyways.
578- res += "\t %s" % value
579-
580- res += '\n '
573+ row .append (value )
574+ rows .append (row )
581575
576+ # Add total costs if we have values to add
582577 if len (all_costs ) > 0 :
583- if not csv :
584- res += "_" * 60 + '\n '
585- else :
586- res += '\n '
578+ empty_row = ["" ] * len (field_names )
579+ rows .append (empty_row )
580+ for currency , cost in all_costs .items ():
581+ row = empty_row [:]
582+ row [0 ] = "Total Cost, {currency:>4}" .format (** vars ())
583+ row [3 ] = "{currency:>4} {cost:.2f}" .format (** vars ())
584+
585+ rows .append (row )
587586
588- res += "Total Cost: \n "
587+ res = _table_string ( field_names , rows , csv )
589588
590- for currency in all_costs .keys ():
591- if not csv :
592- res += "\t \t %s %.2f\n " % (currency , all_costs [currency ])
593- else :
594- res += "%s\t %.2f\n " % (currency , all_costs [currency ])
595-
596- res += '\n '
597589 return res
598590
599-
600- # FIXME: finish this.
601- def bill_of_materials_justified ():
602- res = ''
603- columns = [ s . rjust ( 8 )
604- for s in ( "Desc." , "Count" , "Unit Price" , "Total Price" )]
605- all_costs = {}
606- for desc , ( count , currency , price ) in g_parts_dict . items () :
607- if count > 0 :
608- if price :
609- total = price * count
610- try :
611- all_costs [ currency ] += total
612- except :
613- all_costs [ currency ] = total
614-
615- res += "%(desc)s %(count)s %(currency)s %(price)s %(currency)s %(total)s \n " % vars ()
616- else :
617- res += "%(desc)s %(count)s " % vars ()
618- if all_costs > 0 :
619- res + = "_" * 60 + ' \n '
620- res += "Total Cost: \n "
621- for currency in all_costs . keys ():
622- res + = "\t \t %s %.2f \n " % ( currency , all_costs [ currency ])
623- res += " \n "
624- return res
591+ def _currency_str ( value , currency = "$" ):
592+ return "{currency:>4} {value:.2f}" . format ( ** vars ())
593+
594+ def _table_string ( field_names , rows , csv = False ):
595+ # Output a justified table string using the prettytable module.
596+ # Fall back to Excel-ready tab-separated values if prettytable's not found
597+ # or CSV is requested
598+ if not csv :
599+ try :
600+ import prettytable
601+ table = prettytable . PrettyTable ( field_names = field_names )
602+ for row in rows :
603+ table . add_row ( row )
604+ res = table . get_string ()
605+ except ImportError as e :
606+ print ( "Unable to import prettytable module. Outputting in TSV format" )
607+ csv = True
608+ if csv :
609+ lines = [ " \t " . join ( field_names )]
610+ for row in rows :
611+ line = "\t " . join ([ str ( f ) for f in row ])
612+ lines . append ( line )
613+
614+ res = "\n " . join ( lines )
615+
616+ return res + " \n "
625617
626618# ================
627619# = Bounding Box =
0 commit comments