'How do I get a function to return the frequency of a specific item from a dictionary?

I trying to create a program that combines C++ and Python that opens and reads a text file of grocery items. The first function ListItemsPurchased works and it returns all items purchased along with their frequencies. However, I am currently working on a function called FrequencyOfItem. Once it is called, it is supposed to return the frequency of a specific item entered by the user in the C++ file and then passed on to the function in the Python file. But whenever I call the function, I get an error saying "Local variable 'item_frequency' referenced before assignment." Can someone help me with this?

C++ file

#include <Python.h>
#include <iostream>
#include <Windows.h>
#include <cmath>
#include <string>

using namespace std;

/*
Description:
To call this function, simply pass the function name in Python that you wish to call.
*/
void CallProcedure(string pName)
{
char* procname = new char[pName.length() + 1];
std::strcpy(procname, pName.c_str());

Py_Initialize();
PyObject* my_module = PyImport_ImportModule("setup");
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
*/
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*)"setup");
    // 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 function you wish to call and the 
string parameter you want to send
*/
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*)"setup");
// 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);
}

// Displays a list of options to user
void displayMenu() {
cout << endl;
cout << "1: Produce a list of all items purchased in a day" << endl;
cout << "2: Produce a number respresenting how many times an item was purchased" << 
endl;
cout << "3: Produce a histogram listing all items purchased in a day" << endl;
cout << "4: Exit the program" << endl;
cout << "Enter your selection as a number 1, 2, 3, 4." << endl;
}

void menuSelection() {
    int option;
    string item;
    do
    {
        displayMenu();
        cin >> option;
        if (option == 1) {
            // Calls function from Python file
            CallProcedure("ListItemsPurchased");
        }
        else if (option == 2) {
            cout << "Enter an item: " << endl;
            cin >> item;
            // Calls function from Python file
            cout << callIntFunc("FrequencyOfItem", item);
        }
        else if (option == 3) {
            // Calls function from Python file
            cout << callIntFunc("ItemHistogram", item);
        }
        else if (option == 4) {
            cout << endl;
            cout << "You have exited the application." << endl;
            break;
        }
        else {
            cout << "You have entered an invalid input." << endl;
        }
    } while (option != 4);
}


void main()
{

menuSelection();

}

Python file

import re
import string

def ListItemsPurchased():
    frequency = {}
    with open('GroceryList.txt') as file:
        # Finds the frequency of each word in the text file 
        for word in file:
            count = frequency.get(word,0)
            frequency[word] = count + 1
        # Allows us to see our keys 
        frequency_list = frequency.keys()
        # Gets the word and its frequency
        for words in frequency_list:
            print (words, frequency[words])
    file.close()

    return None

def FrequencyOfItem(item):
    frequency = {}
    with open('GroceryList.txt') as file:
        # Finds the frequency of each word in the text file 
        for word in file:
            count = frequency.get(word,0)
            frequency[word] = count + 1
        # Allows us to see our keys 
        frequency_list = frequency.keys()
        # Gets frequency of item
        for words in frequency_list:
            if words == item:
                item_frequency = frequency[words]
    return item_frequency


Solution 1:[1]

As @jarmod has suggested in a comment, you can fix your code by initializing item_frequency outside the for loop to avoid the error you're seeing:

        def FrequencyOfItem(item):
            frequency = {}
            item_frequency = 0
            with open('GroceryList.txt') as file:
                # Finds the frequency of each word in the text file 
                for word in file:
                    count = frequency.get(word,0)
                    frequency[word] = count + 1
                # Allows us to see our keys 
                frequency_list = frequency.keys()
                # Gets frequency of item
                for words in frequency_list:
                    if words == item:
                        item_frequency = frequency[words]
            return item_frequency

Also, not sure if you are specifically attempting to roll your own frequency counting logic, but if not I thought I'd mention that in the collections module in Python there's a class called Counter that can help with this:

        def FrequencyOfItem(item):
            with open('GroceryList.txt') as file:
                # Finds the frequency of each word in the text file 
                words = Counter(word for word in file)
                return words[item]

UPDATED: Because there's no test file provided, I've created the following version of the above code (both your original approach and the Counter approach) with a hardcoded test case. To try it with your file, just change TESTING from True to False in two places:

        def GetItemsFromFile():
            words = []
            with open('GroceryList.txt') as file:
                for word in file:
                    words += word
            return words
        def GetItemsFromTestCase():
            return ["Spinach", "Olives", "Spinach", "Olives", "Olives", "Spinach", "Spinach", "Spinach", "Gravy"]
        def FrequencyOfItem(item):
            frequency = {}
            item_frequency = 0
            TESTING = True # change to False to use with input file
            groceryList = GetItemsFromTestCase() if TESTING else GetItemsFromFile()
            for word in groceryList:
                count = frequency.get(word,0)
                frequency[word] = count + 1
            # Allows us to see our keys 
            frequency_list = frequency.keys()
            # Gets frequency of item
            for words in frequency_list:
                if words == item:
                    item_frequency = frequency[words]
            return item_frequency        
        def FrequencyOfItem_2(item):
            TESTING = True # change to False to use with input file
            groceryList = GetItemsFromTestCase() if TESTING else GetItemsFromFile()
            words = Counter(word for word in groceryList)
            return words[item]        
        print(FrequencyOfItem("Spinach"))
        print(FrequencyOfItem_2("Spinach"))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1