-1

I'm writing a code for Telegram Bot. I want to feed in series of images as an input. for that I'm using counter variable count = 0 in order to count the number of images. However, I obtain exception when feeding in second image and so on. Exception says my variable is being referenced as local variable, whereas I made it global. What problem may be?

from telegram import (ReplyKeyboardMarkup, ReplyKeyboardRemove)
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters, RegexHandler,
                          ConversationHandler)
import requests
import logging
import matplotlib.pyplot as plt
from PIL import Image
from matplotlib import patches
from io import BytesIO




# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

logger = logging.getLogger(__name__)

GENDER, PHOTO, LOCATION, BIO = range(4)


face_api_url = 'https://example.com'


headers = { 'Ocp-Apim-Subscription-Key': 'TOKEN' }

params = {
    'userID': '74'
}


saveResult = ""
count = 0
emArray = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

def start(bot, update):
    update.message.reply_text('Send me five photos and you will recieve your emotion')

    return PHOTO



def gender(bot, update):
    response = requests.post(face_api_url, params=params, headers=headers, json={"url": img_url})
    faces = response.json()
    image_file = BytesIO(requests.get(img_url).content)
    image = Image.open(image_file)
    for face in faces:
        fa = face["faceAttributes"]
        em = fa["emotion"]

        if (count < 4):
            for i in em:
                newTmp = em[str(i)]
                logger.info(count)
                emArray[em.keys().index(i)] += newTmp
            count += 1    
        elif (count>4):        
            saveResult += "sadness: " + str(emArray[0]/500) + "%\n"
            saveResult += "neutral: " + str(emArray[1]/500) + "%\n"
            saveResult += "contempt: " + str(emArray[2]/500) + "%\n"
            saveResult += "disgust: " + str(emArray[3]/500) + "%\n"
            saveResult += "anger: " + str(emArray[4]/500) + "%\n"
            saveResult += "surprise: " + str(emArray[5]/500) + "%\n"
            saveResult += "fear: " + str(emArray[6]/500) + "%\n"
            saveResult += "happiness: " + str(emArray[7]/500) + "%\n"        
            update.message.reply_text(saveResult)



def photo(bot, update):
    user = update.message.from_user
    photo_file = bot.get_file(update.message.photo[-1].file_id)
    global img_url
    img_url = str(photo_file.file_path)
    update.message.reply_text("Wait a little bit")
    gender(bot, update)
    #return GENDER


def skip_photo(bot, update):
    user = update.message.from_user
    logger.info("User %s did not send a photo.", user.first_name)
    update.message.reply_text('I bet you look great! Now, send me your location please, '
                              'or send /skip.')

    return LOCATION


def location(bot, update):
    user = update.message.from_user
    user_location = update.message.location
    logger.info("Location of %s: %f / %f", user.first_name, user_location.latitude,
                user_location.longitude)
    update.message.reply_text('Maybe I can visit you sometime! '
                              'At last, tell me something about yourself.')

    return BIO


def skip_location(bot, update):
    user = update.message.from_user
    logger.info("User %s did not send a location.", user.first_name)
    update.message.reply_text('You seem a bit paranoid! '
                              'At last, tell me something about yourself.')

    return BIO


def bio(bot, update):
    user = update.message.from_user
    logger.info("Bio of %s: %s", user.first_name, update.message.text)
    update.message.reply_text('Thank you! I hope we can talk again some day.')

    return ConversationHandler.END


def cancel(bot, update):
    user = update.message.from_user
    logger.info("User %s canceled the conversation.", user.first_name)
    update.message.reply_text('Bye! I hope we can talk again some day.',
                              reply_markup=ReplyKeyboardRemove())

    return ConversationHandler.END


def error(bot, update, error):
    """Log Errors caused by Updates."""
    logger.warning('Update "%s" caused error "%s"', update, error)


def main():
    # Create the EventHandler and pass it your bot's token.
    updater = Updater("TOKEN")
    # global count
    # global emArray
    # global saveResult
    # saveResult = ""
    # count = 0
    # emArray = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # Add conversation handler with the states GENDER, PHOTO, LOCATION and BIO
    conv_handler = ConversationHandler(
        entry_points=[CommandHandler('start', start)],

        states={
            GENDER: [RegexHandler('^(Boy|Girl|Other)$', gender)],

            PHOTO: [MessageHandler(Filters.photo, photo),
                    CommandHandler('skip', skip_photo)],

            LOCATION: [MessageHandler(Filters.location, location),
                       CommandHandler('skip', skip_location)],

            BIO: [MessageHandler(Filters.text, bio)]
        },

        fallbacks=[CommandHandler('cancel', cancel)]
    )

    dp.add_handler(conv_handler)

    # log all errors
    dp.add_error_handler(error)

    # Start the Bot
    updater.start_polling()

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()


if __name__ == '__main__':
    main()

Here exception is being throwed

if (count < 4):
    for i in em:
        newTmp = em[str(i)]
        logger.info(count)
        emArray[em.keys().index(i)] += newTmp
    count += 1    
Okzhetpes
  • 164
  • 1
  • 1
  • 8
  • 3
    # global count..... it is commented? – Rakesh Mar 20 '18 at 07:46
  • Can you iterate on "emotion"? Looking at the [documentation](https://westus.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236) it looks like it's just an object. – Jon Mar 20 '18 at 07:52
  • Possible duplicate of [UnboundLocalError in Python](https://stackoverflow.com/questions/9264763/unboundlocalerror-in-python) – cdarke Mar 20 '18 at 08:01

1 Answers1

3

You need to use

global count

in each function that is assigning to count

def gender(bot, update):
    global count
    ...

and

def main():
    global count
    ...

Better would be to avoid the global. Just make count a local variable in main and pass it in and out of gender etc.

def gender(bot, update, count):
    ...
    return count
John La Rooy
  • 295,403
  • 53
  • 369
  • 502