code: def fill_direction(df: pd.DataFrame, **kwargs: Any) -> pd.DataFrame:
      """Provide a method-chainable function for filling missing values
      in selected columns.
  
      It is a wrapper for `pd.Series.ffill` and `pd.Series.bfill`,
      and pairs the column name with one of `up`, `down`, `updown`,
      and `downup`.
  
      !!!note
  
          This function will be deprecated in a 1.x release.
          Please use `pd.DataFrame.assign` instead.
  
      Examples:
          >>> import pandas as pd
          >>> import janitor as jn
          >>> df = pd.DataFrame(
          ...    {
          ...        'col1': [1, 2, 3, 4],
          ...        'col2': [None, 5, 6, 7],
          ...        'col3': [8, 9, 10, None],
          ...        'col4': [None, None, 11, None],
          ...        'col5': [None, 12, 13, None]
          ...    }
          ... )
          >>> df
             col1  col2  col3  col4  col5
          0     1   NaN   8.0   NaN   NaN
          1     2   5.0   9.0   NaN  12.0
          2     3   6.0  10.0  11.0  13.0
          3     4   7.0   NaN   NaN   NaN
          >>> df.fill_direction(
          ... col2 = 'up',
          ... col3 = 'down',
          ... col4 = 'downup',
          ... col5 = 'updown'
          ... )
             col1  col2  col3  col4  col5
          0     1   5.0   8.0  11.0  12.0
          1     2   5.0   9.0  11.0  12.0
          2     3   6.0  10.0  11.0  13.0
          3     4   7.0  10.0  11.0  13.0
  
      Args:
          df: A pandas DataFrame.
          **kwargs: Key - value pairs of columns and directions.
              Directions can be either `down`, `up`, `updown`
              (fill up then down) and `downup` (fill down then up).
  
      Raises:
          ValueError: If direction supplied is not one of `down`, `up`,
              `updown`, or `downup`.
  
      Returns:
          A pandas DataFrame with modified column(s).
      """  # noqa: E501
  
      if not kwargs:
          return df
  
      fill_types = {fill.name for fill in _FILLTYPE}
      for column_name, fill_type in kwargs.items():
          check("column_name", column_name, [str])
          check("fill_type", fill_type, [str])
          if fill_type.upper() not in fill_types:
              raise ValueError(
                  "fill_type should be one of up, down, updown, or downup."
              )
  
      check_column(df, kwargs)
  
      new_values = {}
      for column_name, fill_type in kwargs.items():
          direction = _FILLTYPE[f"{fill_type.upper()}"].value
          if len(direction) == 1:
              direction = methodcaller(direction[0])
              output = direction(df[column_name])
          else:
              direction = [methodcaller(entry) for entry in direction]
              output = _chain_func(df[column_name], *direction)
          new_values[column_name] = output
  
      return df.assign(**new_values)
  
file_path: pyjanitor/janitor/functions/fill.py
imports: from collections.abc import Iterable
  from enum import Enum
  from operator import methodcaller
  from typing import Any, Hashable, Iterable, Union
  import pandas
  import pandas_flavor
  from multipledispatch import dispatch
  from janitor.utils import check, check_column, deprecated_alias, refactored_function
label_desc: Use image node_id 1 for calling a global function with example usage: fill_direction(df) and returns: df, df