Python Design Concepts

I am only returning to programming after a 20 year gap. I thought Python looked pretty simple and powerful, so I did an online course and some reading.

Now I am looking through a few simple projects to familiarize myself with the language. One of the problems is that I get a head from object-oriented programming, which was not the last time I wrote a program.

My first project was to read in a data file containing information about a stock portfolio, do some calculations for each and print a report. It works for me.

So, now I look at something more advanced, reading the data and saving it, and then using the data to provide answers to interactive questions. My question is how to store data so that it can be easily retrieved.

My first thought was to make a list of lists, for example

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

They can be easily accessed in cycles, but the access methods are not entirely friendly - numbers as indices instead of names:

 companyqty = companies[1][1] 

Or for loops:

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

Then I thought of a dictionary whose value is 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 fixated on numerical indices.

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

Or is it a problem that is not suitable for an object-oriented approach?

thanks

+4
source share
4 answers

This is a good problem for the OOP approach. For example, you can create a class for a specific stock portfolio that has attributes for the company name, number of shares, and stock price. You can give it useful functions like getValue . Here is 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 can go to the next level and write a class for the portfolio, which can have attributes such as "keepList" and "broker name" and functions such as "getTotalValue", etc.

+4
source

The next step may be to use the class generated by 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 objects namedtuple listed objects are immutable. You cannot assign attributes; instead, you must create a new object.

You will need to switch to custom classes if you need to add functionality to your objects; add methods that act on the data associated with the 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) 
+3
source

you can 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 as:

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

You can even define additional “properties” for the 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'} } 
+1
source

Even in Python there is one and only one way to do something, the answer to this question really depends on what is “easy to access”.

Does this mean that it is easy for a programmer to access an object and its attribute? Then the best way is to make the company an instance of the class and provide attributes by price, quantity, etc. This is probably overproduction to create the Portfolio class, unless you have a non-trivial logic other than the one listed or dict. It is also possible to make a class based on a dictionary, so access by keys and attributes is possible. This is what I would call affordable easily. Take a look at the Storage Framework webpy class: https://github.com/webpy/webpy/blob/master/web/utils.py#L52 as an example.

If “easy to access” means that some serialization or other processing data will be performed using data from a third-party library, then the easiest way is to use the data structures expected by the library. For example, the JSON format works very well with Python lists and dictionaries (see Roman Pekar's answer).

0
source

Source: https://habr.com/ru/post/1497588/


All Articles