does boost python support a function returning a vector, by ref or value? - boost-python

I am new to python, I have looked at boost python, and it looks very
impressive. However going through the introduction I can not find
any examples where, vector of objects are returned as python list/tuples.
i.e Take this example, I want to expose class X, Cont and all its functions.
critical bit being return a vector of X's or strings to python
class X {};
class Cont {
.....
// how can this be exposed using boost python
const std::vector<X>& const_ref_x_vec() const { return x_vec_;}
std::vector<X> value_x_vec() const { return x_vec;}
const std::vector<std::string>& const_ref_str_vec() const { return str_vec_;}
std::vector<std::string> value_str_vec() const { return str_vec_; }
...
private:
std::vector<X> x_vec_;
std::vector<std::string> str_vec_;
};
My own fruitless attempt at trying to expose the functions like
const_ref_x_vec(), value_x_vec(),etc just leads to compile errors.
from googling around I have not seen any example that support returning vectors
by value or reference. Is this even possible with boost python?
are there any workarounds ? should I be using SWIG for this case ?
Any help appreciated.
Avtar

Autopulated's reason was essentially correct, but the code was more complicated then necessary.
The vector_indexing_suite can do all that work for you:
class_< std::vector<X> >("VectorOfX")
.def(vector_indexing_suite< std::vector<X> >() )
;
There is a map_indexing_suite as well.

Because you can't expose template types to python you have to explicitly expose each sort of vector that you want to use, for example this is from my code:
Generic template to wrap things:
namespace bp = boost::python;
inline void IndexError(){
PyErr_SetString(PyExc_IndexError, "Index out of range");
bp::throw_error_already_set();
}
template<class T>
struct vec_item{
typedef typename T::value_type V;
static V& get(T& x, int i){
static V nothing;
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) return x[i];
IndexError();
return nothing;
}
static void set(T& x, int i, V const& v){
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) x[i] = v;
else IndexError();
}
static void del(T& x, int i){
if(i < 0) i += x.size();
if(i >= 0 && i < int(x.size())) x.erase(x.begin() + i);
else IndexError();
}
static void add(T& x, V const& v){
x.push_back(v);
}
};
Then, for each container:
// STL Vectors:
// LineVec
bp::class_< std::vector< Line > >("LineVec")
.def("__len__", &std::vector< Line >::size)
.def("clear", &std::vector< Line >::clear)
.def("append", &vec_item< std::vector< Line > >::add,
bp::with_custodian_and_ward<1, 2>()) // let container keep value
.def("__getitem__", &vec_item< std::vector< Line > >::get,
bp::return_value_policy<bp::copy_non_const_reference>())
.def("__setitem__", &vec_item< std::vector< Line > >::set,
bp::with_custodian_and_ward<1,2>()) // to let container keep value
.def("__delitem__", &vec_item< std::vector< Line > >::del)
.def("__iter__", bp::iterator< std::vector< Line > >())
;
// ...
A similar approach is possible for std::map.
I used lots of help from wiki.python.org when writing this.

Related

Backtracking results in same repeating course

