How can I translate this python function to c++? - python

I am trying to translate a python function to c++ without success. Can someone help me?
The python function receives as input a string S and 2 integers (fragment_size and jump).
The aim of this function is to slice the string S in a number of fragments of length equal to the first integer given by the input (fragment_size) and traverse the whole string S with a step equal to the second integer given by the input (jump).
import sys
# First we read the input and asign it to 3 different variables
S = sys.stdin.readline().strip()
fragment_size = sys.stdin.readline().strip()
jump = sys.stdin.readline().strip()
def window(S, fragment_size, jump):
word = S[:fragment_size]
if len(word)< fragment_size:
return []
else:
return [word] + window(S[jump:], fragment_size, jump)
# We check that S is not an empty string and that fragment_size and jump are bigger than 0.
if len(S) > 0 and int(fragment_size) > 0 and int(jump) > 0:
# We print the results
for i in window(S, int(fragment_size), int(jump)):
print(i)
For example:
Input
ACGGTAGACCT
3
1
Output
ACG
CGG
GGT
GTA
TAG
AGA
GAC
ACC
CCT
Example 2:
Input
ACGGTAGACCT
3
3
Output
ACG
GTA
GAC
I know how to solve this in c++ returning a string in the window function. But I really need to return a list, like the one I am returning in the python program.
Right now, I have this C++ code:
# include <iostream>
# include <vector>
# include <string>
using namespace std;
vector<string> window_list(string word, vector<vector<string>>& outp_list){
outp_list.push_back(word);
}
vector<string> window(string s, int len_suf, int jump){
string word;
vector<vector<string>> outp_list;
word = s.substr(0, len_suf);
if(word.length() < len_suf){
return vector<string> window_list();
}
else {
window_list(word, outp_list);
return window(s.substr(jump), len_suf, jump);
}
}
int main(){
// We define the variables
string s;
int len_suf, jump;
// We read the input and store it to 3 different variables
cin >> s;
cin >> len_suf;
cin >> jump;
// We print the result
vector<string> ans = window(s, len_suf, jump);
for(auto& x: ans){
cout << x << endl;
}
return 0;
}
Thanks!

It does the job, but as I'm not very into C++ Alexandros Palacios approach might be better anyways. This is just a blunt translation of your Python code.
#include <strings.h>
#include <iostream>
#include <vector>
std::string window(std::string S, int fragment_size, int jump) {
for (int i = 0; i <= S.length(); jump) {
std::string word = S.substr(i, i+fragment_size);
if (word.length() < fragment_size) {
return "";
}
else {
return word + " " + window(S.substr(jump, S.length()-1), fragment_size, jump);
}
}
}
int main(int argc, char const *argv[])
{
std::string S;
std::cout << "Enter DNA sequence: ";
std::cin >> S;
int fragment_size;
std::cout << "Enter fragment size: ";
std::cin >> fragment_size;
int jump;
std::cout << "Enter jump size: ";
std::cin >> jump;
std::vector<std::string> data;
std::string result;
if (S.length() > 0 && fragment_size > 0 && jump > 0) {
result = window(S, fragment_size, jump);
} else {
return 1;
}
size_t pos;
std::string delimiter = " ";
while ((pos = result.find(delimiter)) != std::string::npos) {
data.push_back(result.substr(0, pos));
result.erase(0, pos + delimiter.length());
}
for (const auto &str : data) {
std::cout << str << " ";
}
std::cout << std::endl;
return 0;
}

Using the string data type you can achieve it without so much problems. Instead of the python [:] operator, you can use the substr method:
#include <iostream>
#include <string.h>
using namespace std;
string S = "";
int fragment_size = 0;
int jump = 0;
char a_result[1024];
string window(string s) {
if (s.length() < fragment_size)
return "";
else
return s.substr(0, fragment_size) + " " + window(s.substr(jump));
}
int main(int argc, char *argv[]) {
cin >> S;
cin >> fragment_size;
cin >> jump;
if (S.length() && fragment_size > 0 && jump > 0) {
string result = window(S);
cout << endl
<< result;
// Get array from the string
strncpy(a_result, result.c_str(), sizeof(a_result));
a_result[sizeof(a_result) - 1] = 0;
}
return 0;
}
Also, in your window function, you have an extra for loop that isn't needed since you return a value after the first iteration.

