code: def interact(obj):
      tab = widgets.Tab()
      base_style = widgets.ButtonStyle()
      selected_style = widgets.ButtonStyle(
          button_color="#DDFFDD", font_weight="bold"
      )
  
      if isinstance(obj, hl.Table):
          glob = widgets.Button(
              description="globals",
              layout=widgets.Layout(width="150px", height="30px"),
          )
          rows = widgets.Button(
              description="rows",
              layout=widgets.Layout(width="150px", height="200px"),
          )
          rows.style = selected_style
  
          globals_frames = []
          globals_frames.append(
              widgets.HTML(
                  f"<p><big>Global fields, with one value in the dataset.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate_globals", "https://hail.is/docs/0.2/hail.Table.html#hail.Table.annotate_globals")}: '
                  f"add new global fields.</li>"
                  f"</ul>"
              )
          )
          append_struct_frames(obj.globals.dtype, globals_frames)
  
          row_frames = []
          row_frames.append(
              widgets.HTML(
                  f"<p><big>Row fields, with one record per row of the table.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate", "https://hail.is/docs/0.2/hail.Table.html#hail.Table.annotate")}: '
                  f"add new fields.</li>"
                  f'<li>{html_link("filter", "https://hail.is/docs/0.2/hail.Table.html#hail.Table.filter")}: '
                  f"filter rows of the table.</li>"
                  f'<li>{html_link("aggregate", "https://hail.is/docs/0.2/hail.Table.html#hail.Table.aggregate")}: '
                  f"aggregate over rows to produce a single value.</li>"
                  f"</ul>"
              )
          )
          if len(obj.key) > 0:
              row_frames.append(
                  widgets.HTML(f"<p><big>Key: {list(obj.key)}<big><p>")
              )
          append_struct_frames(obj.row.dtype, row_frames)
  
          tab.children = [
              widgets.VBox(frames)
              for frames in [globals_frames, row_frames]
          ]
          tab.set_title(0, "globals")
          tab.set_title(1, "row")
          tab.selected_index = 1
  
          box = widgets.VBox([glob, rows])
          buttons = [glob, rows]
      else:
          assert isinstance(obj, hl.MatrixTable)
          glob = widgets.Button(
              description="globals",
              layout=widgets.Layout(width="65px", height="30px"),
          )
          cols = widgets.Button(
              description="cols",
              layout=widgets.Layout(width="200px", height="30px"),
          )
          rows = widgets.Button(
              description="rows",
              layout=widgets.Layout(width="65px", height="200px"),
          )
          entries = widgets.Button(
              description="entries",
              layout=widgets.Layout(width="200px", height="200px"),
          )
          entries.style = selected_style
  
          globals_frames = []
          globals_frames.append(
              widgets.HTML(
                  f"<p><big>Global fields, with one value in the dataset.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate_globals()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.annotate_globals")}: '
                  f"add new global fields.</li>"
                  f"</ul>"
              )
          )
          append_struct_frames(obj.globals.dtype, globals_frames)
  
          row_frames = []
          row_frames.append(
              widgets.HTML(
                  f"<p><big>Row fields, with one record per row in the dataset.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate_rows()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.annotate_rows")}: '
                  f'add new row fields. This method supports {html_link("aggregation", "https://hail.is/docs/0.2/aggregators.html")}, '
                  f"aggregating over entries to compute one result per row, e.g. computing the mean depth per variant.</li>"
                  f'<li>{html_link("filter_rows()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.filter_rows")}: '
                  f"filter rows in the matrix table.</li>"
                  f'<li>{html_link("aggregate_rows()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.aggregate_rows")}: '
                  f"aggregate over rows (not including entries or columns) to produce a single value, e.g. counting the number of loss-of-function variants.</li>"
                  f'<li>{html_link("rows()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.rows")}: '
                  f'return the rows as a Hail {html_link("Table", "https://hail.is/docs/0.2/hail.Table.html")}.</li>'
                  f"</ul>"
              )
          )
          if len(obj.row_key) > 0:
              row_frames.append(
                  widgets.HTML(
                      f"<p><big>Row key: {list(obj.row_key)}<big><p>"
                  )
              )
          append_struct_frames(obj.row.dtype, row_frames)
  
          col_frames = []
          col_frames.append(
              widgets.HTML(
                  f"<p><big>Column fields, with one record per column in the dataset.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate_cols()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.annotate_cols")}: '
                  f'add new column fields. This method supports {html_link("aggregation", "https://hail.is/docs/0.2/aggregators.html")}, '
                  f"aggregating over entries to compute one result per column, e.g. computing the mean depth per sample.</li>"
                  f'<li>{html_link("filter_cols()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.filter_cols")}: '
                  f"filter columns in the matrix table.</li>"
                  f'<li>{html_link("aggregate_cols()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.aggregate_cols")}: '
                  f"aggregate over columns (not including entries or rows) to produce a single value, e.g. counting the number of samples with case status.</li>"
                  f'<li>{html_link("cols()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.cols")}: '
                  f'return the columns as a Hail {html_link("Table", "https://hail.is/docs/0.2/hail.Table.html")}.'
                  f"</li>"
                  f"</ul>"
              )
          )
          if len(obj.col_key) > 0:
              col_frames.append(
                  widgets.HTML(
                      f"<p><big>Column key: {list(obj.col_key)}<big><p>"
                  )
              )
          append_struct_frames(obj.col.dtype, col_frames)
  
          entry_frames = []
          entry_frames.append(
              widgets.HTML(
                  f"<p><big>Entry fields, with one record per (row, column) pair in the dataset.</big></p>\n"
                  f"<p>Commonly used methods:</p>\n"
                  f"<ul>"
                  f'<li>{html_link("annotate_entries()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.annotate_entries")}: '
                  f"add new entry fields.</li>"
                  f'<li>{html_link("filter_entries()", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.filter_entries")}: '
                  f"filter entries in the matrix table, removing them from downstream operations, like aggregations.</li>"
                  f'<li>{html_link("aggregate_entries", "https://hail.is/docs/0.2/hail.MatrixTable.html#hail.MatrixTable.aggregate_entries")}: '
                  f"aggregate over entries to produce a single value, e.g. computing mean depth across an entire dataset.</li>"
                  f"</ul>"
              )
          )
          append_struct_frames(obj.entry.dtype, entry_frames)
  
          tab.children = [
              widgets.VBox(frames)
              for frames in [
                  globals_frames,
                  row_frames,
                  col_frames,
                  entry_frames,
              ]
          ]
          tab.set_title(0, "globals")
          tab.set_title(1, "row")
          tab.set_title(2, "col")
          tab.set_title(3, "entry")
          tab.selected_index = 3
  
          box = widgets.VBox(
              [
                  widgets.HBox([glob, cols]),
                  widgets.HBox([rows, entries]),
              ]
          )
          buttons = [glob, rows, cols, entries]
  
      selection_handler = widgets.IntText(tab.selected_index)
      button_idx = dict(zip(buttons, range(len(buttons))))
  
      def handle_selection(x):
          if x["name"] == "value" and x["type"] == "change":
              buttons[x["old"]].style = base_style
              selection = x["new"]
              buttons[selection].style = selected_style
              tab.selected_index = selection
  
      selection_handler.observe(handle_selection)
      widgets.jslink(
          (tab, "selected_index"), (selection_handler, "value")
      )
  
      def button_action(b):
          selection_handler.value = button_idx[b]
  
      for button in button_idx:
          button.on_click(button_action)
  
      display(box, tab)
  
file_path: hail/hail/python/hail/experimental/interact.py
imports: from IPython.display import display
  from ipywidgets import widgets
  import hail
  from hail.expr.types import summary_type
label_desc: Use image node_id 1 for calling a global function with example usage: interact(obj) without return types