I am trying to solve a puzzle, and it has been suggested that I use backtracking - I did not know the term so did some investigation, and found the following in Wikipedia:
In order to apply backtracking to a specific class of problems, one must provide the data P for the particular instance of the problem that is to be solved, and six procedural parameters, root, reject, accept, first, next, and output. These procedures should take the instance data P as a parameter and should do the following:
root(P): return the partial candidate at the root of the search tree.
reject(P,c): return true only if the partial candidate c is not worth completing.
accept(P,c): return true if c is a solution of P, and false otherwise.
first(P,c): generate the first extension of candidate c.
next(P,s): generate the next alternative extension of a candidate, after the extension s.
output(P,c): use the solution c of P, as appropriate to the application.
The backtracking algorithm reduces the problem to the call backtrack(root(P)), where backtrack is the following recursive procedure:
procedure backtrack(c) is
if reject(P, c) then return
if accept(P, c) then output(P, c)
s ← first(P, c)
while s ≠ NULL do
backtrack(s)
s ← next(P, s)
I have attempted to use this method for my solution, but after the method finds a rejected candidate it just starts again and finds the same route, rather than the next possible one.
I now don't think I have used the next(P,s) correctly, because I don't really understand the wording 'after the extension s'.
I've tried 2 methods:
(a) in the first() function, generating all possible extensions, storing them in a list, then using the first. The next() function then uses the other extensions from the list in turn. But this maybe can't work because of the calls to backtrack() in between the calls to next().
(b) adding a counter to the data (i.e. the class that includes all the grid info) and incrementing this for each call of next(). But can't work out where to reset this counter to zero.
Here's the relevant bit of code for method (a):
private PotentialSolution tryFirstTrack(PotentialSolution ps)
{
possibleTracks = new List<PotentialSolution>();
for (Track trytrack = Track.Empty + 1; trytrack < Track.MaxVal; trytrack++)
{
if (validMove(ps.nextSide, trytrack))
{
ps.SetCell(trytrack);
possibleTracks.Add(ps);
}
}
return tryNextTrack(ps);
}
private PotentialSolution tryNextTrack(PotentialSolution ps)
{
if (possibleTracks.Count == 0)
{
ps.SetCell(Track.Empty);
return null;
}
ps = possibleTracks.First();
// don't use same one again
possibleTracks.Remove(ps);
return ps;
}
private bool backtrackTracks(PotentialSolution ps)
{
if (canExit)
{
return true;
}
if (checkOccupiedCells(ps))
{
ps = tryFirstTrack(ps);
while (ps != null)
{
// 'testCells' is a copy of the grid for use with graphics - no need to include graphics in the backtrack stack
testCells[ps.h, ps.w].DrawTrack(g, ps.GetCell());
if (ps.TestForExit(endColumn, ref canExit) != Track.MaxVal)
{
drawRowColTotals(ps);
return true;
}
ps.nextSide = findNextSide(ps.nextSide, ps.GetCell(), ref ps.h, ref ps.w);
if (ps.h >= 0 && ps.h < cellsPerSide && ps.w >= 0 && ps.w < cellsPerSide)
{
backtrackTracks(ps);
ps = tryNextTrack(ps);
}
else
return false;
}
return false;
}
return false;
}
and here's some code using random choices. This works fine, so I conclude that the methods checkOccupiedCells() and findNextSide() are working correctly.
private bool backtrackTracks(PotentialSolution ps)
{
if (canExit)
{
return true;
}
if (checkOccupiedCells(ps))
{
Track track = createRandomTrack(ps);
if (canExit)
return true;
if (track == Track.MaxVal)
return false;
ps.SetCell(track);
ps.nextSide = findNextSide(ps.nextSide, track, ref ps.h, ref ps.w);
if (ps.h >= 0 && ps.h < cellsPerSide && ps.w >= 0 && ps.w < cellsPerSide)
backtrackTracks(ps);
else
return false;
}
}
If it helps, there's more background info in the puzzle itself here

Bad address error when comparing Strings within BPF