You can use the program shown in the below example:
#include <iostream>
#include <vector>
#include <string>
std::vector<std::string> stringFragmenter(const std::string &inputString, int len, int stepSize)
{
std::string::const_iterator currentBegin = inputString.begin();
std::string::const_iterator end = inputString.end();
std::string::const_iterator currentPosition = currentBegin;
std::vector<std::string> output;
std::string pushedString;
while(currentPosition + len <= end)
{
currentBegin = currentPosition;
std::string::const_iterator currentEnd = currentBegin + len;
while(currentBegin != currentEnd)
{
pushedString+= *currentBegin;
++currentBegin;
}
output.push_back(pushedString);
currentPosition = currentPosition + stepSize;
//clear the pushedString for next iteration
pushedString.clear();
}
return output;
}
int main()
{
std::string inputString;
std::cin >> inputString;
int length;//this denotes the length of string that has to be displayed(stored) at each time
std::cin >> length;
int stepSize;
std::cin >>stepSize;//this denotes the jump size
std::vector<std::string> fragmentedString = stringFragmenter(inputString, length, stepSize);
//print out the elements of the returned vector so that we can confirm if it contains the correct elements
for(const std::string &elem: fragmentedString)
{
std::cout<<elem<<std::endl;
}
return 0;
}
The output of the above program matches with both of your input cases as can be seen here.
In the above program, to enter your input case 1 you should first enter the string ACGGTAGACCT and then the length 3 and then finally the stepSize(or jump size) 1 and the input/output would look like:
ACGGTAGACCT
3
1
ACG
CGG
GGT
GTA
TAG
AGA
GAC
ACC
CCT
which matches with your desired output. Similarly for your input case 2. Check out the output here.

Related

unordered_map giving Segmentation fault (core dumped) when calling C++ library from python

