Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python object oriented design concepts

I'm just getting back to programming after a 20 year gap. I thought Python looked fairly straightforward and powerful, so I have done an online course and some reading.

I'm now looking at some simple projects to get familiar with the language. One of the challenges is getting my head around object oriented programming, which was not around when I last wrote a program.

My first project was to read in a data file containing information about a share portfolio, do some calculations on each and print a report. I have this working.

So now I am looking at something more advanced, reading in the data and storing it, then using the data to provide answers to interactive questions. My question is how to store the data so it can be accessed easily.

My first thought was to make a list of lists, eg,

companies = [ ['AMP', 1000, 2.50], ['ANZ', 2000, 17.00], ['BHP', 500, 54.30] ]

This can be accessed in loops easily enough, but the access methods are not exactly friendly - numbers as indexes instead of names:

companyqty = companies[1][1]

Or for loops:

for company in companies:
    if company[0] == 'BHP':
        companyqty = company[1]

Then I thought about a dictionary, with the value being a list:

companies = {'AMP':[1000, 2.50], 'ANZ':[2000, 17.00], 'BHP':[500, 54.30] }
companyqty = companies['BHP'][0]

This provides immediate access to any given company, but is still stuck with the numeric indexes.

So I am wondering how to structure this in an object oriented manner so as to be able to hold a list of companies and all the associated data, and be able to access the values conveniently. All my ideas so far just look like lists or dictionaries as above.

Or is this sort of problem not really suited to an object oriented approach?

Thanks

like image 861
David M Avatar asked Aug 17 '13 15:08

David M


3 Answers

This is a fine problem for an OOP approach. You could, for example, create a class for a particular portfolio stock holding, which has attributes for the company name, number of shares, and share price. You can give it useful functions, like getValue. Here's an example implementation:

class Holding:
    def __init__(self, companyName, numShares, sharePrice):
        self.companyName = companyName
        self.numShares = numShares
        self.sharePrice = sharePrice
    def getValue(self):
        return self.numShares * self.sharePrice

portfolio = {'AMP':Holding('AMP', 1000, 2.5), 'ANZ':Holding('ANZ', 2000, 17.0), 'BHP':Holding('BHP', 500, 54.30)}

print portfolio['BHP'].sharePrice
# 54.3
print portfolio['AMP'].getValue()
# 2500.0

You can access the attributes of your holdings by attribute name. You could take it to the next level, and write a class for portfolio, too, which could have attributes like "holdingList", and "broker name", and functions like "getTotalValue", and so forth.

like image 109
Brionius Avatar answered Oct 18 '22 21:10

Brionius


Your next step could be to use a class generated with the collections.namedtuple() factory:

from collections import namedtuple

Company = namedtuple('Company', 'quantity price')

companies = {'AMP': Company(1000, 2.50), 'ANZ': Company(2000, 17.00), 'BHP': Company(500, 54.30)}

companies['AMP'].quantity

Note that like tuple objects, namedtuple-derived objects are immutable. You cannot assign to the attributes, you'd create a new object instead.

You'd only need to switch to custom classes if you needed to add functionality to your objects; add methods that act on the data associated with an object:

class Company(object):
    def __init__(self, quantity, price):
        self.quantity = quantity
        self.price = price

    def profit(self, newprice):
        return self.quantity * (newprice - self.price)
like image 45
Martijn Pieters Avatar answered Oct 18 '22 20:10

Martijn Pieters


you could also use nested dictionaries:

companies =
   {
      'AMP': {'quantity':1000, 'price': 2.50},
      'ANZ': {'quantity':2000, 'price': 17.00},
      'BHP': {'quantity':500, 'price': 54.30}
   }

and access it like:

companyqty = companies['BHP']['quantity']

you even could define extra "properties" for company:

companies =
   {
      'AMP': {'quantity':1000, 'price': 2.50, 'foundation_date': '2013-01-01'},
      'ANZ': {'quantity':2000, 'price': 17.00},
      'BHP': {'quantity':500, 'price': 54.30, 'head': 'Jeffrey'}
   }
like image 20
Roman Pekar Avatar answered Oct 18 '22 20:10

Roman Pekar