I have an example program I am running here to see if the substring matches the string and then print them out. So far, I am having trouble running the program due to a bad address. I am wondering if there is a way to fix this problem? I have attached the entire code but my problem is mostly related to isSubstring.
#include <uapi/linux/bpf.h>
#define ARRAYSIZE 64
struct data_t {
char buf[ARRAYSIZE];
};
BPF_ARRAY(lookupTable, struct data_t, ARRAYSIZE);
//char name[20];
//find substring in a string
static bool isSubstring(struct data_t stringVal)
{
char substring[] = "New York";
int M = sizeof(substring);
int N = sizeof(stringVal.buf) - 1;
/* A loop to slide pat[] one by one */
for (int i = 0; i <= N - M; i++) {
int j;
/* For current index i, check for
pattern match */
for (j = 0; j < M; j++)
if (stringVal.buf[i + j] != substring[j])
break;
if (j == M)
return true;
}
return false;
}
int Test(void *ctx)
{
#pragma clang loop unroll(full)
for (int i = 0; i < ARRAYSIZE; i++) {
int k = i;
struct data_t *line = lookupTable.lookup(&k);
if (line) {
// bpf_trace_printk("%s\n", key->buf);
if (isSubstring(*line)) {
bpf_trace_printk("%s\n", line->buf);
}
}
}
return 0;
}
My python code here:
import ctypes
from bcc import BPF
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
string = contents[i].encode('utf-8')
print(len(string))
lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="Test")
b.trace_print()
Edit: Forgot to add the error: It's really long and can be found here: https://pastebin.com/a7E9L230
I think the most interesting part of the error is near the bottom where it mentions:
The sequence of 8193 jumps is too complex.
And a little bit farther down mentions: Bad Address.
The verifier checks all branches in your program. Each time it sees a jump instruction, it pushes the new branch to its “stack of branches to check”. This stack has a limit (BPF_COMPLEXITY_LIMIT_JMP_SEQ, currently 8192) that you are hitting, as the verifier tells you. “Bad Address” is just the translation of kernel's errno value which is set to -EFAULT in that case.
Not sure how to fix it though, you could try:
With smaller strings, or
On a 5.3+ kernel (which supports bounded loops): without unrolling the loop with clang (I don't know if it would help).

CS50 pset 3: Tideman sort_pairs function

I need some assistance in understanding the logic behind this function. This is my current sort_pairs function in Tideman:
// Sort pairs in decreasing order by the strength of victory
void sort_pairs(void)
{
qsort(pairs, pair_count, sizeof(pair), compare);
return;
}
// Function for sort_pairs
int compare(const void *a, const void *b)
{
const pair *p1 = (const pair *) a;
const pair *p2 = (const pair *) b;
if (p1->winner < p2->winner)
{
return -1;
}
else if (p1->winner > p2->winner)
{
return 1;
}
else
{
return 0;
}
}
This does not clear check50 and I looked online to find how to approach this problem. It seems that most functions compare the values from the preferences array instead (eg preferences[pairs[i].winner][pairs[i].loser]) . My previous functions vote, record_preferences, and add_pairs all clear check50. I have not advanced beyond sort_pairs yet.
Why can't I compare the strength of victory directly from the pairs array instead since I already have the data stored there?
You don't need to make this so complex, you can use your own sorting here. Let's try a simple insertion sort-
void sort_pairs()
{
pair temp;
for (int i = 1, j; i < pair_count; i++)
{
temp = pairs[i];
j = i - 1;
for (; j >= 0 && preferences[pairs[j].winner][pairs[j].loser] < preferences[temp.winner][temp.loser]; j--)
{
pairs[j + 1] = pairs[j];
}
pairs[j + 1] = temp;
}
}
The pair struct looks like-
typedef struct
{
int winner;
int loser;
}
pair;
Explanation:-
We go through each pair of elements inside the pairs array - starting at 1 since I'm going to compare with the previous element (j = i - 1)
Now we check all the previous elements from the current element and compare them with the key - preferences[pairs[INDEX].winner][pairs[INDEX].loser]
This is the key you should be sorting by. preferences[WINNER_ID][LOSER_ID] means the amount of people that prefer WINNER_ID over LOSER_ID.
And that's pretty much it!, it's simply a insertion sort but the key is the important part.

Linked List Parameterized constructor

I tried to do a Parameterized constructor for a linked list my program is about to implement a queue by using a liked list so i want to do a parameterized constructor like Queue(int value , int size) and it dose not run or doing a list
this is my code for this problem
Queue(int value,int _size)
{
for(int i = 0; i < _size; ++i)
{
Node* temp = new Node;
temp->data = value;
temp->next = nullptr;
if(head == nullptr)
{
head = tail = temp;
}
else
{
tail->next = temp;
tail = temp;
}
}
}
i expected that the result is to fill the lest by value times size like if i run this function Queue x(20,3) the linked list should be
20 20 20
Since that this is a constructor, The head and tail are not properly initialized to use them. I would suggest adding head = tail = nullptr just before the loop and see what happens.
Follow this code after your node creation. I hope this will work. And do use i++ instead of ++i, as the later will make the loop for size-1 times.
if(head == NULL)
head = temp;
else{
Node *x;
x= head;
while(x->next != NULL)
x = x->next;
x->next = temp;
}

Unity / Search closes Object from a List by tag

I have a Problem to find the closest Object in my List.
There are three types with the tags (Food, Stone and Wood).
I spawn them at the beginning , some for each type, if i found some Resources, they're not hidden anymore, and i add them to the List that a Worker goes to them and harvests them.
So Later in the Game, for expample
i found 3 Stone Resources, then worker should harvest the closest one first everytime....
but i don't know how to iterate throw a Loop only to search for the Tags and how to get the position of the closest one.
Here is some code of the Method that i wrote:
void FindNearestFoodRessource()
{
for (int i = 0; i < gameController.discoveredRessources.Count; i++)
{
//float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
GameObject nearestFoodRessource = GameObject.FindGameObjectWithTag("Food");
}
}
First thing first - don't use FindGameObject**** in frequently called methods, it is very expensive.
About your problem - just check tag and distance of all the resources:
float minDist = Vector3.Distance(gameController.discoveredRessources[0].transform.position, transform.position);
int minDistIndex = 0;
for (int i = 1; i < gameController.discoveredRessources.Count; i++)
{
if (gameController.discoveredRessources[i].gameObject.CompareTag("Food"))
{
float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
if (dist < minDist)
{
minDist = dist;
minDistIndex = i;
}
}
}
//Now you can move to gameController.discoveredRessources[minDistIndex]
Also you can store all the food/stones/wood in the separate lists when you find it
Using Linq Where and this usefull extension method MinBy
using System;
using System.Collections.Generic;
using System.Linq;
public static class Linqextensions
{
public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
}
}
(simply copy that code somwhere into your project) you could do it in "one" line
var closestItem = gameController.discoveredRessources
// this is a filter only selecting the ones with tag = "Food"
.Where(obj => obj.CompareTag("Food"))
// this returns you the item from the list with the lowest distance
.MinBy(obj => Vector3.Distance(obj.transform.position, transform.position));