Passing an empty set to a function with type const std::set<std::string>& my_set_that_can_be_empty - c++

I'm trying to pass a set of strings to a c++ function. That works fine. However, in some cases the set is empty and I get a type error.
It may be that this is a c++ problem or it may also be that it is connected that I call the function fro python via pybind11.
Any suggestions on how this can be elegantly solved are highly appreciated.
I have posted an example here:
https://github.com/dickreuter/neuron_poker/blob/master/tests/test_montecarlo_cpp.py#L44
def test_montecarlo4():
"""Montecarlo test"""
my_cards = {'AS', 'KS'}
cards_on_table = {}
expected_results = 66.1 + 1.6
players = 2
_runner(my_cards, cards_on_table, players, expected_results)
def _runner(my_cards, cards_on_table, players, expected_result):
"""Montecarlo test"""
# if len(cards_on_table) < 3:
# cards_on_table = {'null'}
equity = calculator.montecarlo(my_cards, cards_on_table, players, 5000)
assert equity == pytest.approx(expected_result, abs=1)
calling
https://github.com/dickreuter/neuron_poker/blob/master/tools/Montecarlo.cpp#L266
double montecarlo(const std::set<std::string>& my_cards, const std::set<std::string>& cards_on_table, const int number_of_players, const int iterations) {
resulting in:
E TypeError: montecarlo(): incompatible function arguments. The following argument types are supported:
E 1. (arg0: Set[str], arg1: Set[str], arg2: int, arg3: int) -> float

Related

Why do I get an error when building a zero coupon inflation swap helper in Quantlib?

I am trying to create a ZC Inflation Swap Helper but I get an error for the below code, does anyone know what the issue is?
import QuantLib as ql
quote = ql.QuoteHandle(ql.SimpleQuote(0.02))
period = ql.Period('3M')
date = ql.Date(15,3,2022)
calendar = ql.TARGET()
convention = ql.ModifiedFollowing
daycounter = ql.Actual360()
index = ql.EUHICPXT(True)
helper = ql.ZeroCouponInflationSwapHelper(quote, period, date, calendar, convention, daycounter, index)
{TypeError}Wrong number or type of arguments for overloaded function 'new_ZeroCouponInflationSwapHelper'.
Possible C/C++ prototypes are:
ZeroCouponInflationSwapHelper::ZeroCouponInflationSwapHelper(Handle< Quote > const &,Period const &,Date const &,Calendar const &,BusinessDayConvention,DayCounter const &,ext::shared_ptr< ZeroInflationIndex > const &,CPI::InterpolationType,Handle< YieldTermStructure > const &)
ZeroCouponInflationSwapHelper::ZeroCouponInflationSwapHelper(Handle< Quote > const &,Period const &,Date const &,Calendar const &,BusinessDayConvention,DayCounter const &,ext::shared_ptr< ZeroInflationIndex > const &,Handle< YieldTermStructure > const &)
This is the same code as the QuantLib userguide...
Posted the issue on Github ... looks like documentation hasn't been updated since the last QuantLib update.
https://github.com/lballabio/QuantLib/issues/1360
The following should work:
import QuantLib as ql
quote = ql.QuoteHandle(ql.SimpleQuote(0.02))
period = ql.Period('6M')
date = ql.Date(15,6,2020)
calendar = ql.TARGET()
convention = ql.ModifiedFollowing
daycounter = ql.Actual360()
index = ql.EUHICPXT(True)
flatForward = ql.FlatForward(ql.Date(15,6,2020), ql.QuoteHandle(ql.SimpleQuote(0.05)), ql.Actual360())
yieldTermStructure = ql.YieldTermStructureHandle(flatForward)
helper = ql.ZeroCouponInflationSwapHelper(quote, period, date, calendar, convention, daycounter, index, yieldTermStructure)

IDA How to set variables type with name which have angle brackets in local types name?

IDA local types has a local type like:
struct DEMOTYPE<int>
{
_DWORD dw1;
_DWORD dw2;
}
how to use "DEMOTYPE"(C++ type) just like normal c type? press Y can not Can't achieve the goal since the "<>" in it.
i know if the target is function,we can change the function declaration with its mangled name.
In a word, how can we use the c++ type declaration in the local types to change the type of the local variable?
Below is the code I tried, but the F5 pseudocode view cannot be changed.
def setVarType(lvname, lti, isptr=False):
addr = idc.here()
c = idaapi.decompile(addr)
for v in c.lvars:
if v.name == lvname:
print("find target variable:", v.name)
idati = ida_typeinf.get_idati()
ti = ida_typeinf.tinfo_t()
if ti.get_numbered_type(idati, lti):
print("find local type:", lti, ":", ti)
if isptr:
ti_ptr = ida_typeinf.tinfo_t()
ti_ptr.create_ptr(ti) # ti_ptr = ti *
bret = v.set_final_lvar_type(ti_ptr)
else:
bret = v.set_final_lvar_type(ti)
print(bret)
This should work, though only for local variables (not for function arguments).
Typical usage: set_lvar_name_type(here(), 'v1', None, 'rage::atArray<int>')
def set_lvar_name_type(ea, src, name, t, vu=None):
"""
Change the name or type of a local variable
#param ea: address of function
#param src: current name of variable
#param name: new name (or None to leave as is)
#param t: new type (str, tinfo_t, or None to leave as is)
#param v: handle to existing pseudocode window (vdui_t, or None)
#note
Will not work with function arguments or global variables
"""
# m = [ea for ea in [pprev(ea, 1) for ea in l if GetFuncName(ea)] if ea]
def get_tinfo_elegant(name):
ti = ida_typeinf.tinfo_t()
til = ti.get_til()
# get_named_type(self, til, name, decl_type=BTF_TYPEDEF, resolve=True, try_ordinal=True)
if ti.get_named_type(til, name, ida_typeinf.BTF_STRUCT, True, True):
return ti
return None
def get_pseudocode_vu(ea, vu=None):
func = idaapi.get_func(ea)
if func:
return idaapi.open_pseudocode(func.start_ea, 0)
if isinstance(t, str):
tif = get_tinfo_elegant(t)
if not tif:
raise ValueError("Couldn't get tinfo_t for type '{}'".format(t))
t = tif
elif isinstance(t, ida_typeinf.tinfo_t) or t is None:
pass
else:
raise TypeError("Unknown type for t '{}'".format(type(t)))
vu = get_pseudocode_vu(ea, vu)
if vu:
lvars = [n for n in vu.cfunc.lvars if n.name == src]
if len(lvars) == 1:
print("changing name/type of {}/{} to {}/{}".format(lvars[0].name, lvars[0].type(), name, str(t)))
if t:
vu.set_lvar_type(lvars[0], t)
if name:
vu.rename_lvar(lvars[0], name, 1)
else:
print("[set_lvar_name_type] couldn't find var {}".format(src))
return False

Read a list of parameters from a LuaRef using LuaBridge

[RESOLVED]
I'm building a game engine that uses LuaBridge in order to read components for entities. In my engine, an entity file looks like this, where "Components" is a list of the components that my entity has and the rest of parameters are used to setup the values for each individual component:
-- myEntity.lua
Components = {"MeshRenderer", "Transform", "Rigidbody"}
MeshRenderer = {
Type = "Sphere",
Position = {0,300,0}
}
Transform = {
Position = {0,150,0},
Scale = {1,1,1},
Rotation = {0,0,0}
}
Rigidbody = {
Type = "Sphere",
Mass = 1
}
I'm currently using this function (in C++) in order to read the value from a parameter (given its name) inside a LuaRef.
template<class T>
T readParameter(LuaRef& table, const std::string& parameterName)
{
try {
return table.rawget(parameterName).cast<T>();
}
catch (std::exception e) {
// std::cout ...
return NULL;
}
}
For example, when calling readVariable<std::string>(myRigidbodyTable, "Type"), with myRigidbodyTable being a LuaRef with the values of Rigidbody, this function should return an std::string with the value "Sphere".
My problem is that when I finish reading and storing the values of my Transform component, when I want to read the values for "Ridigbody" and my engine reads the value "Type", an unhandled exception is thrown at Stack::push(lua_State* L, const std::string& str, std::error_code&).
I am pretty sure that this has to do with the fact that my component Transform stores a list of values for parameters like "Position", because I've had no problems while reading components that only had a single value for each parameter. What's the right way to do this, in case I am doing something wrong?
I'd also like to point out that I am new to LuaBridge, so this might be a beginner problem with a solution that I've been unable to find. Any help is appreciated :)
Found the problem, I wasn't reading the table properly. Instead of
LuaRef myTable = getGlobal(state, tableName.c_str());
I was using the following
LuaRef myTable = getGlobal(state, tableName.c_str()).getMetatable();

Assign randomly chosen, but matching parameters for connected OMNeT++ gates?

I'm developing a network model in OMNeT++ in which I have introduced a custom channel type to represent links in my network. For one property of this channel type's instances, I'd like to assign a random parameter. However, the random number should be the same for connected gates.
My node definition has the following gates definition:
simple GridAgent
{
/* ... other paramters/definitions omitted ... */
gates:
inout agentConnections[];
}
In my network configuration, I connect nodes using the simple <--> syntax, e.g.:
someSwitchyard.agentConnections++ <--> AgentConnectionChannel <--> someWindfarm.agentConnections++;
Now, this AgentConnectionChannel has a property called impedance, which I'd like to randomly assign. This impedance property should be the same for both A -> B and B -> A. I have tried to add { impedance = default(unitform(1, 10)) } to the network definition, as well as putting **.agentConnections$o[*].channel.impedance = uniform(1, 10) into omnetpp.ini. In both cases, however, A -> B has a different value assigned than B -> A.
As indicated on the OMNet++ mailing list, this happens because the <--> syntax is actually a shorthand for creating two distinct connections, hence two drawings from the random number distribution happen.
How can I assign a random parameter to a connection's property and have the same value for both directions of two connected gates? Is there a way to do this in the omnetpp.ini file, or do I need to create a script in, e.g., Perl, Ruby, or Python to generate the omnetpp.ini for my runs?
There is no simple solution of your problem, and it could not be resolved manipulating omnetpp.ini file merely.
I propose manual rewriting a parameter value for the second direction. It requires preparing a C++ class for a channel (which you have probably done).
Assuming that your channel definition in NED is following:
channel AgentConnectionChannel extends ned.DatarateChannel {
#class(AgentConnectionChannel);
double impedance;
}
and in omnetpp.ini you has:
**.agentConnections$o[*].channel.impedance = uniform(1, 10)
you should prepare C++ class AgentConnectionChannel:
class AgentConnectionChannel: public cDatarateChannel {
public:
AgentConnectionChannel() : parAlreadyRewritten(false) {}
void setParAlreadyRewritten() {parAlreadyRewritten=true;}
protected:
virtual void initialize();
private:
bool parAlreadyRewritten;
private:
double impedance;
};
Define_Channel(AgentConnectionChannel);
void AgentConnectionChannel::initialize() {
if (parAlreadyRewritten == false) {
parAlreadyRewritten = true;
cGate * srcOut = this->getSourceGate();
cModule *owner = srcOut->getOwnerModule();
int index = srcOut->isVector() ? srcOut->getIndex() : -1;
cGate *srcIn = owner->gateHalf(srcOut->getBaseName(), cGate::INPUT,
index);
cChannel * channel = srcIn->findIncomingTransmissionChannel();
AgentConnectionChannel * reverseChan =
dynamic_cast<AgentConnectionChannel*>(channel);
if (reverseChan) {
reverseChan->setParAlreadyRewritten();
// assigning a value from forward direction channel
reverseChan->par("impedance") = this->par("impedance");
}
}
// and now read a parameter as usual
impedance = par("impedance").doubleValue();
EV << getFullPath() << ", impedance=" << impedance << endl;
}

