[Tutor] Code structure help
Hi, Note I have cross posted this as I have only just found this mailing list and perhaps it is the more appropriate place (I am not sure)? I have been working on re-writing a model in python. However I am not sure how easy on the eye my final structure is and would appreciate any constructive comments/suggestions. So broadly the model estimates how plants grow using a number of related sub functions which I have grouped into classes and they all live in separate files. My main issue at the moment is I think I have a lot of verbose class instances but I really can't see a better way to do it. Is there a better way? How do other people do similar things? I am talking largely about the instances in the method run_sim I have left some of the bones of the code out but this is basically what would it looks like. thanks, Martin import constants as const from file_parser import ConfigFileParser from plant_growth import PlantGrowth from print_outputs import PrintOutput from litter import LitterFlows from decomp import DecompFactors from soil_cnflows import CarbonFlows, NitrogenFlows from nmineralisation import Mineralisation from update_pools import CarbonPools, NitrogenPools ...etc... class ModelName(object): def __init__(self, cfg_fname=None): Set everything up Read meterological forcing file, any user adjusted files. If there is anything in the user file then adjust the model parameters, control or initial state attributes that are used within the code. # sweep the cmd line options, args = cmdline_parser() # quit if asked only to dump default paramater files if options.DUMP_INPUT == True: ...call some stuff... # read in user defined variables (stored in dictionaries) pars = ConfigFileParser(cfg_fname=cfg_fname) (control, params, state, files, fluxes, met_data) = pars.main() # objects holding model state, fluxes, etc self.met_data = met_data self.control = control self.params = params self.state = state self.fluxes = fluxes # instances of other model parts.. self.pr = PrintOutput(self.params, self.state, self.fluxes, self.control, self.files, dump=False) # start date of simulation self.date = self.simulation_start_date() ...etc def run_sim(self): mi = Mineralisation(self.control, self.params, self.state, self.fluxes) cf = CarbonFlows(self.control, self.params, self.state, self.fluxes) nf = NitrogenFlows(self.control, self.params, self.state, self.fluxes) de = Derive(self.control, self.params, self.state, self.fluxes) dc = DecompFactors(self.control, self.params, self.state, self.fluxes) lf = LitterFlows(self.control, self.params, self.state, self.fluxes) pg = PlantGrowth(self.control, self.params, self.state, self.fluxes, self.met_data) cpl = CarbonPools(self.control, self.params, self.state, self.fluxes) npl = NitrogenPools(self.control, self.params, self.state, self.fluxes) for i in self.met_data.doy: project_day = i - 1 # N:C ratios leafnc, rootnc = self.leaf_root_ncratio() # litterfall rate: C and N fluxes lf.flows(leafnc, rootnc) # plant growth pg.grow(project_day, self.date, leafnc) # calculate model decay rates dc.decay_rates() # soil model fluxes cf.calculate_cflows() nf.calculate_nflows() # N uptake and loss mi.calculate_mineralisation() # soil model - update pools cact, cslo, cpas = cpl.calculate_cpools() npl.calculate_npools(cact, cslo, cpas) if self.control.print_options == 1: self.pr.print_state() self.pr.print_fluxes() self.increment_date() if self.control.print_options == 2: self.pr.print_state() self.pr.print_fluxes() # house cleaning, close ouput files self.pr.tidy_up() ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Code structure help
Martin De Kauwe wrote: Note I have cross posted this as I have only just found this mailing list and perhaps it is the more appropriate place (I am not sure)? I think your question is appropriate for both lists, it just wasn't sexy enough for anyone on c.l.py to answer ;) I have been working on re-writing a model in python. However I am not sure how easy on the eye my final structure is and would appreciate any constructive comments/suggestions. So broadly the model estimates how plants grow using a number of related sub functions which I have grouped into classes and they all live in separate files. My main issue at the moment is I think I have a lot of verbose class instances but I really can't see a better way to do it. Is there a better way? How do other people do similar things? I am talking largely about the instances in the method run_sim Random remarks: pg = PlantGrowth(self.control, self.params, self.state, self.fluxes, self.met_data) I'd prefer your code to be even more verbose here; no two-letter variables for anything that is non-generic. # plant growth pg.grow(project_day, self.date, leafnc) With the construction in mind that is actually # plant growth plant_growth.grow(project_day, self.date, leafnc) but plant_grows.grow() does not make a lot of sense, and the comment is superfluous as it just undoes the abbreviation instead of explaining what is going on. for i in self.met_data.doy: project_day = i - 1 self.increment_date() I'd iterate over the project_day-s directly if possible for project_day in self.project_days(): ... # calculate model decay rates dc.decay_rates() A lot of methods don't take any arguments and return nothing. I'm guessing that they modify the state that you passed to the initializer. I prefer these modifications to be explicit if feasible, e. g. state = dc.decay_rates(state) where of course state is a placeholder for the actual variables that are necessary to do the calculations. The big picture? I'll leave that for someone else. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Code structure help
(...snip...) I think your question is appropriate for both lists, it just wasn't sexy enough for anyone on c.l.py to answer ;) what is not sexy about modelling plant carbon uptake ;P Random remarks: pg = PlantGrowth(self.control, self.params, self.state, self.fluxes, self.met_data) I'd prefer your code to be even more verbose here; no two-letter variables for anything that is non-generic. ok so a more thorough name then? I had seen class instances used before with single letters # plant growth pg.grow(project_day, self.date, leafnc) With the construction in mind that is actually Sorry don't get this? # plant growth plant_growth.grow(project_day, self.date, leafnc) but plant_grows.grow() does not make a lot of sense, and the comment is superfluous as it just undoes the abbreviation instead of explaining what is going on. Yep sorry I haven't gone through and finished all the comments, some of them were placeholders! Agreed grow isn't the best name # calculate model decay rates dc.decay_rates() A lot of methods don't take any arguments and return nothing. I'm guessing that they modify the state that you passed to the initializer. I prefer these modifications to be explicit if feasible, e. g. state = dc.decay_rates(state) where of course state is a placeholder for the actual variables that are necessary to do the calculations. yes well i guess that is one of the issues - two objects state and fluxes are modified throughout. So you think it is better to pass these to the methods rather than to the class constructors? If i do it that way I potentially have to then pass it throughout a number of methods in other classes. The way I set it up, I could call it though the self statement, e.g. self.fluxes.some_variable in a various class methods. The big picture? I'll leave that for someone else. thanks ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor -- View this message in context: http://old.nabble.com/-Tutor--Code-structure-help-tp31124923p31126370.html Sent from the Python - tutor mailing list archive at Nabble.com. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor