2016-05-26 4 views
0

Я пишу программу, которая обрабатывает контракты, срок действия которых истекает в разные месяцы.Python Custom Formatters

Например, контракт на кукурузу фьючерсы, который истекает в декабре 2016 года будет называться:

CZ2016 

где C означает «зерно», Z означает декабря (это пользовательский).

Внутренне представляю все как (year, month).

Каждый тип контракта имеет другой формат, и в идеале мне нужно иметь возможность идти в обоих направлениях.

В настоящее время я написал некоторую сложную обработку строк, чтобы сделать это, но это беспорядок.

Что является самым питоническим способом для этого?

+1

лично - я бы написать '__format__' магический метод (при условии, что каждый контракт представлен экземпляром пользовательского класса, как вы можете просто использовать печать. чтобы создать формат записи. –

+1

Создайте класс с c'tor, который берет строку, и метод '__str__' для возврата подобной строки? –

ответ

3

Вот что-то быстро (МОГ):

#!python3 
import collections 
import time 

class FuturesContract: 
    Commodity = collections.namedtuple('Commodity', 
      'symbol future exchange delivery_months') 

    Commodities = [ 
     # Source: http://www.mrci.com/web/online-explanation-pages/symbols-a-codes.html 
     # !IMPORTANT! Sorted by length of symbol!!! 
     Commodity('ITCO', 'Brent Crude', 'ICE', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('AD', 'Australian Dollar', 'CME', 'H,M,U,Z'), 
     Commodity('BP', 'British Pound', 'CME', 'H,M,U,Z'), 
     Commodity('CD', 'Canadian Dollar', 'CME', 'H,M,U,Z'), 
     Commodity('DX', 'US Dollar Index', 'ICE', 'H,M,U,Z'), 
     Commodity('EU', 'EuroFx', 'CME', 'H,M,U,Z'), 
     Commodity('JY', 'Japanese Yen', 'CME', 'H,M,U,Z'), 
     Commodity('SF', 'Swiss Franc', 'CME', 'H,M,U,Z'), 
     Commodity('CL', 'Crude Oil', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('HO', 'NY Harbor ULSD/Heating Oil', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('HU', 'Unleaded Gas', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('NG', 'Natural Gas', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('RB', 'RBOB Gasoline', 'NYM', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('BO', 'Soybean Oil', 'CBOT', 'F,H,K,N,Q,U,V,Z'), 
     Commodity('KW', 'Kansas City Wheat', 'KCBT', 'H,K,N,U,Z'), 
     Commodity('MW', 'Minneapolis Wheat', 'MGE', 'H,K,N,U,Z'), 
     Commodity('SM', 'Soybean Meal', 'CBOT', 'F,H,K,N,Q,U,V,Z'), 
     Commodity('DJ', 'Dow Jones Industrials', 'CBOT', 'H,M,U,Z'), 
     Commodity('KV', 'Value Line (Discontinued)', 'KCBT', 'H,M,U,Z'), 
     Commodity('MV', 'Value Line (Mini)', 'KCBT', 'H,M,U,Z'), 
     Commodity('ND', 'Nasdaq-100', 'CME', 'H,M,U,Z'), 
     Commodity('RL', 'Russell 2000 (Discontinued)', 'CME', 'H,M,U,Z'), 
     Commodity('SP', 'S & P 500', 'CME', 'H,M,U,Z'), 
     Commodity('YU', 'NYSE Composite (Discontinued)', 'NYFE', 'H,M,U,Z'), 
     Commodity('ED', 'Eurodollars', 'CME', 'H,M,U,Z'), 
     Commodity('FV', '5-Yr T-Notes', 'CBOT', 'H,M,U,Z'), 
     Commodity('MB', 'Municipal Bonds', 'CBOT', 'H,M,U,Z'), 
     Commodity('TU', '2-Yr T-Notes', 'CBOT', 'H,M,U,Z'), 
     Commodity('TY', '10-Yr T-Notes', 'CBOT', 'H,M,U,Z'), 
     Commodity('US', '30-Yr T-Bonds', 'CBOT', 'H,M,U,Z'), 
     Commodity('FC', 'Feeder Cattle', 'CME', 'F,H,J,K,Q,U,V,X'), 
     Commodity('LC', 'Live Cattle', 'CME', 'G,J,M,Q,V,Z'), 
     Commodity('LH', 'Lean Hogs', 'CME', 'G,J,K,M,N,Q,V,Z'), 
     Commodity('LE', 'Lean Hogs', 'CME', 'G,J,K,M,N,Q,V,Z'), 
     Commodity('PB', 'Pork Bellies', 'CME', 'G,H,K,N,Q'), 
     Commodity('DA', 'Milk Class III', 'CME', 'F,G,H,J,K,M,N,Q,U,V,X,Z'), 
     Commodity('GC', 'Gold', 'CMX', 'G,J,M,Q,V,Z'), 
     Commodity('HG', 'Copper', 'CMX', 'H,K,N,U,Z'), 
     Commodity('PL', 'Platinum', 'NYM', 'F,J,N,V'), 
     Commodity('SI', 'Silver', 'CMX', 'H,K,N,U,Z'), 
     Commodity('RR', 'Rice', 'CBOT', 'F,H,K,N,U,X'), 
     Commodity('CC', 'Cocoa', 'ICE', 'H,K,N,U,Z'), 
     Commodity('CT', 'Cotton', 'ICE', 'H,K,N,V,Z'), 
     Commodity('KC', 'Coffee', 'ICE', 'H,K,N,U,Z'), 
     Commodity('LB', 'Lumber', 'CME', 'F,H,K,N,U,X'), 
     Commodity('JO', 'Orange Juice', 'ICE', 'F,H,K,N,U,X'), 
     Commodity('SB', 'Sugar #11', 'ICE', 'H,K,N,V'), 
     Commodity('C', 'Corn', 'CBOT', 'F,H,K,N,U,X,Z'), 
     Commodity('O', 'Oats', 'CBOT', 'H,K,N,U,Z'), 
     Commodity('S', 'Soybeans', 'CBOT', 'F,H,K,N,Q,U,X'), 
     Commodity('W', 'Wheat', 'CBOT', 'H,K,N,U,Z'), 
    ] 

    Months = { 
     1: 'January', 
     2: 'February', 
     3: 'March', 
     4: 'April', 
     5: 'May', 
     6: 'June', 
     7: 'July', 
     8: 'August', 
     9: 'September', 
     10: 'October', 
     11: 'November', 
     12: 'December', 
     'F': 'January', 
     'G': 'February', 
     'H': 'March', 
     'J': 'April', 
     'K': 'May', 
     'M': 'June', 
     'N': 'July', 
     'Q': 'August', 
     'U': 'September', 
     'V': 'October', 
     'X': 'November', 
     'Z': 'December', 
    } 

    MonthCodes = { 
     'January': 'F', 
     'February': 'G', 
     'March': 'H', 
     'April': 'J', 
     'May': 'K', 
     'June': 'M', 
     'July': 'N', 
     'August': 'Q', 
     'September': 'U', 
     'October': 'V', 
     'November': 'X', 
     'December': 'Z', 
    } 

    def __init__(self, details=None): 
     if details is None: 
      now = time.localtime() 
      month = now.tm_mon 
      year = now.tm_year 
      self.commodity = None 
     else: 
      for c in self.Commodities: 
       if details.startswith(c.symbol): 
        self.commodity = c 
        symlen = len(c.symbol) 
        month = details[symlen:symlen+1] 
        year = details[symlen+1:] 
        if len(year) == 2: 
         year = '20'+year 
        year = int(year) 
        break 
      else: 
       raise ValueError("Unparseable details given: "+details) 

     month = self.Months[month] 
     if self.commodity is not None: 
      month_code = self.MonthCodes[month] 
      if month_code not in self.commodity.delivery_months: 
       raise ValueError('Invalid delivery month for commodity: '+month) 

     self.month = month 
     self.year = year 

    def __str__(self): 
     c = self.commodity 
     return 'Unspecified' if c is None else c.symbol + self.MonthCodes[self.month] + str(self.year) 


    def explain(self): 
     c = self.commodity 
     return [ 'A FuturesContract for:', 
       '\t{}: {} (on the {} exchange)'.format(c.symbol, c.future, c.exchange), 
       '\tDated: {} ({}), {}'.format(self.month, self.MonthCodes[self.month], self.year), 
       ] 

cz2016 = FuturesContract('CZ2016') 

print('\n'.join(cz2016.explain())) 
print('\n') 
print('Commodity:', cz2016.commodity) 
print('Month:', cz2016.month) 
print('Year:', cz2016.year) 

print("\nHas __str__:", cz2016) 

print("\n\n") 
print("Future LBQ2014: (should be invalid, because Q):") 
fc = FuturesContract('LBQ2014') 
+0

О, боже мой, это потрясающе! Спасибо, скажи, пишите это только для этого вопроса? :) – cjm2671