Norbert Wesolowski
Norbert Wesolowski

Reputation: 75

Is there a way to short lots of repeated code in a class

I have the following code:

import matplotlib.pyplot as plt ### imports plotting
import numpy as np
import pandas as pd

class Population:
    def __init__(self,name,population):
        self.name = name
        self.population = population
        self.conservative = self.population * 48/100
        self.labour = self.population * 30/100
        self.libDem = self.population * 12/100
        self.green = self.population * 5/100
        self.brexit = self.population * 3/100
        self.others = self.population * 2/100

    def distribution(self):
        print(self.conservative)
        print(self.labour)
        print(self.libDem)
        print(self.brexit)
        print(self.others)

    def rulingParty(self):
        parties = {"Conservative":self.conservative,"Labour":self.labour,"LibDem":self.libDem,"Green":self.green,"Brexit":self.brexit,"Other":self.others}
        return max(parties, key=parties.get)

    def addCon(self,amount, Lab=1/5,LD=1/5,GRN=1/5,BXT=1/5,Others=1/5):
        self.conservative += amount
        self.labour += -amount * Lab
        self.libDem += -amount * LD
        self.green += -amount * GRN
        self.brexit += -amount * BXT
        self.others += -amount * Others

    def addLab(self,amount, Con=1/5,LD=1/5,GRN=1/5,BXT=1/5,Others=1/5):
        self.labour += amount
        self.conservative += -amount * Con
        self.libDem += -amount * LD
        self.green += -amount * GRN
        self.brexit += -amount * BXT
        self.others += -amount * Others

    def addLD(self,amount, Con=1/5,Lab=1/5,GRN=1/5,BXT=1/5,Others=1/5):
        self.libDem += amount
        self.conservative += -amount * Con
        self.labour += -amount * Lab
        self.green += -amount * GRN
        self.brexit += -amount * BXT
        self.others += -amount * Others

    def addGRN(self,amount, Con=1/5,Lab=1/5,LD=1/5,BXT=1/5,Others=1/5):
        self.green += amount
        self.conservative += -amount * Con
        self.labour += -amount * Lab
        self.libDem += -amount * LD
        self.brexit += -amount * BXT
        self.others += -amount * Others

    def addBXT(self,amount, Con=1/5,Lab=1/5,LD=1/5,GRN=1/5,Others=1/5):
        self.brexit += amount
        self.conservative += -amount * Con
        self.labour += -amount * Lab
        self.libDem += -amount * LD
        self.green += -amount * GRN
        self.others += -amount * Others

    def addOthers(self,amount, Con=1/5,Lab=1/5,LD=1/5,GRN=1/5,BXT=1/5):
        self.others += amount
        self.conservative += -amount * Con
        self.labour += -amount * Lab
        self.libDem += -amount * LD
        self.green += -amount * GRN
        self.brexit += -amount * BXT

c = Population("UK",100000)
d = [c.conservative,c.labour,c.libDem,c.green,c.brexit,c.others]
while not c.rulingParty()=="Labour": 
    c.addCon(-1000)
    d = np.vstack((d,[c.conservative,c.labour,c.libDem,c.green,c.brexit,c.others]))


print(d)
print(np.shape(d)[0])

It should be noted that this is just an exercise I'm doing to improve my python skills and not a political simulation of any kind. My question is, is there any way to reduce the number of repeated lines amongst the addCon(), addLab() etc. functions, as they all have lots of the same code.

Any feedback would be appreciated Yours,

Upvotes: 1

Views: 59

Answers (1)

cadolphs
cadolphs

Reputation: 9617

There absolutely is, but it involves a teeny bit of extra work.

First, I wouldn't have libDem and conservative as fields in the class. Instead, I'd have them be keys in a dictionary, and votes as values. Kinda like you do in the ruling_party method. But set the dictionary up in __init__ instead, and then you can rewrite your methods.

In fact, you can consolidate them all into a single method:

def add_party(self, party, amount, adjustment_factors):
    self.votes[party] += amount
    for other_party in self.votes:
        if other_party != party:
            factor = adjustment_factors.get(other_party, 1/5)
            self.votes[other_party] -= amount * factor

Upvotes: 1

Related Questions