I am trying to do a homework assignment that reads an integer in from C++ and passes it to a Python function that will display a multiplication table or double the integer. Note: the callIntFunc() function was given code by my instructor. I only wrote the code in main():
int callIntFunc(string proc, int param)
{
char* procname = new char[proc.length() + 1];
std::strcpy(procname, proc.c_str());
PyObject* pName, * pModule, * pDict, * pFunc, * pValue = nullptr, * presult = nullptr;
// Initialize the Python Interpreter
Py_Initialize();
// Build the name object
pName = PyUnicode_FromString((char*)"PythonCode");
// Load the module object
pModule = PyImport_Import(pName);
// pDict is a borrowed reference
pDict = PyModule_GetDict(pModule);
// pFunc is also a borrowed reference
pFunc = PyDict_GetItemString(pDict, procname);
if (PyCallable_Check(pFunc))
{
pValue = Py_BuildValue("(i)", param);
PyErr_Print();
presult = PyObject_CallObject(pFunc, pValue);
PyErr_Print();
}
else
{
PyErr_Print();
}
//printf("Result is %d\n", _PyLong_AsInt(presult));
Py_DECREF(pValue);
// Clean up
Py_DECREF(pModule);
Py_DECREF(pName);
// Finish the Python Interpreter
Py_Finalize();
// clean
delete[] procname;
return _PyLong_AsInt(presult);
}
void displayMenu() {
cout << setfill('=') << setw(45) << " " << endl;
cout << "1: Display a Multiplication Table" << endl;
cout << "2: Double a Value" << endl;
cout << "3: Exit" << endl;
cout << "Enter your selection as number 1, 2, or 3" << endl;
cout << setfill('=') << setw(45) << " " << endl;
}
int main()
{
int userInput;
displayMenu();
cin >> userInput;
//While loop for input validation to check to see if anything other than 1, 2 or 3 is entered
while (userInput != 1 && userInput != 2 && userInput != 3) {
cout << "Invalid input, enter 1, 2 or 3" << endl;
displayMenu();
cin >> userInput;
}
//Creates a multiplication table with given number if user entered 1
if (userInput == 1) {
cout << "Enter a number to create a multiplication table" << endl;
cin >> userInput;
cout << callIntFunc("MultiplicationTable", userInput) << endl;
}
//Doubles the given number if user entered 2
else if (userInput == 2) {
cout << "Enter a number to double it" << endl;
cin >> userInput;
cout << callIntFunc("DoubleValue", userInput) << endl;
}
//Exits program if user entered 3
else if (userInput == 3) {
cout << "Exiting..." << endl;
exit(0);
}
cout << "\nDone\n";
return 0;
}
The error occurs on the line with Py_DECREF(pValue). I also posted the call stack:
> Integrating Languages.exe!callIntFunc(std::string proc, int param) Line 129 C++
Integrating Languages.exe!main() Line 190 C++
[External Code]
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
import re
import string
def printsomething():
print("Hello from python!")
def PrintMe(v):
print("You sent me: " + v)
return 100;
def SquareValue(v):
return v * v
def MultiplicationTable(num):
for i in range(1, 11):
print(str(num) + "x " + str(i) + "= " + str(num * i))
return -1
def DoubleValue(num):
return num * 2
I'm trying to port the following series of videos from C++ to Python.
You can find them in YT: https://www.youtube.com/channel/UCzGKCXSeHjDRSmpX9SmQ1fw/videos
The library with the 12000 words can be found here: https://pastebin.com/E5sDrFJ5
The idea behing is to build a solver for crosswords from scratch. So far, up to module 9, my Python code is equivalent to the C++ version:
def ToUpper(s):
return s.upper()
class Library:
def __init__(self):
self.words = []
self.counts = {}
def IsWord(self, s):
for w in self.words:
if s == w:
return True
return False
def GetWord(self, i):
assert (i >= 0 and i < len(self.words))
return self.words[i]
def ReadFromFile(self, filename):
with open(filename, 'r') as f:
for line in f:
# print(f"{line.rstrip()} ({len(line.rstrip())})")
line = ToUpper(line)
self.words.append(line.rstrip())
print(f"Read {len(self.words)} words from file '{filename}'")
def ComputeStats(self):
assert self.counts == {}
for i in range(18):
self.counts[i] = []
for s in self.words:
_len = len(s)
if _len < 18:
self.counts[_len].append(_len)
def PrintStats(self):
print("Here are the counts of each word length")
for k,v in self.counts.items():
if k != 0:
print(f"[{k}] {len(v)}")
class Grid:
def __init__(self, n):
self.name = n
self.lines = []
def rows(self):
return len(self.lines)
def cols(self):
if self.lines == []:
return 0
else:
return len(self.lines[0])
def LoadFromFile(self, filename):
with open(filename, 'r') as f:
for line in f:
# print(f"{line.rstrip()} ({len(line.rstrip())})")
if not line.startswith('#'):
self.lines.append(line.rstrip())
def Check(self):
for s in self.lines:
assert len(s) == self.cols()
def Print(self):
print(f"Grid: {self.name} "
f"(rows={self.rows()},"
f" cols={self.cols()})")
for s in self.lines:
print(f" {s.rstrip()}")
if __name__ == "__main__":
lib = Library()
lib.ReadFromFile("top_12000.txt")
lib.ComputeStats()
lib.PrintStats()
print(lib.IsWord("DOG"))
print(lib.IsWord("FUFFJFJ"))
print(lib.IsWord("THANKS"))
# grid = Grid("MY GRID")
# grid.LoadFromFile('test')
# grid.Check()
# grid.Print()
The C++ version from the video is this one:
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include <fstream>
using namespace std;
string ToUpper(string s) {
string s2;
for (char c : s) {
s2.push_back(toupper(c));
}
return s2;
}
class Library {
public:
bool IsWord(string s) const {
for (string t : words) {
if (s == t) {
return true;
}
}
return false;
}
void ComputeStats() {
assert(counts.empty());
counts.resize(18);
for (string s : words) {
int len = s.length();
if (len < 18) {
counts[len]++;
}
}
}
void PrintStats() const {
cout << "Here are the counts of each word length:\n";
for (int i=1; i<counts.size(); i++) {
cout << "[" << i << "] " << counts[i] << "\n";
}
}
string GetWord(int i) const {
assert(i >= 0 && i < words.size());
return words[i];
}
void ReadFromFile(string filename) {
ifstream f;
f.open(filename);
while (!f.eof()) {
string line;
getline(f, line);
// cout << line << " (" << line.length() << ")\n";
if (!line.empty()) {
line = ToUpper(line);
int len = line.length();
if (line[len-1] == '\r') {
line = line.substr(0, len-1);
}
words.push_back(line);
}
}
cout << "Read " << words.size() << " words from file '"
<< filename << "'\n";
}
private:
vector<string> words;
vector<int> counts;
};
struct Grid {
Grid(string n) {
name = n;
}
int rows() const { return lines.size(); }
int cols() const {
if (lines.empty()) {
return 0;
} else {
return lines[0].size();
}
}
void LoadFromFile(string filename) {
ifstream f;
f.open(filename);
while (!f.eof()) {
string line;
getline(f, line);
cout << line << " (" << line.length() << ")\n";
if (!line.empty() && line[0] != '#') {
lines.push_back(line);
}
}
}
void Check() const {
for (int i=0; i<lines.size(); i++) {
assert(lines[i].size() == cols());
}
}
void Print() const {
cout << "Grid: " << name
<< " (rows=" << rows()
<< ", cols=" << cols() << ")\n";
for (string s : lines) {
cout << " " << s << "\n";
}
}
string name;
vector<string> lines;
};
int main() {
Library lib;
lib.ReadFromFile("top_12000.txt");
lib.ComputeStats();
lib.PrintStats();
cout << lib.IsWord("DOG") << "\n";
cout << lib.IsWord("FUFFJFJ") << "\n";
cout << lib.IsWord("THANKS") << "\n";
// Grid grid("MY GRID");
// grid.LoadFromFile("test");
// grid.Check();
// grid.Print();
But I got stuck in lesson 9 because there is no "struct" data type in Python. In the video for lesson 9, this new structure "Word" was introduced. I highligthed the changes:
**struct Word {
Word(string s) {
word = s;
}
string word;
};
typedef vector<Word> Words;**
class Library {
public:
bool IsWord(string s) const {
for (**Word w** : words) {
if (s == **w.word**) {
return true;
}
}
return false;
}
void ComputeStats() {
assert(counts.empty());
counts.resize(18);
for (**Word w** : words) {
int len = **w.word**.length();
if (len < 18) {
counts[len]++;
}
}
}
void PrintStats() const {
cout << "Here are the counts of each word length:\n";
for (int i=1; i<counts.size(); i++) {
cout << "[" << i << "] " << counts[i] << "\n";
}
}
string GetWord(int i) const {
assert(i >= 0 && i < words.size());
return words[i]**.word**;
}
void ReadFromFile(string filename) {
ifstream f;
f.open(filename);
while (!f.eof()) {
string line;
getline(f, line);
// cout << line << " (" << line.length() << ")\n";
if (!line.empty()) {
line = ToUpper(line);
int len = line.length();
if (line[len-1] == '\r') {
line = line.substr(0, len-1);
}
words.push_back(**Word(line)**);
}
}
cout << "Read " << words.size() << " words from file '"
<< filename << "'\n";
}
private:
**Words words**;
vector<int> counts;
}
How should I proceed? Is it just to create a class "Word" like this?
class Word:
def __init__(self, n):
self.word = n
I'm missing the typedef, because there are not such structures in Python. And then, how to use this new class in the "Library" class?
class Library:
def __init__(self):
self.words = Words()
self.counts = {}
Because this is giving me a TypeError:
TypeError: __init__() missing 1 required positional argument: 'n'
Any help will be appreciated.
So, a few years ago I wrote a program in Python that writes the English names of a sequential list of numbers to a file (one, two, three, etc.). I have been working on getting a C++ version working off and on for the last month (personal project), and I think I have it running pretty well. One problem: it's five times slower than the Python version. I've tried switching string concatenation methods ( << vs operator+ vs operator+= vs .append()), using fprinf() instead of ofstream, pre-allocating the string size (.reserve()), and a lot of other things I can't remember, but I seemed to have run into a wall. Then I noticed that the C++ writing speed seems to max out around 70MB/s, whereas the Python version writes at around 350MB/s. The drive I am using is a 5400rpm disk (CrystalDiskMark gives a sequential write speed of 60-90 MB/s), so the C++ write speeds are believable, but the Python?
TL;DR: Python seems to be writing five times faster than possible, (near to the read speeds!) of the disk.
I've included the programs below, in case I am missing something obvious (plausible). "Benchmarking" involved running each program for the numbers 1-1,000,000, resulting in a file of 50,824KB. ~50s for C++, ~8.5s for Python.
Python:
##Code in Python version 2.7.5 for generating a file with the English names of a set range of numbers.
while 1:
s=input("Starting_Value:")
f=input("Ending_Value:")
filename=raw_input("Desired Name of File:")
##dictionary
one=["","one","two","three","four","five","six","seven","eight","nine","error_one"]
one2=["","-one","-two","-three","-four","-five","-six","-seven","-eight","-nine","error_one2"]
teen=["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen","error_teen"]
ten=["","twenty","thirty","fourty","fifty","sixty","seventy","eighty","ninety","error_ten"]
##Functions
def translate(n): ##handles '' to 999
work=[]
if n>=100:
work.append(one[int(n/100)]+" hundred ")
n=n-(100*int(n/100))
if n>=10:
if n>=20:
work.append(ten[int(n/10)-1]+one2[n-(10*int(n/10))]+" ")
else:
work.append(teen[n%10]+" ")
elif n>=1:
work.append(one[n]+ " ")
elif n>=10:
if n>=20:
work.append(ten[int(n/10)-1]+one2[n-(10*int(n/10))]+" ")
else:
work.append(teen[n%10]+" ")
elif n>=1:
work.append(str(one[n])+" ")
end1=', '.join(work)
end1=end1.replace(", ","")
return end1
def english(m): ##handles billions, hundred millions, millions, hundred thousands, thousands
work2=[]
if m>=1000000000:
work2.append(str(translate(int(m/1000000000)))+"billion ")
elif m>=1000000:
work2.append(str(translate(int(m/1000000)))+"million "+str(translate(int(m-(1000000*int(m/1000000)))/1000))+"thousand "+str(translate(m-(1000*int(m/1000)))))
if ((int(m/1000)%1000)==0):
end3=str(', '.join(work2))
end4=end3.replace("thousand ", "")
work2[:]=[]
work2=[str(end4)]
else:
end3=str()
elif m>=1000:
work2.append(str(translate(int(m/1000)))+"thousand "+str(translate(m%1000)))
elif m>=1:
work2.append(translate(m))
end2=str(', '.join(work2))
end2=end2[:-1]
return end2
##Main Program - Iterator
file = open(str(filename), "a")
for i in range(f-s+1):
file.write(str(english(s))+", ")
s = s + 1
file.close()
a = raw_input("Close window to EXIT, or press ENTER to generate another file")
C++
//Generates a file of sequential numbers in English
//libraries
#include <iostream> //for output to terminal
#include <fstream> //for output to file
#include <string> //for handling strings
using namespace std; //yes
ofstream fout; //for convenience with 'cout'
//function prototypes
string thousands(int n); //translates 1 to 999
string millions(int m); //translates the hundred thousands, millions,
hundred millions
int lint(int j, int k); //outputs the digits of a number greater than the kth place i.e. lint(123456, 1000) = 123
//variables
int shi = 0; //starting value
int kut = 1; //ending value
int i = 0; //iterator
string fname = ""; //filename
string buffern = ""; //buffer for thousands
string bufferm = ""; //buffer for millions
string bufferf = ""; //first digit buffer
//dictionary
char one[10][7] = { ""," one"," two"," three"," four"," five"," six"," seven"," eight"," nine" };
char one2[10][7] = { "","-one","-two","-three","-four","-five","-six","-seven","-eight","-nine" };
char teen[10][11] = { " ten"," eleven"," twelve"," thirteen"," fourteen"," fifteen"," sixteen"," seventeen"," eighteen"," nineteen" };
char ten[10][9] = { "",""," twenty"," thirty"," fourty"," fifty"," sixty"," seventy"," eighty"," ninety" };
//main function
int main()
{
while (1)
{
//get user input
cout << " Starting Number: ";
cin >> shi;
cout << " Ending Number: ";
cin >> kut;
while (fout.is_open() != 1)
{
cout << " Desired Filename: ";
cin >> fname;
fname.append(".txt");
fout.open(fname);
if (fout.is_open() != 1)
cout << "\n Invalid file name. Please try again.\n";
}
//translate and write to file
if (shi == 0) { //handles starting at zero
fout << "zero,";
shi = 1;
}
else //handles spacing for next word
{
bufferf = millions(shi);
bufferf.erase(0, 1);
bufferf += ",";
fout << bufferf;
shi++;
}
for (i = shi; i < (kut); ++i) //Main Iterator
{
fout << millions(i) << ",";
}
fout << millions(kut) << "."; //handles last word
fout.close();
//display confirmation and prompt to exit/continue
cout << "\n Complete\n";
cin.get();
cin.ignore();
cout << endl;
}
}
//function definitions
string thousands(int n) //writes '' to 999
{
buffern = "";
buffern.reserve(30);
if (n >= 100) { //write hundreds place
buffern += one[lint(n, 100)];
buffern += " hundred";
n = n % 100;
if (n >= 10) { //write tens place
if (n >= 20) {
buffern += ten[lint(n, 10)];
buffern += one2[n % 10];
}
else { //deal with 'teens'
buffern += teen[n % 10];
}
}
else if (n >= 1) { //write ones place
buffern += one[n % 10];
}
}
else if (n >= 10) { //write tens place
if (n >= 20) {
buffern += ten[lint(n, 10)];
buffern += one2[n % 10];
}
else { //deal with 'teens'
buffern += teen[n % 10];
}
}
else if (n >= 1) { //write ones place
buffern += one[n];
}
return buffern;
}
string millions(int m)
{
bufferm = "";
bufferm.reserve(100);
if (m >= 1000000)
{
if (int(m / 1000) % 1000 == 0) { //if xxx,000,xxx
bufferm += thousands(lint(m, 1000000));
bufferm += " million";
bufferm += thousands(m % 1000);
}
else {
bufferm += thousands(lint(m, 1000000)); //millions
bufferm += " million";
bufferm += thousands(lint(m, 1000) % 1000); //hundred thousands
bufferm += " thousand";
bufferm += thousands(m % 1000); //thousands
}
}
else if (m >= 1000) {
bufferm += thousands(lint(m, 1000)); //hundred thousands
bufferm += " thousand";
bufferm += thousands(m % 1000); //thousands
}
else if (m >= 1) {
bufferm += thousands(m); //thousands
}
return bufferm;
}
int lint(int j, int k)
{
return ((j - (j % k)) / k);
}
I would appreciate any insights as to why the programs are running at different speeds, how the Python is writing so fast, or suggestions on speeding up the c++ code.
Edit: #VTT was right, not all of the C++ code was there. Added.
I was able to create my own class in C++ which is basically an array of fixed size, where I can append, retrieve, and change integers in.
This is the C++-code:
#include <iostream>
class List {
public:
//Item-object needed to store
//elements
struct Item {
int data = 0;
Item* next = nullptr;
};
//Constructor
//creates a list of fixed size
List(int size) {
//Filling up with empty items
for (int i = 0; i < size; i++) {
Item* item = new Item;
//If first item,
//store start-address
//set buffer to start address
if (i == 0)
this->start = item;
//Setting current item as nextptr
//for previous item in buffer
if (i > 0)
this->buffer->next = item;
//Storing current address in buffer
this->buffer = item;
//Outputting address and value (just for testing purposes)
//std::cout << "Address: " << &item << " -> " << item->data << std::endl;
}
}
//Destructor
~List() {
Item* current = this->start;
while(current) {
delete current;
current = current->next;
}
}
//Returns address of very first element in list
Item* getFirstItemAddress() {
return this->start;
}
//Append to list
bool append(int value) {
Item* start = this->start;
//Calculating insertIndex
int insertIndex = this->index *2;
//Inserting
(start + insertIndex)->data = value;
//Increment index for next call
this->index++;
return true;
}
//Retrieve item at index from list
int retrieve(int i) {
//Error check (index out of range)
if (i >= this->index) {
std::cerr << "Index out of range!" << std::endl;
throw("Index out of range");
return -1;
}
i = i * 2;
return (start + i)->data;
}
//Remove element at index from list
bool remove(int index) {
index = index * 2;
//Shifting all elements above 'index'
//one down
Item* current = (this->start + index);
while (current->next) {
Item* next = current->next;
current->data = next->data;
current = next;
}
//Decrementing index
this->index--;
return true;
}
//Change element to value at index
bool change(int index, int value) {
index = index * 2;
(this->start + index)->data = value;
return true;
}
//Printing out list
void print() {
int counter = 0;
Item* current = this->getFirstItemAddress();
while (current) {
if (counter >= this->index) break;
std::cout << current->data << std::endl;
current = current->next;
counter++;
}
}
private:
//Holding address of first item
Item* start = nullptr;
//Buffer holding temporary address
Item* buffer = nullptr;
//Variable pointing to indexToInsert
int index = 0;
};
int main() {
List list(5);
//Printing out
/*std::cout << std::endl << "Testing output:" << std::endl;
List::Item* current = list.getFirstItemAddress();
while (current) {
std::cout << current->data << std::endl;
current = current->next;
}*/
List::Item* start = list.getFirstItemAddress();
list.append(1);
list.append(2);
list.append(3);
list.append(4);
list.append(5);
std::cout << list.retrieve(0) << std::endl;
std::cout << list.retrieve(1) << std::endl;
std::cout << list.retrieve(2) << std::endl;
std::cout << list.retrieve(3) << std::endl;
std::cout << list.retrieve(4) << std::endl;
list.remove(2);
std::cout << std::endl;
list.print();
std::cout << std::endl;
list.change(3, 8);
std::cout << list.retrieve(3) << std::endl;
return 0;
}
But I actually want it in Python 3,
Python Code:
class Item:
data = None
next = None
def __init__(self, data=None, next=None):
self.data = data
self.next = next
class List:
start = Item()
buffer = Item()
index = 0
def __init__(self, size):
for i in range(0, size):
item = Item
if (i == 0):
start = item
if (i > 0):
self.buffer.next = item
buffer = item
def getFirstItemAddress(self):
return self.start
def append(self, value):
start = self.start
insertIndex = self.index * 2
(addressof(start) + insertIndex).data = value
self.index+=1
return True
def retrieve(self, i):
if i >= self.index:
print("Index out of range")
return -1
exit()
i = i * 2
return (self.start + i).data
def remove(self, index):
index = index * 2
current = (self.start + index)
while current.next:
next = current.next
current.data = next.data
current = next
self.index-=1
return True
def print(self):
counter = 0
current = self.getFirstItemAddress()
while current:
if counter >= self.index: break
print(current.data)
current = current.next
counter+=1
list = List(5)
list.append(1)
That code ain't working a little bit. I get errors like:
Traceback (most recent call last):
File "main.py", line 73, in <module>
list.append(1)
File "main.py", line 34, in append
(start + insertIndex).data = value
TypeError: unsupported operand type(s) for +: 'Item' and 'int'
Which is pretty logic, however, I need to be able to use SOME KIND of pointers and references in Python. Because I have to calculate index'es based on start-addresses etc.
I have researched a bit and stumbled on functions like 'id()', and 'addressof()' but those weren't working.
Without using special implementations like PyPy or CPython, how would I achieve this? I knew that in Python you have very little options to do memory management, but it's said that everything done in C++ can be done in Python... So how would I create my own made array-list implementation in Python?
TL;DR
I have created my own 'array-implementation' in C++, but I want it in Python3. However Python has very little memory management options like 'new', pointers, references,... I'm still searching for a way to achieve this in Python.
This question already has answers here:
Size of Matrix OpenCV
(5 answers)
Closed 6 years ago.
I want to get image width and height, how can I do that in OpenCV?
For example:
Mat src = imread("path_to_image");
cout << src.width;
Is that right?
You can use rows and cols:
cout << "Width : " << src.cols << endl;
cout << "Height: " << src.rows << endl;
or size():
cout << "Width : " << src.size().width << endl;
cout << "Height: " << src.size().height << endl;
or size
cout << "Width : " << src.size[1] << endl;
cout << "Height: " << src.size[0] << endl;
Also for openCV in python you can do:
img = cv2.imread('myImage.jpg')
height, width, channels = img.shape