i am trying to use https://github.com/Spyros-DC/words-in-some-editdistance/blob/master/my_distance.cpp C++ implementation in python, however i kept receiving Segmentation fault (core dumped). Below is the entire code in python and C++, i have edited small parts of the original library to suit my use case. I have managed to find that when trying to use the unordered_map children.count(remaining_w.at(0)) it is throwing the segmentation fault error. I was wondering if anyone knows what is causing the error. Thank you so much in advance.
#include <iostream>
#include <unordered_map>
#include <string>
#include <fstream>
#include <unordered_set>
#include <vector>
#include <sstream>
#include <typeinfo>
using namespace std;
// using namespace std::chrono;
class trie{
public:
string word;
unordered_map<char, trie*> children;
// this function works
// with the argument flag set to zero
int insert(string w, int flag, string remaining_w = ""){
//the first time we call insert
if(flag == 0)
remaining_w = w;
int the_size = remaining_w.size();
if(children.count(remaining_w.at(0)) == 0){
children[remaining_w.at(0)] = new trie();
}
if(the_size == 0){
word = w;
return 0;
}else{
//the recursive calls with flag one
children[remaining_w.at(0)]->insert(w, 1, remaining_w.erase(0, 1));
return 0;
}
}
};
class AutoCorrect{
public:
// The tree
trie tree;
//the dictionary with the words
const int max_cost = 2;
const int too_big_distance = 10;
void insert(char* word){
ifstream ifp(word);
while(ifp >> word){
cout << word <<endl;
tree.insert(word, 0);
// }
}
}
void test(char* test){
cout << test << endl;
}
void search_recursive(trie* p_tree, char ch, const string& word, vector<int>& previous_row, int max_cost, unordered_map <string, int>& results)
{
int sz = previous_row.size();
int min_row = 12;
vector<int> current_row(sz, too_big_distance);
current_row[0] = previous_row[0] + 1;
// Calculate the min cost of insertion, deletion, match or substution
int insert_or_del, replace;
for (int i = 1; i < sz; i++) {
insert_or_del = min(current_row[i-1] + 1, previous_row[i] + 1);
replace = (word[i-1] == ch) ? previous_row[i-1] : (previous_row[i-1] + 1);
current_row[i] = min(insert_or_del, replace);
}
if ((current_row[sz-1] <= max_cost) && (p_tree->word != "")) {
results[p_tree->word] = current_row[sz-1];
}
for(auto& it: current_row){
if (it < min_row)
min_row = it;
}
if(min_row <= max_cost){
for(auto& it: p_tree->children){
search_recursive(it.second, it.first, word, current_row, max_cost, results);
}
}
}
int search(string word)
{
unordered_map <string, int> results;
int sz = word.size();
vector<int> current_row(sz + 1);
for (int i = 0; i <= sz; ++i){
current_row[i] = i;
}
for(auto& it: tree.children){
search_recursive(it.second, it.first, word, current_row, max_cost, results);
}
for(auto& p:results)
cout << p.first << ", " << p.second << endl;
return 0;
}
};
// The cost and a distance for vector initialization
extern "C" {
AutoCorrect* AutoCorrect_new(){ return new AutoCorrect(); }
void AutoCorrect_insert(AutoCorrect* autocorrect, char* word){ autocorrect->insert(word); }
void AutoCorrect_search(AutoCorrect* autocorrect, string input_word){ autocorrect->search(input_word); }
void AutoCorrect_test(AutoCorrect* autocorrect, char* name){ autocorrect-> test(name); }
}
Python main.py:
from ctypes import cdll
lib = cdll.LoadLibrary('autocorrect.so')
class AutoCorrect(object):
def __init__(self):
self.obj = lib.AutoCorrect_new()
def insert(self, word):
lib.AutoCorrect_insert(self.obj,word)
def search(self,input_word):
lib.AutoCorrect_search(self.obj,input_word)
def test(self,test):
lib.AutoCorrect_test(self.obj,test)
if __name__ == "__main__":
import json
WordCount = 0
autocorrect = AutoCorrect()
data_dir = "some_txt_file.txt"
autocorrect.insert(bytes(str(data_dir), encoding='utf8'))
Looking at the line you specified, i think there is an instance you are trying to add a value to a non existent key:
if(children.count(remaining_w.at(0)) == 0){
children[remaining_w.at(0)] = new trie();
if "children.count" returns 0 then that character is not present, then trying to add a value on the second line there means....
what i think you want to do on that line is:
if(children.count(remaining_w.at(0)) == 1){
children[remaining_w.at(0)] = new trie();
meaning you add the value only if key is present.

Callback functions in ROS ? How to properly update them?

So I make robot, which should get data from laser sensor and then move until some distance and stops.
But I find problem in callback functions. Is there somewhere better explanation how to update variables with callback properly ? I had same problem with python and there I found out that time.sleep(0.2) let the class to update properly. Even this is little bit magic for me. Because I was thinking that in python this works automatically because separated threading.
In c++ I know that the basic is using spinOnce() and spin(). This works how it should in normal non-object-oriented case. But in the class again I found out that the class is not updated properly. Why is this a case ?
I can not find why the callback function is not working properly. I could see if it was the case by print full range from reading, but it never happens. I have ros::spinOnce() and I think I have correctly member functions. Can someone please help me ? And help me to understand ?
robot.h
#include <ros/ros.h>
#include "sensor_msgs/LaserScan.h"
#include "geometry_msgs/Twist.h"
#include <math.h>
#include <iostream>
class Robot{
geometry_msgs::Twist velocity;
sensor_msgs::LaserScan ls_scan;
ros::Subscriber sub;
ros::Publisher pub;
ros::Rate rate{10};
double speed_linear;
double speed_angular;
public:
Robot(ros::NodeHandle *handle_IN, double rate_IN, double speed_linear_IN,double speed_angular_IN){
rate = ros::Rate{rate_IN};
speed_linear=speed_linear_IN;
speed_angular=speed_angular_IN;
sub = handle_IN->subscribe("/scan",1000,&Robot::scan_callback,this);
pub = handle_IN->advertise<geometry_msgs::Twist>("/cmd_vel",10);
usleep(2000000);
}
void scan_callback(const sensor_msgs::LaserScan::ConstPtr& msg);
void move();
void rotate(bool clock_wise);
void stop();
bool obstacle_in_front(double distance);
bool can_drive(double distance);
std::vector<float> front_read();
std::vector<float> back_read();
};
robot.cpp
#include "robot.h"
void Robot::scan_callback(const sensor_msgs::LaserScan::ConstPtr& msg){
ls_scan = *msg;
for(float x: ls_scan.ranges)
std::cout << x;
std::cout << std::endl;
}
void Robot::move(){
velocity = geometry_msgs::Twist();
velocity.linear.x = speed_linear;
ros::spinOnce();
while(!obstacle_in_front(0.56)){
ros::spinOnce();
std::cout << "moving\n";
pub.publish(velocity);
rate.sleep();
}
stop();
}
void Robot::rotate(bool clock_wise){
velocity = geometry_msgs::Twist();
velocity.angular.z = speed_angular;
ros::spinOnce();
while(can_drive(2)){
ros::spinOnce();
std::cout << "rotating\n";
pub.publish(velocity);
rate.sleep();
}
stop();
}
void Robot::stop(){
std::cout << "stop\n";
velocity = geometry_msgs::Twist();
pub.publish(velocity);
}
float min(const std::vector<float>& v){
if(v.size() == 0)
return -1;
float min = v[0];
for(float x: v){
if(x < min)
min = x;
}
return min;
}
std::vector<float> Robot::front_read(){
ros::spinOnce();
std::vector<float> front(20);
if(ls_scan.ranges.size()<350)
return front;
for(int i = 0; i < 10; ++i)
front.push_back(ls_scan.ranges[i]);
for(int i = 350; i < 360; ++i)
front.push_back(ls_scan.ranges[i]);
return front;
}
std::vector<float> Robot::back_read(){
ros::spinOnce();
std::vector<float> front(20);
if(ls_scan.ranges.size()<350)
return front;
for(int i = 169; i < 190; ++i)
front.push_back(ls_scan.ranges[i]);
return front;
}
bool Robot::obstacle_in_front(double distance){
float minN = min(front_read());
if(minN > distance)
return false;
else
return true;
std::cout << minN << "\n";
}
bool Robot::can_drive(double distance){
float minN = min(front_read());
if(minN > distance)
return true;
else
return false;
}
robot_control_node.cpp
#include "robot.h"
int main(int argc, char **argv){
ros::init(argc,argv, "robot_node_node");
ros::NodeHandle n;
Robot robot(&n,10,0.5,0.3);
robot.move();
}
So the final answer is this.
Wait for valid data -> I did this with simple wait loop which runs after initialization of publisher/subscriber in constructor.
Then you can check for new valid data when you need it. Example is calling spinOnce() in move member function. This is done with do-while, because you want to check condition after new data.
void Robot::wait_for_valid_data(){
while(ls_scan.ranges.size() < 359)
{
std::cout << "waiting for valid data\n";
ros::spinOnce();
rate.sleep();
}
std::cout << "valid data";
}
void Robot::move(){
velocity = geometry_msgs::Twist();
velocity.linear.x = speed_linear;
do{
if(!ros::ok())
break;
std::cout << "moving\n";
pub.publish(velocity);
ros::spinOnce();
rate.sleep();
}while(!obstacle_in_front(0.56));
stop();
}
I found the problem.
Basically with callbacks. You have to be sure, that the publisher catches up. So before you call the spinOnce() which checks if it is something there. You have to call some sort of wait function. ros::rate/ros::Duration and wait. Then when you call spinOnce(). You will have new incoming data, which the callback function can read.
In this sence:
std::vector<float> Robot::front_read(){
ros::Duration(0.1).sleep(); //wait for new callback
ros::spinOnce(); //read the callback
std::vector<float> front;
if(ls_scan.ranges.size()<350)
return front;
for(int i = 0; i < 10; ++i)
front.push_back(ls_scan.ranges[i]);
for(int i = 350; i < 360; ++i)
front.push_back(ls_scan.ranges[i]);
return front;
}

Why pybind11 converts double to int?

I created .pyd file:
#include <pybind11/pybind11.h>
#include <iostream>
#include <typeinfo>
namespace py = pybind11;
int add(int num) {
float a = 1.0;
for (int i = 0; i <= num; i = i + 1) {
a = (a + i)/a;
}
std::cout << "dll is typing: " << a << '\n';
std::cout << typeid(a).name() << std::endl;
return a;
}
PYBIND11_MODULE(py_dll, m) {
m.doc() = "pybind11 py_dll plugin"; // optional module docstring
m.def("add", &add, "Add function", py::arg("num"));
}
I call it from python:
import py_dll
num = 500
a = py_dll.add(num)
print ('python is typing: ', a)
It prints:
Why digit became int? I speak about 22. I expect it to be float 22.8722
This function
int add(int num)
takes an int as parameter and returns an int. The "problem" is not with pybind. Try this to see:
int main() {
auto x = add(42);
std::cout << "return value: " << x << '\n';
std::cout << typeid(x).name() << std::endl;
}
If the function should return a float you have to declare that it returns a float:
float add(int num)

CTYPES and PYTHON3: Can't return long string

I have a C++ code for which I created a python.ctypes wrapper. It works quite well, except when the returning string is long. Example of C code:
extern "C" {
const char * hallo(char * nome)
{
string str(nome);
str = "hallo " + str;
for(int i=0; i<100; i++)
str += " new content";
return str.c_str();
}
My python code is:
self.lib = ctypes.CDLL(LIB_PATH)
self.lib.hallo.restype = ctypes.c_char_p
self.lib.hallo.argtypes =[ctypes.c_char_p]
j = self.lib.hallo('my name'.encode())
print('INIT: ' + j.decode())
The string size is dynamic (in fact, it will be a json string). What is the best way to deal with this situation?
Thanks so much.
The issue here is that when you return str.c_str() you're returning a pointer to stack allocated memory which gets overwritten on return from the C++ code.
Potential workarounds are to use static string str such as:
#include <string>
#include <sstream>
extern "C" {
const char * hallo(char * nome)
{
static std::string str;
std::stringstream stream;
stream << "hallo " << nome;
for(int i=0; i<100; i++)
stream << " new content";
str = stream.str();
return str.c_str();
}
}
Although this will prevent you from calling the routine from multiple threads.
If you want to be able to call it from multiple places, you should probably take a parameter pointer to some memory, and pass in a pointer buffer created from ctypes.create_string_buffer (hoping that it has the right size in this case).
For example:
#include <string>
#include <sstream>
extern "C" {
const char * hallo(char * nome, char *writebuffer, unsigned int buffersize)
{
std::string str(nome);
str = "hallo " + str;
for(int i=0; i<100; i++)
str += " new content";
if (str.size() < buffersize) {
str.copy(writebuffer, buffersize);
return writebuffer;
} else {
return 0;
}
}
}
Then some sample python code that uses this library; passing in a 128k buffer (python 3 updated):
import ctypes
lib = ctypes.CDLL(LIB_PATH)
lib.hallo.restype = ctypes.c_char_p
lib.hallo.argtypes =[ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint]
allocation = ctypes.create_string_buffer(128 * 1024)
j = lib.hallo('my name'.encode(), allocation, 128 * 1024)
if j is not None:
print('INIT: ' + j.decode("UTF-8"))
else:
print("Buffer was too small")

How to use coordinates from an input file with prim's algorithm in order to create circles using pygraphics and C++?

I have looked at many many examples of Prim's Algorithm on here and Google and found no real answer to this question... Please excuse my structure of this problem. I'm terrible with how S/O prints things out.
I have an input file "SmallGraph.txt" that contains a set of coordinates and the number of vertices at the top:
9
50 100
100 150
200 150
300 150
350 100
300 50
200 50
100 50
150 100
I'm having a lot of trouble trying to figure out how to get these input items read so that my while loop will be able to print a "circle" for every vertice mentioned above so I can run Prim's algorithm for a minimum spanning tree.
What code I have so far of me attempting to get something printed out with a while loop. Also, a few classes to implement Prim's algorithm with those points I need to plot through python:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cstring>
#include <math.h> /* pow() function */
// This line allows commonly-used functions to be used without specifying the
// library in which that function is defined. For instance, this line allows
// the use of "cout" rather than the full specification "cout"
using namespace std;
class SetOfIntegers
{
public:
// Constructor. Any setup operation you wish for the class.
SetOfIntegers()
{
members.clear();
} // end constructor
void add(int m) // Add members to set WITHOUT repetition
{
for (auto i : members)
{
if (i == m) return; // no addition of existing member
}
members.push_back(m);
}
int size() { return members.size(); }
void show() { for (auto i: members) cout << i << " "; cout << endl; }
bool isMember(int m)
{
//cout << "isMember(" << m << ") is ";
for (auto i : members)
{
if (i == m)
{
//cout << " true" << endl;
return true;
}
}
//cout << " false" << endl;
return false;
}
private:
vector<int> members;
};
//--------------------------------------------------------------------------
class Point
{
public:
// Constructor. Any setup operation you wish for the class.
Point()
{
x = 0; y = 0;
} // end constructor
Point(int a, int b, int id)
{
x = a; y = b; pointID = id;
} // end constructor
int getX() { return x; }
int getY() { return y; }
int getID() { return pointID; }
private:
int x = 0;
int y = 0;
int pointID = 0;
}; // end class Point
//--------------------------------------------------------------------------
class Edge
{
public:
// Constructor. Any setup operation you wish for the class.
Edge()
{
} // end constructor
Edge(Point ptA, Point ptB)
{
pointA = ptA;
pointB = ptB;
length = sqrt(pow(abs(pointA.getX() - pointB.getX() ), 2) + pow(abs(pointA.getY() - pointB.getY() ), 2) );
} // end constructor
Point getPtA() { return pointA; }
Point getPtB() { return pointB; }
double getLen() { return length; }
int getPtAID() { return pointA.getID(); }
int getPtBID() { return pointB.getID(); }
private:
Point pointA;
Point pointB;
double length;
}; // end class Edge
// NOTE: DO NOT declare with empty parentheses, as vector<Point> myPointvector();
vector<Point> myPointvector; // vector will expand as needed
vector<Edge> MinSpanTree;
// Pass arguments or parameters from command-line execution. argc is the count of
// those parameters, including the executable filename. argv[] is an array of the
// parameters.
int main (int argc, char *argv[])
{
string token;
int xValue, yValue;
ifstream fin;
int coordPairs; // number of coordinate pairs in the file
int ptX, ptY;
vector<Edge> unsortedEdgeVector;
vector<Edge> sortedEdgeVector;
int loopCounter;
int pointCounter = 0;
double MSTLength = 0.0;
// Check the number of arguments. Expected: filename of a file
if (argc != 2) // This check is often hardcoded
{ // If failure in parameters, offer advice for correction
cout << "\nThis program uses command-line argument.\n";
cout << "Usage: a.exe <filename>\n";
exit(0);
}
try // All lines within this block are part of the same exception handler
{
fin.open(argv[1]);
}
catch (exception& ex)
{
cout << ex.what(); // display standard explanation of the exception
exit(0); // exit the program
}
// Read from the file, one token at a time. If the type of token is known, it
// can be read into a corresponding variable type, such as
// in >> x; // Read the first item into an integer variable x.
// in >> str; // Read the next item into a string variable str.
//for (int i = 0; 1 != 10; i++) {
// fin >> ptX[2] >> ptY[2];
//}
//cout << ptX << endl;
// This line provides the graphic window setup.
cout << "800 600 white" << endl;
fin >> coordPairs;
while (fin >> ptX)
{
// Do something with the element read from the file
cout << ptX << endl;
fin >> ptY;
cout << ptY << endl;
cout << "circle " << ptX << " " << ptY << " " << 20 << " seagreen" << endl;
/*
Point dummyPoint(ptX, ptY, pointCounter++);
myPointvector.push_back(dummyPoint); // vector will expand as needed
cout << "Now myPointvector has size " << myPointvector.size() << endl;
*/
} // end while
fin.close();
}
As you can see... I have a while loop in my main function that is attempting to create a "circle" based on ptX and ptY. That's what I'm having trouble with.. How do I read from this input file in order to get these points and get them to create a circle through python? If you notice.. I've attempted a for loop that is currently commented out for reading the file.
I was using the wrong command for requesting information from the input file. I was using the commands:
g++ -std=c++11 PrimMSTAlgor.cpp (Compile the code)
a PrimMSTAlgor.cpp > PrimData.dat (Put data into primData.dat from the .cpp file)
python BearPlot.py PrimData.dat (use python to apply graphics)
The second command is incorrect. I need to use the .txt file as the argument for "a" (the execution).
a SmallGraph.txt > PrimData.dat
What I have is already set up to put the input into the .dat file this way, I just couldn't see it...

Categories

Resources