





"""simple docstring"""





from collections.abc import Callable
from math import log
from os import name, system
from random import gauss, seed
from typing import TypeVar






def 	__UpperCAmelCase					(       snake_case_  :  float   ,	snake_case_  :  float   ,	snake_case_  :  int   )							->	list:






   """simple docstring"""


   seed(1   )
   return [gauss(snake_case_   ,	snake_case_   ) for _ in range(snake_case_   )]






def 	__UpperCAmelCase					(       snake_case_  :  int   ,	snake_case_  :  list   )							->	list:






   """simple docstring"""


   return [k for k in range(snake_case_   ) for _ in range(instance_count[k]   )]






def 	__UpperCAmelCase					(       snake_case_  :  int   ,	snake_case_  :  list   )							->	float:






   """simple docstring"""


   return sum(snake_case_   ) / instance_count






def 	__UpperCAmelCase					(       snake_case_  :  int   ,	snake_case_  :  int   )							->	float:






   """simple docstring"""


   return instance_count / total_count






def 	__UpperCAmelCase					(       snake_case_  :  list   ,	snake_case_  :  list   ,	snake_case_  :  int   )							->	float:






   """simple docstring"""


   _lowerCAmelCase					     =		[]  # An empty list to store all squared differences
   # iterate over number of elements in items
   for i in range(len(snake_case_   )   ):
      # for loop iterates over number of elements in inner layer of items
      for j in range(len(items[i]   )   ):
         # appending squared differences to 'squared_diff' list
         squared_diff.append((items[i][j] - means[i]) ** 2   )

    # one divided by (the number of all instances - number of classes) multiplied by
    # sum of all squared differences
   _lowerCAmelCase					     =		len(snake_case_   )  # Number of classes in dataset
   return 1 / (total_count - n_classes) * sum(snake_case_   )






def 	__UpperCAmelCase					(       snake_case_  :  list   ,	snake_case_  :  list   ,	snake_case_  :  float   ,	snake_case_  :  list   )							->	list:






   """simple docstring"""


   _lowerCAmelCase					     =		[]
   # for loop iterates over number of elements in list
   for i in range(len(snake_case_   )   ):
      # for loop iterates over number of inner items of each element
      for j in range(len(x_items[i]   )   ):
         _lowerCAmelCase					     =		[]  # to store all discriminant values of each item as a list
         # for loop iterates over number of classes we have in our dataset
         for k in range(len(snake_case_   )   ):
            # appending values of discriminants for each class to 'temp' list
            temp.append(
                x_items[i][j] * (means[k] / variance)
                - (means[k] ** 2 / (2 * variance))
                + log(probabilities[k]   )   )
         # appending discriminant values of each item to 'results' list
         results.append(snake_case_   )

   return [result.index(max(snake_case_   )   ) for result in results]






def 	__UpperCAmelCase					(       snake_case_  :  list   ,	snake_case_  :  list   )							->	float:






   """simple docstring"""


   _lowerCAmelCase					     =		sum(1 for i, j in zip(snake_case_   ,	snake_case_   ) if i == j   )
   # percentage of accuracy equals to number of correct predictions divided by number
   # of all data and multiplied by 100
   return (correct / len(snake_case_   )) * 100


SCREAMING_SNAKE_CASE				:     Union[str, Any]          =	TypeVar('''num''')






def 	__UpperCAmelCase					(       snake_case_  :  Callable[[object], num]   ,	snake_case_  :  str   ,	snake_case_  :  str   ,	snake_case_  :  Callable[[num], bool] = lambda snake_case_   : True   ,	snake_case_  :  str | None = None   ,	)							->	num:






   """simple docstring"""


   while True:
      try:
         _lowerCAmelCase					     =		input_type(input(snake_case_   ).strip() or default   )
         if condition(snake_case_   ):
            return user_input
         else:
            print(F"""{user_input}: {err_msg}"""   )
            continue
      except ValueError:
         print(
             F"""{user_input}: Incorrect input type, expected {input_type.__name__!r}"""   )






