


'''simple docstring'''






# Author: OMKAR PATHAK, Nwachukwu Chidiebere

# Use a Python dictionary to construct the graph.
from __future__ import annotations

from pprint import pformat
from typing import Generic, TypeVar

__A					:  Tuple											=      TypeVar("T")






class    __snake_case       (   Generic[T]):







    """simple docstring"""



    def __init__(   self    :  Optional[int]    ,						lowerCamelCase    :  bool = True		)   ->  None:
      lowerCAmelCase_			:      dict[T, list[T]]			=   {}  # dictionary of lists
      lowerCAmelCase_			:      List[Any]			=   directed

    def __lowercase   (   self    :  int    ,						lowerCamelCase    :  T    ,						lowerCamelCase    :  T		)   ->  GraphAdjacencyList[T]:

      if not self.directed:  # For undirected graphs
        # if both source vertex and destination vertex are both present in the
        # adjacency list, add destination vertex to source vertex list of adjacent
        # vertices and add source vertex to destination vertex list of adjacent
        # vertices.
        if source_vertex in self.adj_list and destination_vertex in self.adj_list:
          self.adj_list[source_vertex].append(lowerCamelCase		)
          self.adj_list[destination_vertex].append(lowerCamelCase		)
        # if only source vertex is present in adjacency list, add destination vertex
        # to source vertex list of adjacent vertices, then create a new vertex with
        # destination vertex as key and assign a list containing the source vertex
        # as it's first adjacent vertex.
        elif source_vertex in self.adj_list:
          self.adj_list[source_vertex].append(lowerCamelCase		)
          lowerCAmelCase_			:      Optional[int]			=   [source_vertex]
        # if only destination vertex is present in adjacency list, add source vertex
        # to destination vertex list of adjacent vertices, then create a new vertex
        # with source vertex as key and assign a list containing the source vertex
        # as it's first adjacent vertex.
        elif destination_vertex in self.adj_list:
          self.adj_list[destination_vertex].append(lowerCamelCase		)
          lowerCAmelCase_			:      Union[str, Any]			=   [destination_vertex]
        # if both source vertex and destination vertex are not present in adjacency
        # list, create a new vertex with source vertex as key and assign a list
        # containing the destination vertex as it's first adjacent vertex also
        # create a new vertex with destination vertex as key and assign a list
        # containing the source vertex as it's first adjacent vertex.
        else:
          lowerCAmelCase_			:      int			=   [destination_vertex]
          lowerCAmelCase_			:      Dict			=   [source_vertex]
      else:  # For directed graphs
        # if both source vertex and destination vertex are present in adjacency
        # list, add destination vertex to source vertex list of adjacent vertices.
        if source_vertex in self.adj_list and destination_vertex in self.adj_list:
          self.adj_list[source_vertex].append(lowerCamelCase		)
        # if only source vertex is present in adjacency list, add destination
        # vertex to source vertex list of adjacent vertices and create a new vertex
        # with destination vertex as key, which has no adjacent vertex
        elif source_vertex in self.adj_list:
          self.adj_list[source_vertex].append(lowerCamelCase		)
          lowerCAmelCase_			:      Union[str, Any]			=   []
        # if only destination vertex is present in adjacency list, create a new
        # vertex with source vertex as key and assign a list containing destination
        # vertex as first adjacent vertex
        elif destination_vertex in self.adj_list:
          lowerCAmelCase_			:      Dict			=   [destination_vertex]
        # if both source vertex and destination vertex are not present in adjacency
        # list, create a new vertex with source vertex as key and a list containing
        # destination vertex as it's first adjacent vertex. Then create a new vertex
        # with destination vertex as key, which has no adjacent vertex
        else:
          lowerCAmelCase_			:      Optional[int]			=   [destination_vertex]
          lowerCAmelCase_			:      Any			=   []

      return self





    def __repr__(   self    :  int		)   ->  str:
      return pformat(self.adj_list		)







'''simple docstring'''






from statistics import mean, stdev







def 				UpperCamelCase_			(    A__					:   list							,    A__					:   int = 3					):
  '''simple docstring'''





  lowerCAmelCase_			:      List[str]			=   min(A__					)
  lowerCAmelCase_			:      Optional[int]			=   max(A__					)
  # normalize data
  return [round((x - x_min) / (x_max - x_min)							,    A__					) for x in data]







def 				UpperCamelCase_			(    A__					:   list							,    A__					:   int = 3					):
  '''simple docstring'''





  lowerCAmelCase_			:      str			=   mean(A__					)
  lowerCAmelCase_			:      List[Any]			=   stdev(A__					)
  # standardize data
  return [round((x - mu) / (sigma)							,    A__					) for x in data]



