This program almost works perfectly but currently still has an issue. The goal is to have an
Question:
This program almost works perfectly but currently still has an issue. The goal is to have an input file, which is a list of groceries. C++ and Python work together here to achieve three specific outputs. The user is given the option to see 1) how many times all of the individual items in the list appear in the list 2) how many times a specific item appears in the list and 3) a histogram version of how many times each item appears in the list.
Currently, I can print the list of all items and how many times they appear in the list, and the histogram. The problem I'm currently facing is how many times a specific item appears. I can't seem to figure out how to return the right number from python to C++ because whenever I try to return the variable used for counting that number, I get an access violation error so as of now it only returns 0. It is specifically the python function "item_frequency"
Source.cpp
#include#include #include #include #include #include using namespace std; /* Description: To call this function, simply pass the function name in Python that you wish to call. Example: callProcedure("printsomething"); Output: Python will print on the screen: Hello from python! Return: None */ void CallProcedure(string pName) { char* procname = new char[pName.length() + 1]; std::strcpy(procname, pName.c_str()); Py_Initialize(); PyObject* my_module = PyImport_ImportModule("PythonCode"); PyErr_Print(); PyObject* my_function = PyObject_GetAttrString(my_module, procname); PyObject* my_result = PyObject_CallObject(my_function, NULL); Py_Finalize(); delete[] procname; } /* Description: To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send Example: int x = callIntFunc("PrintMe","Test"); Output: Python will print on the screen: You sent me: Test Return: 100 is returned to the C++ */ int callIntFunc(string proc, string param) { char* procname = new char[proc.length() + 1]; std::strcpy(procname, proc.c_str()); char* paramval = new char[param.length() + 1]; std::strcpy(paramval, param.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("(z)", paramval); 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; delete[] paramval; return _PyLong_AsInt(presult); } /* Description: To call this function, pass the name of the Python functino you wish to call and the string parameter you want to send Example: int x = callIntFunc("doublevalue",5); Return: 25 is returned to the C++ */ 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); } // this function is to be used later; it's only purpose is to create strings of repeated characters as needed string nCharString(size_t n, char c) { string charString = ""; // this is the string that will be returned with the character for (size_t i = 0; i < n; i++) { // this for statement will establish the number of times the character is printed charString += c; // adding the character to the string } return charString; // return the properly formatted character string } void main() { //variable for the user to select a choice from the menu below; int menuChoice = 0; ifstream fileInput; string item_name; int item_quantity = 0; //this will be the menu loop while (menuChoice != 4) { // the loop will continue unless the user enters 4, which will quit the program // the menu to be displayed is the following code block cout << nCharString(20, '-') << " MENU " << nCharString(20, '-') << endl; // menu header cout << "[1] Count the number of times each item appears" << endl; cout << "[2] Determine the frequency of an item" << endl; cout << "[3] Display as a text-based histogram" << endl; cout << "[4] Exit program" << endl; cout << nCharString(46, '-') << endl << endl; // bottom of menu border cout << "What would you like to do?" << endl; // prompt user to enter a choice cin >> menuChoice; //retrieve the user's menu choice if (menuChoice == 1) { // this if statement will happen if the user chooses menu item one cout << endl << "Here is a list of the items, and how often they appear:" << endl; CallProcedure("item_list_frequency"); cout << endl; } else if (menuChoice == 2) { // this if statement will be triggered if the user chooses menu item two string groceryItem; // create variable for the grocery item that the user will select if choice one was selected cout << endl << "Please enter the item name: " << endl; cin >> groceryItem; // collect the name of the grocery item the user wants counted cout << callIntFunc("item_frequency", groceryItem) << endl; } else if (menuChoice == 3) { // this if statement will be triggered if the user chooses menu item three CallProcedure("histogram"); fileInput.open("frequency.dat"); // this is the file we created on the python side of things to create the histogram with fileInput >> item_name; fileInput >> item_quantity; while (!fileInput.fail()) { cout << item_name << " "; for (int i = 0; i < item_quantity; i++) { cout << "*"; } cout << endl; fileInput >> item_name; fileInput >> item_quantity; } fileInput.close(); cout << endl; break; } else if (menuChoice == 4) { // this if statement will be triggered if the user chooses menu item four, to exit the program cout << "Goodbye." << endl; break; } else { // else statement in case user enters an option other than one, two, three or four. cout << "Error: Invalid input. Please select 1,2,3, or 4."; } } }
PythonCode.py
import re import string def item_frequency(item_name): # a function to get the number of times a specific item appears for when the user calls on menu choice one item_name.lower() item_list = open("inputFile.txt", "r") # open file item_count = 0 # this is a placeholder variable; this will be updated with how many times the user chosen item appears in the list for line in item_list: line = line.strip() item = line.lower() if item == item_name: item_count += 1 # add one each time an item matching the user chosen item, aka item_name, appears return item_count text.close() def histogram(string = ""): # a function to generate a file with the data needed for C++ to create the histogram item_list = open("inputFile.txt", "r") # open file frequency = open("frequency.dat", "w") # creating the file where the data will be stored item_dictionary = dict() # dictionary to store the items for line in item_list: line = line.strip() item = line.lower() if item in item_dictionary: # increment the item accordingly item_dictionary[item] = item_dictionary[item] + 1 else: item_dictionary[item] = 1 for key in list(item_dictionary.keys()): frequency.write(str(key.capitalize()) + " " + str(item_dictionary[key]) + "\n") item_list.close() frequency.close() def item_list_frequency(): # a function to get the number of times each item appears text = open("inputFile.txt", "r") #open the file item_dictionary = dict() # dictionary to store the items for line in text: line = line.strip() item = line.lower() if item in item_dictionary: item_dictionary[item] = item_dictionary[item] + 1 else: item_dictionary[item] = 1 for key in list(item_dictionary.keys()): print(key.capitalize(), ":", item_dictionary[key]) text.close()
inputFile.txt
Spinach Radishes Broccoli Peas Cranberries Broccoli Potatoes Cucumbers Radishes Cranberries Peaches Zucchini Potatoes Cranberries Cantaloupe Beets Cauliflower Cranberries Peas Zucchini Peas Onions Potatoes Cauliflower Spinach Radishes Onions Zucchini Cranberries Peaches Yams Zucchini Apples Cucumbers Broccoli Cranberries Beets Peas Cauliflower Potatoes Cauliflower Celery Cranberries Limes Cranberries Broccoli Spinach Broccoli Garlic Cauliflower Pumpkins Celery Peas Potatoes Yams Zucchini Cranberries Cantaloupe Zucchini Pumpkins Cauliflower Yams Pears Peaches Apples Zucchini Cranberries Zucchini Garlic Broccoli Garlic Onions Spinach Cucumbers Cucumbers Garlic Spinach Peaches Cucumbers Broccoli Zucchini Peas Celery Cucumbers Celery Yams Garlic Cucumbers Peas Beets Yams Peas Apples Peaches Garlic Celery Garlic Cucumbers Garlic Apples Celery Zucchini Cucumbers Onions
Statistics For Business Decision Making And Analysis
ISBN: 9780321890269
2nd Edition
Authors: Robert Stine, Dean Foster