Package: kwbar
█ kwbar – Print Keywords as a Bar ChartEasily create a bar chart withkwbar; pass keyword arguments that can be converted to float.I made this for fun, but then I thought other people might actually find it useful.Featureskwbarseveral useful features:Plots bars showing the relative magnitide (absolute value) of kwargs.Prints the values of the passed keyword arguments in scientific notation.Pure Python and zero dependencies.Minimal implementation (<100 lines total) which can be audited in a few minutes.Prints the names of the passed keyword arguments.Plots any object that can be converted to float (SupportsFloat).Customizable width, the entire terminal width is used by default.Customizable significant figures, 3 by default.Shows value labels inside bars, making the output width predictable. If the bars are too small, the value labels appear outside of them.Handles inf and NaN values.Negative values are(ANSI) coloredred and can be customized.Respects theNO_COLORenvironment variable.Has an ASCII mode, enabled on import when stdout is not TTY.Warns on stderr (can be disabled) if the output will have to overrun the configured width. Overflow can generally be avoided by configutingoptionssuch asBEFORE=True.Fixed output width. This can be done by either:SettingBEFORE = True, orsettingTRUNCATEandWIDTHto satisfy:WIDTH-TRUNCATE-SF- 17 >= 0.Optionskwbarsupports the following options, which are set by modifying module variables:importkwbarkwbar.WIDTH=-1# Set the output width, -1 = use the terminal width.kwbar.SF=2# The number of sig figs to show.kwbar.SHOW_VAL=True# Show values inside the barskwbar.TRUNCATE=0.25# Truncate long keys (<=1 = % of WIDTH, >1 = columns).kwbar.BAR_CHARS=" ▏▎▍▌▋▊▉█"# Characters to use for the bars.kwbar.POS=""# ANSI escape code for positive values.kwbar.NEG="\x1b[31m"# ANSI escape code for negative values.kwbar.WARN=True# Show a warning if the output will overrun the configured width.kwbar.PAD=" "# Padding characters shown before finite and non-finite values.kwbar.BEFORE=False# Show the value labels before the bar instead of inside.Convenience FunctionsThere are also a couple of functions to set multiple options at once:ASCII ModeSetsBAR_CHARSandPADto ASCII characters. Also disables all ANSI escape codes and setsBEFOREtrue.importkwbarkwbar.WIDTH=50kwbar.ascii()kwbar.kwbar(one=1,two=2,three=3,four=4)one +1.00e+00 XXXXXXXX
  two +2.00e+00 XXXXXXXXXXXXXXXXX
three +3.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXX
 four +4.00e+00 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHotdog Modeimportkwbarkwbar.WIDTH=33kwbar.hotdog()kwbar.kwbar(one=1,two=2,three=3,four=4)one 🌭🌭🌭🌭🌭🌭¾
  two 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭½
three 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭¼
 four 🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭🌭How do I...?Reset All Optionsimportkwbarkwbar.ascii()# Reset to defaults.importimportlibimportlib.reload(kwbar)Use Keys That Are Not Valid Python Keywordsimportkwbarkwbar.ascii()kwbar.kwbar(**{"one":1,"-2":-2,"pi":3.14})one +1.00e+00 XXXXXX
 -2 -2.00e+00 XXXXXXXXXXXX
 pi +3.14e+00 XXXXXXXXXXXXXXXXXXXPrint Dogs Instead of Hotdogsimportkwbarkwbar.hotdog()kwbar.BAR_CHARS=kwbar.BAR_CHARS[:-1]+"🐶"# Replace the last character.kwbar.kwbar(one=1,two=2,pi=3.14)one 🐶🐶🐶🐶🐶🐶🐶🐶🐶¼
two 🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶½
 pi 🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶ThemesJust some ideas for how you could customize the output.Linesimportkwbarkwbar.hotdog()kwbar.BAR_CHARS="╸━"Blue Red Linesimportkwbarkwbar.hotdog()kwbar.BAR_CHARS="╸━"kwbar.POS="\x1b[34m"kwbar.NEG="\x1b[31m"Slicesimportkwbarkwbar.hotdog()kwbar.BAR_CHARS="◔◑◕●"Quater Tallyimportkwbarkwbar.hotdog()kwbar.BAR_CHARS=" ¼½¾1"Eighthskwbar.hotdog()kwbar.BAR_CHARS=" ⅛¼⅜½⅝¾⅞1"Hatchingkwbar.hotdog()kwbar.BAR_CHARS="🥚🐣🐥"FAQsThese are questions that I frequently asked myself while making this.Why did you make this?For fun!Why did you format the script to fill 80 characters on a line?Because I could and it made me happy.Why did you use module variables for configuration?Because it kept the implementation simple/minimal.
This also means that if you import kwbar in multiple places within a script,
it will have a consistent style and does not need to be configured multiple times.How do I have multiple kwbar copies with different configurations?The configuration for kwbar affects all calls tokwbar.kwbar, becuase it is a static
function using module variables for configuration.
If youreallywant to do this, you can, but it feels like a hideous hack:importsysimportimportlibSPEC_KWBAR=importlib.util.find_spec('kwbar')kwbar2=importlib.util.module_from_spec(SPEC_KWBAR)SPEC_KWBAR.loader.exec_module(kwbar2)sys.modules['kwbar2']=kwbar2Now you have another kwbar called kwbar2 with a completely seperate configuration.>>>kwbar.WIDTH=40>>>kwbar2.WIDTH=50>>>print(kwbar.WIDTH)40>>>print(kwbar2.WIDTH)50Why didn't you just make the first argument a dictionary and use kwargs for configuration?Becuase that was less fun that using only kwargs.