{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import scipy as scp\n",
    "import matplotlib.pyplot as plt\n",
    "import csv"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Multi-Factor Anova Test\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this exercise, we practice the multi-factor Anova Test by making the mpartial means table for the following scenario : \n",
    "An EFPL startup wants to build a component for a satellite, but do not know what material to use. They run test on a series of sample with different properties, and attribute a final score to each sample corresponding to how well the sample fits their project.\n",
    "The properties of the sample are :\n",
    "- The Material : can be steel, aluminum or iron\n",
    "- If the material has been annealed : yes or no\n",
    "- The humidity of the environment in which the sample is stored : bins of 10 from 0 to 100"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Load the data from the csv file. Remember to check the csv file for yourself to know which data types to expect and which columns or lines to skip.\n",
    "\n",
    "Here we are expecting different data types and might need to load different lines seperately, then combine them into one list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make 3 lists with the different *levels* that our *factors* can take. These are categories and have no mathematical meaning."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "Factor1_values = np.array([\"Yes\", \"No\"])\n",
    "Factor2_values = np.array([\"Steel\", \"Iron\", \"Aluminum\"])\n",
    "Factor3_values = np.array([\"0-10\", \"10-20\", \"20-30\", \"30-40\", \"40-60\", \"60-70\", \"70-80\", \"80-90\", \"90-100\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Partial Means\n",
    "Let us now make the partial means table for Factors 1 and 2.\n",
    "\n",
    "Start by using a for loop to iterate on the different levels of both factors, and look through the data to find points that fit into this category. Average them and add them to a matrix of appropriate size. Also do the same for the unbiased standard deviation.\n",
    "\n",
    "Remember that you cna use *arr[condition]* to filter out values from an array, and the *&* symbol to use multiple conditions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the given function to plot the partial mean table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tabulate import tabulate\n",
    "\n",
    "def plot_mean_matrix(factor1, factor2, matrix, partial_mean1, partial_mean2, total_mean):\n",
    "    \"\"\" Takes the given Factor Levels, group means and partial means and represents them in a table.\n",
    "    factor1 : A list of levels that the first factor can take.  size (N,)\n",
    "    factor2 : A list of levels that the second factor can take. size (M,)\n",
    "    matrix : The group means of the given levels.   size(N,M)\n",
    "    partial_mean1 : The means over the levels of the first factor   size (N,)\n",
    "    partial_mean2 : The means over the levels of the second factor  size (M,)\n",
    "    total_mean : The total mean of the table\n",
    "    \"\"\"\n",
    "\n",
    "\n",
    "    # Round to get better looking table\n",
    "    matrix = np.round(matrix, 3)\n",
    "    partial_mean1 = np.round(partial_mean1, 3)\n",
    "    partial_mean2 = np.round(partial_mean2, 3)\n",
    "    total_mean = np.round(total_mean, 3)\n",
    "\n",
    "    # Make sure the size is appropriate\n",
    "    factor1 = np.reshape( factor1, (len(factor1),1))\n",
    "    partial_mean1 = np.reshape( partial_mean1, (len(partial_mean1),1))\n",
    "\n",
    "    # Main Matrix\n",
    "    mydata = np.concatenate( (factor1, matrix), axis=1)\n",
    "    # Create Header\n",
    "    head = factor2\n",
    "\n",
    "    # Add partial means\n",
    "    mydata = np.concatenate( (mydata, partial_mean1), axis=1)\n",
    "    mydata = np.concatenate( (mydata, np.reshape(np.append( np.append([\" \"],partial_mean2),[total_mean]), (1,mydata.shape[1])) ) , axis=0)\n",
    "    head = np.append(head, [\" \"] )\n",
    "\n",
    "    # Display table\n",
    "    print(tabulate(mydata, headers=head, tablefmt=\"grid\"))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Represent the different means on a plot with errorbars. The x axis should correspond to the levels of one factor, and multiple plots should represent different values of a second factor."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**(Optional)** Compute the partial mean table of Factor 3 with one other factor, using the previous function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
