I'm trying build a framework which starts with reading an input file which contains some keys and corresponding values. I then update the variables accordingly:
from Inertia import Inertia
...
d = hf.read_input(fin)
locals().update(d)
Then, I'm defining the group MDA:
class MDA(om.Group):
class ObjCmp(om.ExplicitComponent):
def setup(self):
...
def setup_partials(self):
...
def compute(self, inputs, outputs):
...
def setup(self):
...
which contains two subsystems (for now):
self.add_subsystem('d1', SomeModule(), promotes_inputs=['x1','x2'],
promotes_outputs=['y1','y2'])
self.add_subsystem('obj_cmp', self.ObjCmp(), promotes_inputs=['y1'],
promotes_outputs=['obj'])
For housekeeping reasons, since the framework will eventually contain large number of subsystems, I want to keep the classes defining the particular subsystems in separate scripts, imported the the main script (the one where the Group is defined).
The problem I'm facing is that if I only read the input file once at the level of the script where the Group is defined (before entering the Group() class), the variables retrieved this way are not defined at the lower levels, for instance, I cannot use them inside SomeModule(). I'd normally define an init() method inside SomeModule() to be able to pass some variables:
def __init__(self, d):
self.d = d
but since we instantiate the SomeModule() class within self.add_subsystem(), it does not work.
I would be really grateful for any hints.
In OpenMDAO, we deal with this instantiation timing issue in two ways:
We strongly discourage the use of the __init__ method for components or groups. Instead, we recommend you rely on the initialize and setup methods. initialize is called inside the existing __init__ (i.e. at instantiation time). setup is called much later during the build up of the model hierarchy.
We do provide a means of creating init arguments via an options system. Options allow for some built in validation and also give you the chance to change the values later if you want to.
Delaying as much as possible till setup, if you can. Pass your configuration file (or an object built from it if you prefer) into your component as an option, but don't actually use it till setup.
This goes for both components and groups. You can make the configuration data an option at all levels of your groups. They will each pass the object down to their children inside their own setup methods. This way, you only need to have the object in existence by the time you initialize the top level group. It will then pass it down to all its children.
Related
I'm building a class (sorry - Agent) that will work with a set of Tank objects (Fluid Library) - doing things like monitoring individual levels or total level of all tanks, reporting on levels and initiating actions based on levels - things of that nature. For argument's sake let's call it a "TankMonitor" agent.
Ideally I'd like to be able to define a Parameter in my "TankMonitor" agent that allows me to define the tanks of interest when I place a TankMonitor in main. I have tried to define the type of the parameter as Other - ArrayList<Tank> however I don't know how to set up the next step to allow me to populate the ArrayList of Tanks when I put an instance of this agent in main. My preference would be to have a list type control to populate the ArrayList - much like the way the AnyLogic Seize block allows you to specify multiple resource pools to choose from.
Has anyone attempted this before and been successful?
This is possible as follows:
Change the type to "Other" and then 'Tank[]' , i.e. an Array of Tanks
Change the control type to "one-dimensional array"
Example below. Now you have the same UI to pre-define tanks at design time for your agent instance.
In addition to Benjamin's perfect answer, I'd just add the manual workaround, which is not needed here but can be useful when the parameter in question has a more complicated structure than covered by the pre-made controls, say a list of lists, a map, or similar.
In such a case, the Control Type is still Text, and populating it in an instance happens by pointing it to a new object of the parameter's type. E.g. for an ArrayList<Tank> parameter, you might instantiate a new ArrayList object, which you fill with a list of objects like so:
new ArrayList<Tank>(Arrays.asList(tankA, tankB))
In the Java code, whatever is written into that text box will end up on the right side of a parameter assignment statement in the embedded Agent instance's auto-generated parameter setup function. Therefore, multi-statement code won't work in this spot. Instead, if the process of building the parameter value doesn't fit neatly into a single expression, you can hide the code in a function which returns the desired object, and call that from the parameter's text box.
I'm newbie to Scala, and I have years of experience programming in Java.
Usually there are two patterns passing some config:
Using a global object sounds like "ConfigManager". And every time I
needs a config I get directly from it.
Passing the config through parameter. The config param may exists in
many layers in the program.
I choose one pattern depends on how the config will be used when I'm writing Java.
But in Scala, many people talks about eliminating side effects. This makes me wonder if I should use the second patterns at any costs.
Which pattern is better in Scala?
Global objects are bad: https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil
Make each component take it's configuration (individual pieces) as constructor parameters (possibly with some defaults). That prevents the creation of invalid components or components that have not been configured.
You can collect the initial processing of configuration values in a single class to centralize configuration code and to fail-fast when things are missing. But don't make your components (classes needing the configuration) depend on a global object or take in an entire configuration as a parameter. Just what they need as constructor params.
Example:
// centralize the parsing of configuration
case class AppConfig (config: Config) {
val timeInterval = config.getInt("type_interval")
val someOtherSetting = config.getString("some_other_setting")
}
...
// don't depend on global objects
class SomeComponent (timeInterval: Int) {
...
}
object SomeApplication extends App {
val config = AppConfig(ConfigFactory.load())
val component = new SomeComponent(config.timeInterval)
}
Use global object (this object stores only read-only immutable data, so no issues) which loads configuration object and config variables at once. This has many benefits over loading the configuration deep inside the code.
object ConfigParams {
val config = ConfigFactory.load()
val timeInterval = config.getInt("time_interval")
....
}
Benefits:
Prevents runtime errors (Fail fast approach).
If you have miss spelt any property name your app fails during startup as you are trying to fetch the data eagerly. If this were to be deep inside the codebase then it would be hard to know and it fails when the control of the program goes to that line. So, it cannot be easily detected unless rigorous testing is done.
Central place for all configuration logic and configuration transformations if any.
This serves as a central place for all config logic. easy to change and maintain.
Transformations can be done without need for refactoring the code.
Maintainable and readable.
Easy refactoring.
Functional programming point of view
Yes, loading the config file eagerly is great idea from Fail fast point of view but its not a good functional programming practice.
But important thing is you are not mixing the side effect with any other logic and keeping it separate during the loading of the app. So, as you are isolating the side effect and side effecting at the starting of your project, this would not be a program.
Once the side effecting is done and app has started. Your pure code base will not effected from this and remains pure and clean. So, though it is side effecting, it is isolated and does not effect your codebase. Benefits you again from this are worth experiencing, So go ahead.
I would like to present the user with a variable number of scenes within the GUI (arranged say horizontally) composing different views of the data, depending on runtime conditions?
I really don't want to redefine the GUI, and a number of scene related traits for every use case. (i.e. bool_scene_1_viewable=Bool(), bool_scene_2_viewable=Bool()... )
It looks like I might be able to define a wildcard trait: scene_=Instance(Scene,()). But, if this is the best way to do it, how would I go about combining n traits into a View?
(A) I did not distinguish between "runtime" dependence, and merely depending on some number of traits that are declared after initialization (but before config_traits is called). As such, I can use default_traits_view to create a view that depends on the current state of the object and its members.
(B) I was also confused about how to turn this list_of_scenes into an object that could be viewed. After all, HGroup and VGroup don't take lists! I was missing that * could be used to unpack the list.
Steps:
1. init class instance
foo=Foo()
add scenes as you like
foo.add_trait(string_scene_name,scene)
foo.scene_name_list.append(string_scene_name)
foo.scene_list.append(scene)
Create group within default_traits_view()
items=[Item(name,style='custom') for name in self. scene_name_list]
scene_group=Group( *items)
I have some code for solving a puzzle game called nurikabe, recently I've been rewriting it to OOP (still learning) and have the following structure:
# CNurikabe.py
from includes import Board, Validation, Heuristics
class CNurikabe(object):
...
# CValidation.py
from includes import Board, Heuristics
class CValidation(object):
...
# CHeuristics.py
from includes import Board
class CHeuristics(object):
...
# CBoard.py
class CBoard(object):
def __init__(self, filename):
# Vars shared by every class
self.x, self.y, self.z, self.t = self.parseData(filename)
# run.py
from CNurikabe import CNurikabe
nurikabe = CNurikabe()
nurikabe.solve('output')
# includes.py
from CBoard import CBoard
Board = CBoard('data.dat')
from CHeuristics import CHeuristics
Heuristics = CHeuristics()
from CValidation import CValidation
Validation = CValidation()
CBoard class has info which has to be shared among all the other classes (such as board dimensions, number coordinates, etc), also I want it to be instantiated once, if possible preventing dependency injection (unnecessarily passing the filename to each class init method, for example)
The classes are needed to access the following:
CValidation class use: CBoard and CHeuristics
CHeuristics class use: CBoard
CNurikabe class use: CBoard, CValidation and CHeuristics
The code I have, works just as expected. I can call other class' methods within the other classes just the way I want it, for example:
# CNurikabe.py:
class CNurikabe(object):
def someFunc(self):
for i in range(Board.dimensionx):
Heuristics.doSomeStuff()
Validation.doSomeMore()
But I've read maybe too much about how globals are evil. Also the code inside includes.py is a bit hackish, because if I change the order of the imports the program won't run, complaining about being unable to import some names.
I also tried another way, only instantiating globally the CBoard class and then, for the other classes, creating an instance of the classes I need. But I felt that was kinda repetitive, creating an unique global instance of CHeuristics inside each class, for example, and that still wouldn't solve the CBoard global problem.
I also thought about creating an instance inside each class's init, but then the code would be very verbose, having to call for example: self.Heuristics.doSomeStuff()
So my question is what would be a better approach to structure this? I've read about singleton patterns (which may be overkill, since it's a small project), and endless ways of doing it for multiple languages like C++ and PHP. Actually The way I'm doing it resembles that of the "extern Class instance;" way of doing it in C++, long time ago I was working on a C++ project that had that style and I liked it, didn't see any problems with it, although the class instances were global.
Globals are evil. However, you probably need a singleton pattern that encapsulate some things together. My experience from C++ and Python is that you can nicely use the hybrid character of the language and use a module in the role of singleton. (If you think more about it, module variables play the role of a singleton member variables, plain functions in the module resemble methods of a singleton.)
This way I suggest to put the board functionality into board.py heuristic functionality into heuristic.py,..., convert the methods to functions, self.variable to variable and use:
import board
import heuristic
import validation
...
class CNurikabe: # the explicit (object) base class is not needed in Python 3
def someFunc(self):
for i in range(board.dimensionx):
heuristics.doSomeStuff()
validation.doSomeMore()
Think about the import board as about getting the reference to the singleton instance -- which actually is, because there is a single instance of the module object. And it will be syntactically the same as your older code -- except getting the instance (the module) will be easier.
Update: Once you need more instances, you should think in classes again. However, passing objects is very cheap operation in Python -- you only copy reference values (technically the address, i.e. 4 or 8 bytes). Once you get the reference value, you can easily assign it to a local variable. (Every assignment in Python means copying the reference value, hence sharing the access to the assigned object. This way, there is actually no need for global variables, and no excuse to use global variables.
Using local variables, the syntax again remains the same.
I want to build a simple 'rake' style command line tool that will allow me to define tasks in scala (that can optionally take additional command line arguments) that will be automatically loaded and accessible through a single main() method, to provide a single point of entry and minimize generating lots of wrapper scripts.
An example of what I'm looking for is Jersey, which will automatically load all annotated classes in a specified package and create REST endpoints. What's the right way to do this in scala? Basically, I just want to end up with a collection of instances of every class in a
package with a given annotation (which all have a Task trait or are a subclass of Trait, etc.)