Help with some feedback... please :)

Hi coders

I hope you are all well.

Please may you give me some feedback on my code for the Medical Insurance project?

I found the project relatively easy. But this is largely related to the topics I chose to investigate. (I initially aimed to do a linear regression between medical aid costs and the amount of child one has for both females and males, but quickly realised that was going to be too difficult for the level I am at at the moment… I think.)

I am still struggling to comprehend when to use a Class vs a Function.
Similarly, I’m struggling (slightly) with when to know when to use self.

The link to the project overview:

my code:

import csv

age =[]
sex = []
bmis =[]
children =[]
smoker =[]
region = []
charges = []

with open("insurance.csv") as insurance_data:
    insurance_data_dic = csv.DictReader(insurance_data)
    for row in insurance_data_dic:

class PatientInfo:
    def __init__(self, p_age, p_sex, p_bmi, p_children, p_smoker, p_region, p_charges):
        self.p_age= p_age
    def count_men_and_women(self):
        self.count_women = 0
        self.count_men = 0
        for i in range(0,len(self.p_sex)):
            if self.p_sex[i] == "female":
                self.count_women += 1
            if self.p_sex[i] == "male":
                self.count_men += 1
        print("There are {} women and {} men in the sample".format(self.count_women, self.count_men))
        return self.count_women, self.count_men
    def average_age_per_m_and_w(self):
        total_womens_age = 0
        total_mens_age = 0
        for i in range(0,len(self.p_sex)):
            if self.p_sex[i] == "female":
                total_womens_age += int(self.p_age[i])
            if self.p_sex[i] == "male":
                total_mens_age += int(self.p_age[i])
        average_womens_age = total_womens_age/self.count_women
        average_mens_age = total_mens_age/self.count_men
        print("The average age of the women and men are {} and {}, respectively".format(average_womens_age, average_mens_age))
        return average_womens_age, average_mens_age
    def average_charges_per_m_and_w(self):
        total_charges_women = 0
        total_charges_men = 0
        for i in range(0, len(self.p_sex)):
            if self.p_sex[i] == "female":
                total_charges_women += float(self.p_charges[i])
            if self.p_sex[i] == "male":
                total_charges_men += float(self.p_charges[i])
        self.average_charges_women = total_charges_women/self.count_women
        self.average_charges_men = total_charges_men/self.count_men
        print("The average cost for women is {} and men {}".format(self.average_charges_women, self.average_charges_men))
        return self.average_charges_women, self.average_charges_men

patient_info = PatientInfo(age, sex, bmi, children, smoker, region, charges)

# printed There are 662 women and 676 men in the sample

# The average age of the women and men are 39.503021148036254 and 38.917159763313606, respectively

# The average cost for women is 12569.57884383534 and men 13956.751177721886


self is an indicator to variables and methods that a particular instance of a class holds. This becomes clearer when there are more than 1 class objects instantiated. person1 and person2 might have the same person-ness but they will each consider their own self to be self-contained and unique… (e.g. I will consider my name to be Pita, but my neighbor will consider their name to be Baguette, and in their head they will think: "*my* name is Baguette").

which ties in well to the question of: to write a class or not to…
The paradigm offers a lot of benefits, but sometimes it’s not necessary to write one (and there are programming paradigms that don’t use them).