code: def test_info_memory_usage():
      # Ensure memory usage is displayed, when asserted, on the last line
      dtypes = [
          "int64",
          "float64",
          "datetime64[ns]",
          "timedelta64[ns]",
          "complex128",
          "object",
          "bool",
      ]
      data = {}
      n = 10
      for i, dtype in enumerate(dtypes):
          data[i] = (
              np.random.default_rng(2).integers(2, size=n).astype(dtype)
          )
      df = DataFrame(data)
      buf = StringIO()
  
      # display memory usage case
      df.info(buf=buf, memory_usage=True)
      res = buf.getvalue().splitlines()
      assert "memory usage: " in res[-1]
  
      # do not display memory usage case
      df.info(buf=buf, memory_usage=False)
      res = buf.getvalue().splitlines()
      assert "memory usage: " not in res[-1]
  
      df.info(buf=buf, memory_usage=True)
      res = buf.getvalue().splitlines()
  
      # memory usage is a lower bound, so print it as XYZ+ MB
      assert re.match(r"memory usage: [^+]+\+", res[-1])
  
      df.iloc[:, :5].info(buf=buf, memory_usage=True)
      res = buf.getvalue().splitlines()
  
      # excluded column with object dtype, so estimate is accurate
      assert not re.match(r"memory usage: [^+]+\+", res[-1])
  
      # Test a DataFrame with duplicate columns
      dtypes = ["int64", "int64", "int64", "float64"]
      data = {}
      n = 100
      for i, dtype in enumerate(dtypes):
          data[i] = (
              np.random.default_rng(2).integers(2, size=n).astype(dtype)
          )
      df = DataFrame(data)
      df.columns = dtypes
  
      df_with_object_index = DataFrame({"a": [1]}, index=["foo"])
      df_with_object_index.info(buf=buf, memory_usage=True)
      res = buf.getvalue().splitlines()
      assert re.match(r"memory usage: [^+]+\+", res[-1])
  
      df_with_object_index.info(buf=buf, memory_usage="deep")
      res = buf.getvalue().splitlines()
      assert re.match(r"memory usage: [^+]+$", res[-1])
  
      # Ensure df size is as expected
      # (cols * rows * bytes) + index size
      df_size = df.memory_usage().sum()
      exp_size = len(dtypes) * n * 8 + df.index.nbytes
      assert df_size == exp_size
  
      # Ensure number of cols in memory_usage is the same as df
      size_df = np.size(df.columns.values) + 1  # index=True; default
      assert size_df == np.size(df.memory_usage())
  
      # assert deep works only on object
      assert df.memory_usage().sum() == df.memory_usage(deep=True).sum()
  
      # test for validity
      DataFrame(1, index=["a"], columns=["A"]).memory_usage(index=True)
      DataFrame(1, index=["a"], columns=["A"]).index.nbytes
      df = DataFrame(
          data=1,
          index=MultiIndex.from_product([["a"], range(1000)]),
          columns=["A"],
      )
      df.index.nbytes
      df.memory_usage(index=True)
      df.index.values.nbytes
  
      mem = df.memory_usage(deep=True).sum()
      assert mem > 0
  
imports: from io import StringIO
  import re
  from string import ascii_uppercase
  import sys
  import textwrap
  import numpy
  import pytest
  from pandas.compat import IS64, PYPY
  from pandas import CategoricalIndex, DataFrame, MultiIndex, Series, date_range, option_context
  import pandas._testing
label_desc: Use image node_id 14 for calling a global function with example usage: test_info_memory_usage() without return types