Python, correct approach for instancing classes once and using them within other classes - class

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.

Related

Common variables for all subsystems in OpenMDAO

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.

Calling functions in a nested package

I'm trying out organising my matlab code into packages, but having to use fully qualified names in nested package functions is killing me.
Say I have a package called +myPack that looks like this:
+myPack
bar.m
baz.m
The bar function might look like
function bar()
myPack.baz()
end
This is all fine and logical. However, +myPack is a componant that will be reused in multiple other packages. Lets say one looks like this:
+mySuperPack
foo.m
+myPack
bar.m
baz.m
This time, foo calls bar, which in turn calls baz. However, the original code for bar will fail because I have not used the fully qualified name
mySuperPack.myPack.baz()
Obviously +myPack doesn't know which super pack it is in, so I can't do that.
This also stops you from being able to use static methods in classes that are in packages; the class has to know which package it is in to call its own static methods, which seems crazy.
Is there any way to use nested packages like this, or am I doing packages totally wrong?
Instead of writing
mySuperPack.myPack.baz()
you can write
import mySuperPack.myPack.*
baz()
You only need to write the import statement once. Unfortunately (and this is one of the few things that really bugs me with MATLAB) import only imports into the current workspace, so you need to write it once per function/method.
I really wish you could just write it once at the top of a file, and have it import into all functions in the file, or at the top of a class and have it import into all methods of the class, but there you go. At least it's better than always needing fully qualified names everywhere.
PS on the issue of static methods: although you might typically call them as ClassName.staticMethodName, or pkgName.ClassName.staticMethodName, if you have an object obj of that class, you can also call it using obj.staticMethodName. Obviously that's not always relevant, but if you're calling a static method from within a normal method it can be convenient, as you don't need to mention (or import) the package.

How to create a scala class based on user input?

I have a use case where I need to create a class based on user input.
For example, the user input could be : "(Int,fieldname1) : (String,fieldname2) : .. etc"
Then a class has to be created as follows at runtime
Class Some
{
Int fieldname1
String fieldname2
..so..on..
}
Is this something that Scala supports? Any help is really appreciated.
Your scenario doesn't seem to make sense. It's not so much an issue of runtime instantiation (the JVM can certainly do this with reflection). Really, what you're asking is to dynamically generate a class, which is only useful if your code makes use of it later on. But how can your code make use of it later on if you don't know what it looks like? For example, how would your later code know which fields it could reference?
No, not really.
The idea of a class is to define a type that can be checked at compile time. You see, creating it at runtime would somewhat contradict that.
You might want to store the user input in a different way, e.g. a map.
What are you trying to achieve by creating a class at runtime?
I think this makes sense, as long as you are using your "data model" in a generic manner.
Will this approach work here? Depends.
If your data coming from a file that is read at runtime but available at compile time, then you're in luck and type-safety will be maintained. In fact, you will have two options.
Split your project into two:
In the first run, read the file and write the new source
programmatically (as Strings, or better, with Treehugger).
In the second run, compile your generated class with the rest of your project and use it normally.
If #1 is too "manual", then use Macro Annotations. The idea here is that the main sub-project's compile time follows the macro sub-project's runtime. Therefore, if we provide the main sub-project with an "empty" class, members can be added to it dynamically at compile time using data that the macro sees at runtime. - To get started, Modify the macro to read from a file in this example
Else, if you're data are truly only knowable at runtime, then #Rob Starling's suggestion may work for you as it did me. I'll share my attempt if you want to be a guinea pig. For debugging, I've got an App.scala in there that shows how to pass strings to a runtime class generator and access it at runtime with Java reflection, even define a Scala type alias with it. So the question is, will your new dynamic class serve as a type-parameter in Slick, or fail to, as it sometimes does with other libraries?

How to convert a directory into a package?