Change value of parameter in NSubstitute

I have this method to mock with NSubstitute:
public T VoerStoredProcedureUit<T>(string naam, params SqlParameter[] parameters)
The test method using it sends 2 SqlParameters to this method. VoerStoredProcedureUit is supposed to change the values of these parameters so the tested method can extract that.
I created the following with NSubstitute:
SqlParameter[] param =
{
new SqlParameter("#pat_id", SqlDbType.BigInt) {Direction = ParameterDirection.Output, Value = "Melding"},
new SqlParameter("#Melding", SqlDbType.VarChar, 4096) {Direction = ParameterDirection.Output, Value = 2}
};
productieVerbinding.VoerStoredProcedureUit<PatientNieuwResultaat>(Arg.Any<string>(),
Arg.Any<SqlParameter[]>()).ReturnsForAnyArgs(x =>
{
x[1] = param;
return PatientNieuwResultaat.Succes;
});
The setup however rises an exception:
A first chance exception of type 'NSubstitute.Exceptions.ArgumentIsNotOutOrRefException' occurred in NSubstitute.dll
Additional information: Could not set argument 1 (SqlParameter[]) as it is not an out or ref argument.
How do you return a value if the method uses implicitly by reference values?
If I understand your question correctly, you're trying to return the contents of param when VoerStoredProcedureUit<PatientNieuwResultaat> is called.
In ReturnsForAnyArgs, x[1] refers to the second parameter which is an SqlParameter[]. This isn't a ref/out parameter so you can't reassign it in the caller, which is why you get an error. Instead, you need to copy the elements from your template, into the supplied array. Something like this:
productieVerbinding.VoerStoredProcedureUit<PatientNieuwResultaat>(Arg.Any<string>(),
Arg.Any<SqlParameter[]>()).ReturnsForAnyArgs((x) =>
{
for (int i = 0; i < param.Length; i++)
{
((SqlParameter[])x[1])[i] = param[i];
}
return PatientNieuwResultaat.Succes;
});
You could obviously remove the for loop, since you know how many parameters you need to copy...
productieVerbinding.VoerStoredProcedureUit<PatientNieuwResultaat>(Arg.Any<string>(),
Arg.Any<SqlParameter[]>()).ReturnsForAnyArgs((x) =>
{
((SqlParameter[])x[1])[0] = param[0];
((SqlParameter[])x[1])[1] = param[1];
return PatientNieuwResultaat.Succes;
});
I found a working solution. Assigning a new variable to the parameters did't work somehow, but changing them does. Also, the second of the method parameter is an array, so it should be treated as such.
productieVerbinding.VoerStoredProcedureUit<PatientNieuwResultaat>(Arg.Any<string>(),
Arg.Any<SqlParameter[]>()).ReturnsForAnyArgs(x =>
{
paramPatId = ((SqlParameter[])x[1])[0];
paramMelding = ((SqlParameter[])x[1])[1];
paramPatId.Value = (long)2;
paramMelding.Value = "Melding";
return PatientNieuwResultaat.Succes;
});