def 	__UpperCAmelCase					(       )							->	Optional[int]:






   """simple docstring"""


   while True:
      print(""" Linear Discriminant Analysis """.center(50   ,	"""*"""   )   )
      print("""*""" * 50   ,	"""\n"""   )
      print("""First of all we should specify the number of classes that"""   )
      print("""we want to generate as training dataset"""   )
      # Trying to get number of classes
      _lowerCAmelCase					     =		valid_input(
          input_type=snake_case_   ,	condition=lambda snake_case_   : x > 0   ,	input_msg="""Enter the number of classes (Data Groupings): """   ,	err_msg="""Number of classes should be positive!"""   ,	)

      print("""-""" * 100   )

      # Trying to get the value of standard deviation
      _lowerCAmelCase					     =		valid_input(
          input_type=snake_case_   ,	condition=lambda snake_case_   : x >= 0   ,	input_msg=(
              """Enter the value of standard deviation"""
              """(Default value is 1.0 for all classes): """
          )   ,	err_msg="""Standard deviation should not be negative!"""   ,	default="""1.0"""   ,	)

      print("""-""" * 100   )

      # Trying to get number of instances in classes and theirs means to generate
      # dataset
      _lowerCAmelCase					     =		[]  # An empty list to store instance counts of classes in dataset
      for i in range(snake_case_   ):
         _lowerCAmelCase					     =		valid_input(
             input_type=snake_case_   ,	condition=lambda snake_case_   : x > 0   ,	input_msg=(F"""Enter The number of instances for class_{i+1}: """)   ,	err_msg="""Number of instances should be positive!"""   ,	)
         counts.append(snake_case_   )
      print("""-""" * 100   )

      # An empty list to store values of user-entered means of classes
      _lowerCAmelCase					     =		[]
      for a in range(snake_case_   ):
         _lowerCAmelCase					     =		valid_input(
             input_type=snake_case_   ,	input_msg=(F"""Enter the value of mean for class_{a+1}: """)   ,	err_msg="""This is an invalid value."""   ,	)
         user_means.append(snake_case_   )
      print("""-""" * 100   )

      print("""Standard deviation: """   ,	snake_case_   )
      # print out the number of instances in classes in separated line
      for i, count in enumerate(snake_case_   ,	1   ):
         print(F"""Number of instances in class_{i} is: {count}"""   )
      print("""-""" * 100   )

      # print out mean values of classes separated line
      for i, user_mean in enumerate(snake_case_   ,	1   ):
         print(F"""Mean of class_{i} is: {user_mean}"""   )
      print("""-""" * 100   )

      # Generating training dataset drawn from gaussian distribution
      _lowerCAmelCase					     =		[
          gaussian_distribution(user_means[j]   ,	snake_case_   ,	counts[j]   )
          for j in range(snake_case_   )
      ]
      print("""Generated Normal Distribution: \n"""   ,	snake_case_   )
      print("""-""" * 100   )

      # Generating Ys to detecting corresponding classes
      _lowerCAmelCase					     =		y_generator(snake_case_   ,	snake_case_   )
      print("""Generated Corresponding Ys: \n"""   ,	snake_case_   )
      print("""-""" * 100   )

      # Calculating the value of actual mean for each class
      _lowerCAmelCase					     =		[calculate_mean(counts[k]   ,	x[k]   ) for k in range(snake_case_   )]
      # for loop iterates over number of elements in 'actual_means' list and print
      # out them in separated line
      for i, actual_mean in enumerate(snake_case_   ,	1   ):
         print(F"""Actual(Real) mean of class_{i} is: {actual_mean}"""   )
      print("""-""" * 100   )

      # Calculating the value of probabilities for each class
      _lowerCAmelCase					     =		[
          calculate_probabilities(counts[i]   ,	sum(snake_case_   )   ) for i in range(snake_case_   )
      ]

      # for loop iterates over number of elements in 'probabilities' list and print
      # out them in separated line
      for i, probability in enumerate(snake_case_   ,	1   ):
         print(F"""Probability of class_{i} is: {probability}"""   )
      print("""-""" * 100   )

      # Calculating the values of variance for each class
      _lowerCAmelCase					     =		calculate_variance(snake_case_   ,	snake_case_   ,	sum(snake_case_   )   )
      print("""Variance: """   ,	snake_case_   )
      print("""-""" * 100   )

      # Predicting Y values
      # storing predicted Y values in 'pre_indexes' variable
      _lowerCAmelCase					     =		predict_y_values(snake_case_   ,	snake_case_   ,	snake_case_   ,	snake_case_   )
      print("""-""" * 100   )

      # Calculating Accuracy of the model
      print(F"""Accuracy: {accuracy(snake_case_   ,	snake_case_   )}"""   )
      print("""-""" * 100   )
      print(""" DONE """.center(100   ,	"""+"""   )   )

      if input("""Press any key to restart or 'q' for quit: """   ).strip().lower() == "q":
         print("""\n""" + """GoodBye!""".center(100   ,	"""-"""   ) + """\n"""   )
         break
      system("""cls""" if name == """nt""" else """clear"""   )  # noqa: S605


if __name__ == "__main__":
  main()




"""simple docstring"""





from itertools import combinations_with_replacement






def 	__UpperCAmelCase					(       snake_case_  :  int = 100   )							->	int:






   """simple docstring"""


   _lowerCAmelCase					     =		[*list(range(1   ,	21   )   ), 25]
   _lowerCAmelCase					     =		[2 * x for x in range(1   ,	21   )] + [50]
   _lowerCAmelCase					     =		[3 * x for x in range(1   ,	21   )]
   _lowerCAmelCase					     =		singles + doubles + triples + [0]

   _lowerCAmelCase					     =		0
   _lowerCAmelCase					     =		42
   _lowerCAmelCase					     =		42
   _lowerCAmelCase					     =		42
   _lowerCAmelCase					     =		42

   for double in doubles:
      for throwa, throwa in combinations_with_replacement(snake_case_   ,	2   ):
         _lowerCAmelCase					     =		double + throwa + throwa
         if checkout_total < limit:
            num_checkouts += 1

   return num_checkouts


if __name__ == "__main__":
  print(F'{solution() = }')