Homework 9

eda.py

Note: many variations were accepted.

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns


def load_data(file_path):
    # read the csv file, dropping the id column
    df = pd.read_csv(file_path)
    df.drop(columns=['id'], inplace=True)
    return df

def pivotByDiagnosisAndShowMean(df, columns):
    # pivot the dataframe by diagnosis and show the mean of the columns
    return df.groupby('diagnosis')[columns].mean()

def customPandasAnalysis(df):
    df = df.copy()
    df["radius_q"] = pd.qcut(df["radius_mean"], 4, labels=["Q1", "Q2", "Q3", "Q4"])
    return df.groupby(["diagnosis", "radius_q"])[["area_mean", "perimeter_mean"]].mean()

def showPairPlot(df, columns):
    # show the pair plot of the columns
    sns.pairplot(df[columns + ["diagnosis"]], hue='diagnosis')
    plt.show()

def customPlot(df):
    sns.heatmap(df[["radius_mean", "perimeter_mean", "area_mean"]].corr(), annot=True)
    plt.show()

if __name__ == "__main__":
    df = load_data("wdbc.csv")
    print(df.head())
    assert len(df.columns) == 31
    assert df.columns.tolist() == [
        "diagnosis",
        "radius_mean",
        "radius_worst",
        "radius_se",
        "texture_mean",
        "texture_worst",
        "texture_se",
        "perimeter_mean",
        "perimeter_worst",
        "perimeter_se",
        "area_mean",
        "area_worst",
        "area_se",
        "smoothness_mean",
        "smoothness_worst",
        "smoothness_se",
        "compactness_mean",
        "compactness_worst",
        "compactness_se",
        "concavity_mean",
        "concavity_worst",
        "concavity_se",
        "concavepoints_mean",
        "concavepoints_worst",
        "concavepoints_se",
        "symmetry_mean",
        "symmetry_worst",
        "symmetry_se",
        "fractaldimension_mean",
        "fractaldimension_worst",
        "fractaldimension_se",
    ]

    # show the mean of the columns grouped by diagnosis
    mean_df = pivotByDiagnosisAndShowMean(df, ["radius_mean", "smoothness_mean", "texture_mean"])
    print(mean_df)

    # show the pair plot of the columns
    showPairPlot(df, ["radius_mean", "perimeter_mean", "smoothness_mean"])

oop.py

Note: many variations were accepted.

class Zoo:
    def __init__(self):
        self.animals = []

    def add_animal(self, animal):
        if animal not in self.animals:
            self.animals.append(animal)

    def __str__(self):
        animals_by_type = {}
        for animal in self.animals:
            if isinstance(animal, Carnivore):
                animal_type = "Carnivore"
            elif isinstance(animal, Herbivore):
                animal_type = "Herbivore"
            if animal_type not in animals_by_type:
                animals_by_type[animal_type] = []
            animals_by_type[animal_type].append(animal)
        return str(animals_by_type)

    def __len__(self):
        return len(self.animals)

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        # NOTE: can also do on any of the child classes, as self.__class__.__name__ is hard
        return f"<{self.name} the {self.__class__.__name__}, Age: {self.age}>"

    def __eq__(self, other):
        return self.name == other.name and self.age == other.age and isinstance(other, self.__class__)

class Carnivore(Animal):
    pass

class Herbivore(Animal):
    pass

class Lion(Carnivore):
    pass

class Tiger(Carnivore):
    pass

class Elephant(Herbivore):
    pass

class Zebra(Herbivore):
    pass

class Exhibit(Zoo):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def add_animal(self, animal):
        if self.animals:
            if isinstance(animal, Carnivore) and isinstance(self.animals[0], Herbivore):
                print(f"Cannot add {animal.name} to {self.name} exhibit. It is a carnivore.")
                return
            if isinstance(animal, Herbivore) and isinstance(self.animals[0], Carnivore):
                print(f"Cannot add {animal.name} to {self.name} exhibit. It is a herbivore.")
                return
        super().add_animal(animal)

    def __str__(self):
        return f"{self.name} Exhibit: {super().__str__()}"

def main():
    # Create a new zoo
    my_zoo = Zoo()

    # Create some animals
    lion = Lion("Leo", 5)
    tiger = Tiger("Tiggy", 3)
    elephant = Elephant("Dumbo", 10)
    zebra = Zebra("Zara", 4)
    zebra_2 = Zebra("Zuzu", 3)

    # Add animals to the zoo
    my_zoo.add_animal(lion)
    my_zoo.add_animal(tiger)
    my_zoo.add_animal(elephant)
    my_zoo.add_animal(zebra)
    my_zoo.add_animal(zebra_2)

    print("")
    print(f"My Zoo: {my_zoo}")
    print(f"Number of animals in the zoo: {len(my_zoo)}")
    print("")

    # Duplicates not added!
    my_zoo.add_animal(zebra)
    print(f"After attempting to add a duplicate zebra: {my_zoo}")
    print(f"Number of animals in the zoo after duplicate attempt: {len(my_zoo)}")
    print("")

    # Check if the animals are instances of Animal
    print(f"Is {lion.name} an Animal? {isinstance(lion, Animal)}")
    print(f"Is {tiger.name} an Animal? {isinstance(tiger, Animal)}")
    print(f"Is {elephant.name} an Animal? {isinstance(elephant, Animal)}")
    print(f"Is {zebra.name} an Animal? {isinstance(zebra, Animal)}")
    print(f"Is {zebra_2.name} an Animal? {isinstance(zebra_2, Animal)}")
    print("")

    # Check if the animals are instances of Carnivore or Herbivore
    print(f"Is {lion.name} a Carnivore? {isinstance(lion, Carnivore)}")
    print(f"Is {tiger.name} a Carnivore? {isinstance(tiger, Carnivore)}")
    print(f"Is {elephant.name} a Herbivore? {isinstance(elephant, Herbivore)}")
    print(f"Is {zebra.name} a Herbivore? {isinstance(zebra, Herbivore)}")
    print(f"Is {zebra_2.name} a Herbivore? {isinstance(zebra_2, Herbivore)}")
    print("")

    # Make an exhibit
    exhibit = Exhibit("Savannah")
    print(f"Exhibit before adding animals: {exhibit}")
    print(f"Exhibit is a subclass of Zoo: {isinstance(exhibit, Zoo)}")
    print("")

    # Add animals to the exhibit
    exhibit.add_animal(elephant)
    exhibit.add_animal(zebra)
    print(f"Exhibit after adding animals: {exhibit}")
    print(f"Number of animals in the exhibit: {len(exhibit)}")
    print("")

    # Attempt to add a carnivore to the herbivore exhibit
    print("Attempting to add a carnivore to the herbivore exhibit...")
    exhibit.add_animal(lion)
    print(f"Exhibit after attempting to add a carnivore: {exhibit}")
    print(f"Number of animals in the exhibit after attempting to add a carnivore: {len(exhibit)}")

if __name__ == "__main__":
    main()