I have a directory with some helper functions that should be put into a package. Step one is obviously naming the directory something like +mypackage\ so I can call functions with mypackage.somefunction. The problem is, some functions depend on one another, and apparently MATLAB requires package functions to call functions in the very same package still by explicitly stating the package name, so I'd have to rewrite all function calls. Even worse, should I decide to rename the package, all function calls would have to be rewritten as well. These functions don't even work correctly anymore when I cd into the directory as soon as its name starts with a +.
Is there an easier solution than rewriting a lot? Or at least something self-referential like import this.* to facilitate future package renaming?
edit I noticed the same goes for classes and static methods, which is why I put the self-referential part into this separate question.
In truth, I don't know that you should really be renaming your packages often. It seems to me that the whole idea behind a package in MATLAB is to organize a set of related functions and classes into a single collection that you could easily use or distribute as a "toolbox" without having to worry about name collisions.
As such, placing functions and classes into packages is like a final step that you perform to make a nice polished collection of tools, so you really shouldn't have much reason to rename your packages. Furthermore, you should only have to go through once prepending the package name to package function calls.
... (pausing to think if what I'm about to suggest is a good idea ;) ) ...
However, if you really want to avoid having to go through your package and prepend your function calls with a new package name, one approach would be to use the function mfilename to get the full file path for the currently running package function, parse the path string to find the parent package directories (which start with "+"), then pass the result to the import function to import the parent packages. You could even place these steps in a separate function packagename (requiring that you also use the function evalin):
function name = packagename
% Get full path of calling function:
callerPath = evalin('caller', 'mfilename(''fullpath'')');
% Parse the path string to get package directories:
name = regexp(callerPath, '\+(\w)+', 'tokens');
% Format the output:
name = strcat([name{:}], [repmat({'.'}, 1, numel(name)-1) {''}]);
name = [name{:}];
end
And you could then place this at the very beginning of your package functions to automatically have them include their parent package namespace:
import([packagename '.*']);
Is this a good idea? Well, I'm not sure what the computational impacts will be if you're doing this every time you call a package function. Also, if you have packages nested within packages you will get output from packagename that looks like this:
'mainpack.subpack.subsubpack'
And the call to import will only include the immediate parent package subsubpack. If you also want to include the other parent packages, you would have to sequentially remove the last package from the above string and import the remainder of the string.
In short, this isn't a very clean solution, but it is possible to make your package a little easier to rename in this way. However, I would still suggest that it's better to view the creation of a package as a final step in the process of creating a core set of tools, in which case renaming should be an unlikely scenario and prepending package function calls with the package name would only have to be done once.
I have been exploring answers to the same question and I have found that combining package with private folders can allow most or all of the code to be used without modification.
Say you have
+mypackage\intfc1.m
+mypackage\intfc2.m
+mypackage\private\foo1.m
+mypackage\private\foo2.m
+mypackage\private\foo3.m
Then from intfc1, foo1, foo2, and foo3 are all reachable without any package qualifiers or import statements, and foo1, foo2, and foo3 can also call each other without any package qualifiers or import statements. If foo1, foo2, or foo3 needs to call intfc1 or intfc2, then that needs qualification as mypackage.intfc1 or an import statement.
In the case that you have a large set of mutually interdependent functions and a small number of entry points, this reduces the burden of adding qualifiers or import statements.
To go even further, you could create new wrapper functions at the package level with the same name as private functions
+mypackage\foo1.m <--- new interface layer wraps private foo1
+mypackage\private\foo1.m <--- original function
where for example +mypackage\foo1.m might be:
function answer = foo1(some_parameter)
answer = foo1(some_parameter); % calls private function, not itself
end
This way, unlike the intfc1 example above, all the private code can run without modification. In particular there is no need for package qualifiers when calling any other function, regardless of whether it is exposed by a wrapper at the package level.
With this configuration, all functions including the package-level wrappers are oblivious of the package name, so renaming the package is nothing more than renaming the folder.

How does Import and Export work at Runtime in MEF?

I am starting to learn, MEF and one important thing in it is that I can mark some item (class, propety,method) with Export attribute so that, who ever wants use it will create Import attribute on an instance varaible and use it. How does this mapping happen and when does it happen? Is the import happen lazily on demand or all the composition happen at the start up? Sorry for the ignorant question, I am trying to understand the flow.
It happens in a phase called "Composition". First you create a container and load all your possible sources of parts into it, and then you Compose it. When you do the composition, it resolves all the dependencies and throws an exception if it can't resolve them all properly.
In general, your parts get instantiated during composition (and if you set a break point in the constructor of your part classes, you will see the break point hit during your call to Compose()). However, you can override this in a straightforward way if you use Lazy<T> as the type of your import (assuming you exported your part as type T).
To see how the composition works, take a look at the Compose() method here.