create a new method in Brightway 2 - brightway

This question is very similar to the one raised here. Is just that I cannot make work the proposed solution (and I don't have the reputation to add comments).
I want to create a method with just the global warming potential of CO2,CH4 and N2O associated with fossil fuel combustion.
looking into biosphere database, I created a list of tuples with the flow's keys and characterization factors:
flows_list=[]
for flow in bw.Database('biosphere3'):
if 'Carbon dioxide, fossil' in flow['name']:
flows_list.append((flow.key,1.0))
if flow['name']=='Methane':
flows_list.append((flow.key,29.7))
if flow['name']=='Dinitrogen monoxide':
flows_list.append((flow.key,264.8))
and then:
ipcc2013_onlyfossil=bw.Method(('IPCC2013_onlyfossil','climate change','GWP100a'))
ipcc2013_onlyfossil.register(**{'unit':'kg CO2eq',
'num_cfs':11,
'abbreviation':'nonexistent',
'description':'based on IPCC 2013 method but just for fossil CO2, CH4 and N2O',
'filename':'nonexistent'})
(I don't understand the purpose of the double ** or if we can leave keys in the dictionary metadata empty)
lastly:
ipcc2013_onlyfossil.write(flows_list)
I must be doing something wrong, because If I try to use this method I get an assertion error, Brightway can't find the model.
UPDATE: There was a error in my code, the new method works perfectly fine.
For instance, If I run:
[m for m in bw.methods if 'IPCC' in m[0]
and 'GWP100' in str(m)]
I get at list of methods, including the one I attempted to create and I can do LCA calculations with it.
(PS: it is not very clear to me how I should use the validate() method of the method class..)

There are a bunch of questions here...
How do I create and write a new method?
Your code works perfectly on my computer, and it should - it's doing the same thing that the base methods importer does. Maybe you can be more explicit on what "If I try to use this method I get an assertion error" means?
After running your code, you should be able to do ipcc2013_onlyfossil.metadata or ipcc2013_onlyfossil.load(). It is there!
How should I use the validate() function?
If you ask for the docstring in IPython, you get an idea:
> m.validate?
Signature: m.validate(data)
Docstring: Validate data. Must be called manually.
So you can do ipcc2013_onlyfossil.validate(flows_list), but you don't need to: your code is fine.
What metadata should I provide to Method.register()?
No metadata is required, and you should skip anything you don't know. abbreviation and 'num_cfs' are generated automatically.
What does ** mean?
Good answers already exist

Related

NUnit Attribute to simulate condition-based Assert.Inconclusive with custom message text

I have some tests that depend on a certain thing being true (access to the internet, as it happens, but that isn't important and I don't want to discuss the details of the condition).
I can very easily write a static helper method which will test the (parameterless) condition and call Assert.Inconclusive("Explanatory Message") if it's true/false. And then call that at the start of each Test which has this requirement.
But I'd like to do this as an Attribute, if possible.
How, in detail, do I achieve that, in NUnit?
What I've tried so far:
There's an IApplyToTest interface, exposed by NUnit, which I can make my Attribute implement, and will allow me to hook into the TestRunner, but I can't get it to do what I want :(
That interface gives me access to an NUnit.Framework.Internal.Test object.
If I call:
test.RunState = RunState.NotRunnable;
then I get something equivalent to Assert.Fail("").
Similarly RunState.Skipped or RunState.Ignored give me the equivalent of Assert.Ignore("").
But none of these are setting a message on the Test, and there's no test.Message = "foo"; or equivalent (that I can see).
There's a test.MakeInvalid("Foo") which does set a message, but that's equivalent to Assert.Fail("Foo").
I found something that looked promising:
var result = test.MakeTestResult();
result.SetResult(ResultState.Inconclusive, "Custom Message text");
But that doesn't seem to do anything; the Test just Passes :( I looked for a test.SetAsCurrentResult(result) method in case I need to "attach" that result object back to the test? But nothing doing.
It feels like this is supposed to be possible, but I can't quite figure out how to make it all play together.
If anyone can even show me how to get to Skipped + Custom Message displayed, then I'd probably take that!
If you really want your test to be Inconclusive, then that's what Assume.That is there for. Use it just as you would use Assert.That and the specified constraint fails, your test result will be inconclusive.
That would be the simplest answer to your question.
However, reading the things you have tried, I don't think you actually want Inconclusive at least not as it is defined by NUnit.
In NUnit, Inconclusive means that the test doesn't count because it couldn't be run. The result basically disappears and the test run is successful.
You seem to be saying that you want to receive some notice that the condition failed. That makes sense in the situation where (for example) the internet was not available so your test run isn't definitive.
NUnit provides Assert.Ignore and Warn.If (also Warn.Unless) for those situations. Or you can set the corresponding result states in your custom attribute.
Regarding implementation... The RunState of a test applies to it's status before anyone has even tried to execute it. So, for example, the RunState may be Ignored if someone has used the IgnoreAttribute or it may be NotRunnable if it requires arguments and none are provided. There is no Inconclusive run sttate because that would mean the test is written to be inconclusive all the time, which makes no ssense. The IApplyToTest interface allows an attribute to change the status of a test at the point of discovery, before it is even run, so you would not want to use that.
After NUnit has attempted to run a test, it gets a ResultState, which might be Inconclusive. You can affect this in the code of the test but not currently through an attribute. What you want here is something that checks the conditions needed to run the test immediately before running it and skips execution if the conditions are not met. That attribute would need to be one that generates a command in the chain of commands that execute a test. It would probably need to implement ICommandWrapper to do that, which is a bit more complicated than IApplyToTest because the attribute code must generate a command instance that will work properly with NUnit itself and with other commands in the chain.
If I had this situation, I believe I would use a Run parameter to indicate whether the internet should be available. Then, the tests could
Assume.That(InternetIsNotNeeded());
silently ignoring those tests or fail as expected when the internet should be available.

Any reason Origen::Parameter set contexts are hidden from the user?

Is there any reason the Origen::Parameters sets do not have a public method for retrieving all of the possible set ids? I do see a public method that works, though it isn't named like it is meant to be used publicly. Why is this not more visible?
[6] pry(#<PPEKit::Product>)> $dut.func._parameter_sets.ids
=> [:default,
:func_default,
:func_harvest_default,
EDIT
#Ginty, I tried your suggestion but it doesn't return the keys I am looking for. In the first sentence in the Parameter docs, the keys I am looking for are referred to 'parameter contexts'. The reason these would be useful would be to do something like this:
my_param_key = :my_param_key
if Origen.top_level.func.has_context? my_param_key
...
Specifically, I am creating parameter contexts from the information in my flow file and would like to verify that they exist before trying to access them. Essentially it is a handshake between my test flow and the test method parameters I am storing using unique (hopefully) parameter IDs/contexts.
thx
In your example, dut.func.params should return a hash-like object which contains all the parameter sets, so to get the IDs is just: dut.func.params.keys
EDIT
I see now that you want a collection containing the available contexts, but it doesn't seem like that is currently provided via an API.
I don't think there is any particular reason for that, probably hasn't been needed until now.
params.context returns the currently active context, I would recommend we add params.contexts and/or params.available_contexts to return an array of the available context names.
Origen now supports knowing the available parameter contexts.

How to mock an array of interfaces using powermock or mockito

I am mocking an interface array which throws java.lang.IllegalArgumentException: Cannot subclass final class class.
Following are the changes I did.
Added the following annotations at class level in this exact order:
#Runwith(PowerMockRunner.class)
#PrepareForTest({ Array1[].class, Array2[].class })
Inside the class I am doing like this:
Array1[] test1= PowerMockito.mock(Array1[].class);
Array2[] test2= PowerMockito.mock(Array2[].class);
and inside test method:
Mockito.when(staticclass.somemethod()).thenReturn(test1);
Mockito.when(staticclass.somediffmethod()).thenReturn(test2);
Basically I need to mock an array of interfaces.
Any help would be appreciated.
Opening up another perspective on your problem: I think you are getting unit tests wrong.
You only use mocking frameworks in order to control the behavior of individual objects that you provide to your code under test. But there is no sense in mocking an array of something.
When your "class under test" needs to deal with some array, list, map, whatever, then you provide an array, a list, or a map to it - you just make sure that the elements within that array/collection ... are as you need them. Maybe the array is empty for one test, maybe it contains a null for another test, and maybe it contains a mocked object for a third test.
Meaning - you don't do:
SomeInterface[] test1 = PowerMock.mock() ...
Instead you do:
SomeInterface[] test1 = new SomeInterface[] { PowerMock.mock(SomeInterface.class) };
And allow for some notes:
At least in your code, it looks like you called your interface "Array1" and "Array2". That is highly misleading. Give interfaces names that say what their behavior is about. The fact that you later create arrays containing objects of that interface ... doesn't matter at all!
Unless you have good reasons - consider not using PowerMock. PowerMock relies on byte-code manipulation; and can simply cause a lot of problems. In most situations, people wrote untestable code; and then they turn to PowerMock to somehow test that. But the correct answer is to rework that broken design, and to use a mocking framework that comes without "power" in its name. You can watch those videos giving you lengthy explanations how to write testable code!

cucumber: string to an active record model name

I'm trying to do a DRY cucumber feature and I'm facing a problem of converting a string into an ActiveRecord model name
Given /^the following "(.+)" exist:/ do |mod, table|
table.hashes.each do |t|
mod.create!(t)
end
assert mod.all.count == table.hashes.size
end
that gives
undefined method `create!' for "Balloon":String (NoMethodError)
More elegant solution might be to use a factory, but I'm wondering whether it is possible to use the above approach?
You could look into constantize which turns a String into a constant. Try:
"Balloon".constantize.create!(t)
BUT: Using your app code (models in particular) in a Cucumber step is code smell. Your integration tests shouldn't rely on the code under test at all—think of your app as a black box when you implement Cucumber steps. (Also think of a refactoring of your models that require you to go back and change your Cucumber steps—that's your first clue that you're on the wrong track!)
What you could do to improve this is create the models using an API (if your app implements one).
That way, you only rely on those parts of your app that are public-facing.
On another note: Your Given shouldn't have an assertion, it's more like a before hook in RSpec, setting up a condition for a later assertion...

Kohana helper attribute

I have a question that keeps bothering me. Currently, I have started using Kohana 3.2 Framework. I've written a helper to handle some functionality - I have a number of methods, which are (as it should be) declared STATIC. But, all of these methods are somehow working with the database, so I need to load a model. Currently, every method has a non-static variable like this:
$comment = new Model_Comments;
$comment->addComment("abc");
OK, it seems to be working, but then I wanted to get rid of this redundancy by using class attribute to hold the instance of the model (with is class as well).
Something like this:
private static $comment; // Declaring attribute
self::$comment = new Model_Comment; // This is done within helper __constuct method
self::$comment->addComment("abc"); // And call it within the method.
But, I got failed with: Call to a member function addComment() on a non-object
Question is: is it possible to do it ? Maybe there are some other approaches ?
Sorry for a long story and, thanks in advice! :P
A static method cannot call a non-static method without operating on an instance of the class. So, what you're proposing won't work. There may be a way do accomplish something similar, but what about trying the following:
You could implement the singleton or factory pattern for your "helper" class. Then, you could create the model (as an attribute) as you instantiate/return the instance. With an actual instance of your "helper" class, you won't have to worry about the static scope issues.
In other words, you can create a helper-like class as a "normal" class in your application that, upon creation, always has the necessary model available.
I'd be happy to help further if this approach makes sense.
David

Resources