%22%22%22Bottleneck%20explorer.%0A%0AFor%20a%20chosen%20factory%20%2B%20metric%3A%0A-%20Show%20histogram%20of%20that%20metric%20across%20all%201000%20pieces%0A-%20Click%20low-bucket%20pieces%20to%20see%20what%20makes%20them%20score%20badly%0A-%20Click%20high-bucket%20pieces%20to%20see%20what%20makes%20them%20score%20well%0A-%20Surface%20the%20pattern%20that%20drives%20the%20bottleneck%0A%0AThis%20is%20%22why%20is%20entropy%200.076%20for%20lsystem%3F%22%20answered%20visually.%0A%22%22%22%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.22.5%22%0Aapp%20%3D%20marimo.App(width%3D%22full%22%2C%20app_title%3D%22Bottleneck%20Explorer%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20sys%0A%20%20%20%20from%20pathlib%20import%20Path%0A%20%20%20%20sys.path.insert(0%2C%20str(Path(__file__).parent))%0A%20%20%20%20import%20_lib%20as%20lib%0A%0A%20%20%20%20return%20lib%2C%20mo%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Bottleneck%20Explorer%0A%0A%20%20%20%20Pick%20a%20factory%20%2B%20metric%2C%20see%20the%20distribution%2C%20and%20click%20low%2Fhigh%20buckets%20to%20find%20patterns.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(lib%2C%20mo)%3A%0A%20%20%20%20factory%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3Dlib.FACTORIES%2C%0A%20%20%20%20%20%20%20%20value%3D%22lsystem%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Factory%22%2C%0A%20%20%20%20)%0A%20%20%20%20metric%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%5B%22entropy%22%2C%20%22ink_coverage%22%2C%20%22uniqueness%22%2C%20%22composition%22%2C%20%22feasibility%22%2C%20%22line_complexity%22%5D%2C%0A%20%20%20%20%20%20%20%20value%3D%22entropy%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Metric%20to%20investigate%22%2C%0A%20%20%20%20)%0A%20%20%20%20n_buckets%20%3D%20mo.ui.slider(5%2C%2020%2C%20value%3D10%2C%20label%3D%22Histogram%20buckets%22%2C%20show_value%3DTrue)%0A%20%20%20%20mo.hstack(%5Bfactory%2C%20metric%2C%20n_buckets%5D%2C%20gap%3D2%2C%20justify%3D%22start%22)%0A%20%20%20%20return%20factory%2C%20metric%2C%20n_buckets%0A%0A%0A%40app.cell%0Adef%20_(factory%2C%20lib%2C%20metric)%3A%0A%20%20%20%20rows%20%3D%20lib.load_experiments(factory.value)%0A%20%20%20%20values%20%3D%20%5B(r%5B%22id%22%5D%2C%20float(r%5Bmetric.value%5D)%2C%20float(r%5B%22composite_score%22%5D))%20for%20r%20in%20rows%5D%0A%20%20%20%20return%20(values%2C)%0A%0A%0A%40app.cell%0Adef%20_(factory%2C%20metric%2C%20mo%2C%20n_buckets%2C%20values)%3A%0A%20%20%20%20buckets%20%3D%20%5B%5D%0A%20%20%20%20if%20not%20values%3A%0A%20%20%20%20%20%20%20%20hist_view%20%3D%20mo.md(%22_No%20data._%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20vmin%20%3D%20min(v%5B1%5D%20for%20v%20in%20values)%0A%20%20%20%20%20%20%20%20vmax%20%3D%20max(v%5B1%5D%20for%20v%20in%20values)%0A%20%20%20%20%20%20%20%20rng%20%3D%20max(vmax%20-%20vmin%2C%200.001)%0A%20%20%20%20%20%20%20%20bucket_w%20%3D%20rng%20%2F%20n_buckets.value%0A%20%20%20%20%20%20%20%20%23%20Bin%0A%20%20%20%20%20%20%20%20buckets%5B%3A%5D%20%3D%20%5B%5B%5D%20for%20_%20in%20range(n_buckets.value)%5D%0A%20%20%20%20%20%20%20%20for%20piece_id%2C%20val%2C%20comp%20in%20values%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20idx%20%3D%20min(int((val%20-%20vmin)%20%2F%20bucket_w)%2C%20n_buckets.value%20-%201)%0A%20%20%20%20%20%20%20%20%20%20%20%20buckets%5Bidx%5D.append((piece_id%2C%20val%2C%20comp))%0A%0A%20%20%20%20%20%20%20%20max_count%20%3D%20max(len(b)%20for%20b%20in%20buckets)%0A%20%20%20%20%20%20%20%20bar_h%20%3D%20200%0A%0A%20%20%20%20%20%20%20%20%23%20SVG%20histogram%0A%20%20%20%20%20%20%20%20svg_w%20%3D%20800%0A%20%20%20%20%20%20%20%20bar_w%20%3D%20svg_w%20%2F%2F%20n_buckets.value%20-%204%0A%20%20%20%20%20%20%20%20svg_parts%20%3D%20%5Bf'%3Csvg%20viewBox%3D%220%200%20%7Bsvg_w%7D%20%7Bbar_h%20%2B%2060%7D%22%20style%3D%22width%3A100%25%3B%20max-height%3A300px%3B%22%3E'%5D%0A%20%20%20%20%20%20%20%20for%20hist_i%2C%20hist_bucket%20in%20enumerate(buckets)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20count%20%3D%20len(hist_bucket)%0A%20%20%20%20%20%20%20%20%20%20%20%20h%20%3D%20int(count%20%2F%20max_count%20*%20bar_h)%20if%20max_count%20else%200%0A%20%20%20%20%20%20%20%20%20%20%20%20x%20%3D%20hist_i%20*%20(bar_w%20%2B%204)%20%2B%2020%0A%20%20%20%20%20%20%20%20%20%20%20%20y%20%3D%20bar_h%20-%20h%20%2B%2010%0A%20%20%20%20%20%20%20%20%20%20%20%20avg_comp%20%3D%20sum(b%5B2%5D%20for%20b%20in%20hist_bucket)%20%2F%20count%20if%20count%20else%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Color%20by%20avg%20composite%20of%20bucket%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20avg_comp%20%3E%3D%2075%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20%22%234ade80%22%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20avg_comp%20%3E%3D%2065%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20%22%2322d3ee%22%0A%20%20%20%20%20%20%20%20%20%20%20%20elif%20avg_comp%20%3E%3D%2055%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20%22%23fbbf24%22%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20color%20%3D%20%22%23f87171%22%0A%20%20%20%20%20%20%20%20%20%20%20%20svg_parts.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Crect%20x%3D%22%7Bx%7D%22%20y%3D%22%7By%7D%22%20width%3D%22%7Bbar_w%7D%22%20height%3D%22%7Bh%7D%22%20fill%3D%22%7Bcolor%7D%22%20rx%3D%222%22%2F%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7Bx%20%2B%20bar_w%20%2F%202%7D%22%20y%3D%22%7By%20-%204%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%23fff%22%20font-size%3D%2211%22%20font-family%3D%22monospace%22%3E%7Bcount%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ctext%20x%3D%22%7Bx%20%2B%20bar_w%20%2F%202%7D%22%20y%3D%22%7Bbar_h%20%2B%2025%7D%22%20text-anchor%3D%22middle%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'fill%3D%22%23666%22%20font-size%3D%2210%22%20font-family%3D%22monospace%22%3E%7Bvmin%20%2B%20bucket_w%20*%20hist_i%3A.2f%7D%3C%2Ftext%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20svg_parts.append('%3C%2Fsvg%3E')%0A%20%20%20%20%20%20%20%20svg_html%20%3D%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22background%3A%230f0f0f%3B%20padding%3A24px%3B%20border-radius%3A8px%3B%20border%3A1px%20solid%20%23333%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Ch3%20style%3D%22margin%3A0%200%2012px%3B%20color%3A%23fff%3B%20font-family%3Asystem-ui%2Csans-serif%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bfactory.value%7D%20%C2%B7%20%7Bmetric.value%7D%20distribution%3C%2Fh3%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cp%20style%3D%22margin%3A0%200%2016px%3B%20color%3A%23888%3B%20font-size%3A13px%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'Bar%20height%20%3D%20piece%20count.%20Color%20%3D%20avg%20composite%20score%20of%20bucket.%3C%2Fp%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%2B%20''.join(svg_parts)%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cp%20style%3D%22margin%3A16px%200%200%3B%20color%3A%23666%3B%20font-size%3A11px%3B%20font-family%3Amonospace%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'range%20%7Bvmin%3A.3f%7D%20%E2%86%92%20%7Bvmax%3A.3f%7D%20%C2%B7%20%7Blen(values)%7D%20pieces%20total%3C%2Fp%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20f'%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20hist_view%20%3D%20mo.Html(svg_html)%0A%20%20%20%20hist_view%0A%20%20%20%20return%20(buckets%2C)%0A%0A%0A%40app.cell%0Adef%20_(metric%2C%20mo%2C%20n_buckets)%3A%0A%20%20%20%20bucket_picker%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%5Bf%22bucket%20%7Bi%20%2B%201%7D%22%20for%20i%20in%20range(n_buckets.value)%5D%2C%0A%20%20%20%20%20%20%20%20value%3D%22bucket%201%22%2C%0A%20%20%20%20%20%20%20%20label%3Df%22Inspect%20%7Bmetric.value%7D%20bucket%22%2C%0A%20%20%20%20)%0A%20%20%20%20bucket_picker%0A%20%20%20%20return%20(bucket_picker%2C)%0A%0A%0A%40app.cell%0Adef%20_(bucket_picker%2C%20buckets%2C%20lib%2C%20mo)%3A%0A%20%20%20%20bucket_idx%20%3D%20int(bucket_picker.value.split(%22%20%22)%5B1%5D)%20-%201%0A%20%20%20%20if%20bucket_idx%20%3E%3D%20len(buckets)%3A%0A%20%20%20%20%20%20%20%20inspect_view%20%3D%20mo.md(%22_Invalid%20bucket._%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20bucket%20%3D%20buckets%5Bbucket_idx%5D%0A%20%20%20%20%20%20%20%20if%20not%20bucket%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20inspect_view%20%3D%20mo.md(f%22_Bucket%20%7Bbucket_idx%20%2B%201%7D%20is%20empty._%22)%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Sort%20by%20composite%20score%2C%20show%20top%2012%0A%20%20%20%20%20%20%20%20%20%20%20%20bucket_sorted%20%3D%20sorted(bucket%2C%20key%3Dlambda%20b%3A%20-b%5B2%5D)%5B%3A12%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20inspect_cards%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22text-align%3Acenter%3B%20padding%3A4px%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cimg%20src%3D%22%7Blib.png_data_uri(lib.piece_path(b%5B0%5D%2C%20%22png%22))%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'style%3D%22width%3A140px%3B%20border%3A1px%20solid%20%23444%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22font-size%3A11px%3B%20font-family%3Amonospace%3B%20color%3A%23aaa%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bb%5B0%5D%7D%3Cbr%3Eval%3D%7Bb%5B1%5D%3A.3f%7D%3Cbr%3Ecomp%3D%7Bb%5B2%5D%3A.1f%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3C%2Fdiv%3E%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20b%20in%20bucket_sorted%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20lib.piece_path(b%5B0%5D%2C%20%22png%22).exists()%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20inspect_view%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.md(f%22%23%23%23%20Bucket%20%7Bbucket_idx%20%2B%201%7D%3A%20%7Blen(bucket)%7D%20pieces%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(inspect_cards%2C%20wrap%3DTrue%2C%20gap%3D1%2C%20justify%3D%22start%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20inspect_view%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(factory%2C%20lib%2C%20metric%2C%20mo%2C%20values)%3A%0A%20%20%20%20%23%20Compare%20best%20vs%20worst%20by%20metric%20to%20find%20pattern%0A%20%20%20%20if%20not%20values%3A%0A%20%20%20%20%20%20%20%20compare_view%20%3D%20mo.md(%22%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20sorted_vals%20%3D%20sorted(values%2C%20key%3Dlambda%20v%3A%20v%5B1%5D)%0A%20%20%20%20%20%20%20%20worst_5%20%3D%20sorted_vals%5B%3A5%5D%0A%20%20%20%20%20%20%20%20best_5%20%3D%20sorted_vals%5B-5%3A%5D%5B%3A%3A-1%5D%0A%0A%20%20%20%20%20%20%20%20worst_cards%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22text-align%3Acenter%3B%20padding%3A4px%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cimg%20src%3D%22%7Blib.png_data_uri(lib.piece_path(w%5B0%5D%2C%20%22png%22))%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'style%3D%22width%3A140px%3B%20border%3A2px%20solid%20%23f87171%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22font-size%3A10px%3B%20font-family%3Amonospace%3B%20color%3A%23aaa%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bw%5B0%5D%7D%3Cbr%3E%7Bmetric.value%7D%3D%7Bw%5B1%5D%3A.3f%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3C%2Fdiv%3E%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20w%20in%20worst_5%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lib.piece_path(w%5B0%5D%2C%20%22png%22).exists()%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20best_cards%20%3D%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.Html(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22text-align%3Acenter%3B%20padding%3A4px%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cimg%20src%3D%22%7Blib.png_data_uri(lib.piece_path(bp%5B0%5D%2C%20%22png%22))%7D%22%20'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'style%3D%22width%3A140px%3B%20border%3A2px%20solid%20%234ade80%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3Cdiv%20style%3D%22font-size%3A10px%3B%20font-family%3Amonospace%3B%20color%3A%23aaa%3B%22%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%7Bbp%5B0%5D%7D%3Cbr%3E%7Bmetric.value%7D%3D%7Bbp%5B1%5D%3A.3f%7D'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20f'%3C%2Fdiv%3E%3C%2Fdiv%3E'%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20bp%20in%20best_5%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20lib.piece_path(bp%5B0%5D%2C%20%22png%22).exists()%0A%20%20%20%20%20%20%20%20%5D%0A%0A%20%20%20%20%20%20%20%20compare_view%20%3D%20mo.vstack(%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(f%22%23%23%23%20Worst%205%20(%7Bfactory.value%7D%20by%20%7Bmetric.value%7D)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(worst_cards%2C%20gap%3D1%2C%20justify%3D%22start%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(f%22%23%23%23%20Best%205%20(%7Bfactory.value%7D%20by%20%7Bmetric.value%7D)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.hstack(best_cards%2C%20gap%3D1%2C%20justify%3D%22start%22)%2C%0A%20%20%20%20%20%20%20%20%5D)%0A%20%20%20%20compare_view%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
2fa77e4c8cdc874cc5e83d2091f63c83