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.

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

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Algorithms Questions!