why is my global variable still the same after update - python-3.x

i am creating a telegram bot using python and i can't update the global variable in the callback function please help
i have tried to updated the variable using global FLAG inside a callback function but the variable is still the same
FLAG = 0
def start_all(bot,update):
global FLAG
chat_id = update.message.chat_id
FLAG = 0
sell = telegram.KeyboardButton(text="buy")
buy = telegram.KeyboardButton(text="sell")
custom_keyboard =[[ sell, buy ]]
reply_markup = telegram.ReplyKeyboardMarkup(
custom_keyboard)
bot.send_message(chat_id=chat_id,
text="Thank you",
reply_markup=reply_markup
)
command= update.effective_message.text
if command == "buy":
buy = Buy()
FLAG = 1
buy.start(bot,update)
elif command == "sell":
sell = Sell()
FLAG = 2
sell.start(bot,update)
else:
#help
pass
def main():
updater = Updater('')
dp = updater.dispatcher
dp.add_handler(CommandHandler('test',test))
dp.add_handler(CommandHandler('start',start_all))
if FLAG == 1:
buy = Buy()
dp.add_handler(MessageHandler(Filters.location,
buy.start))
elif FLAG == 2:
sell = Sell()
dp.add_handler(MessageHandler(Filters.location, sell.insert_user_to_database))
elif FLAG == 0:
dp.add_handler(MessageHandler(Filters.text, start_all))
else:
pass
i expected the FLAG will be 1 when i click buy ,2 when i click sell and check if i clicked buy or sell in main function and handle the filters accordingly

I am pretty sure that the IF statement is incorrect here. Telegram update.message.text is not a string so the evaluation will always fail and go to pass.
Try changing it to:
command = str(update.message.text)
Edit:
Additionally it seems to me you should be using a query-structure like this:
def start(update, context):
keyboard = [[InlineKeyboardButton("BUY", callback_data='buy'),
InlineKeyboardButton("SELL", callback_data='sell')],
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text('WANT TO BUY OR SELL?', reply_markup=reply_markup)
updater.dispatcher.add_handler(CommandHandler('start', start))
def flag(update, context):
query = update.callback_query
command = str(update.callback_query.data)
if command == 'buy':
FLAG = 1
#do stuff
elif command == 'sell':
FLAG = 2
#do stuff
else:
pass
updater.dispatcher.add_handler(CallbackQueryHandler(flag))

Related

How would I tell if my user has focus on the terminal?

I am creating a chat room application using a CLI over a GUI, and I am on windows so I just use the default terminal in command prompt to run my code. My program detects individual key presses and then adds them to a list in my data class, which, when joined, creates the user's message. The only problem I'm having here is that the program records keypresses even when it is not in focus. Is there any way I can detect if the terminal is in focus or not so I can handle keypresses appropriately? What I have here at the moment is essentially an accidental keylogger of sorts.
My code (although not useful to the question I feel I should add it just in case):
import json, keyboard, os, socket, termcolor, threading
def addKey(key):
data.line.append(key)
data.lineLength += 1
def cls():
os.system("cls")
def display_chatLog():
return "\n".join(data.chatLog)
def display_lineLength():
return f"Characters: {data.lineLength}/{data.maxLineLength}\n\n"
def display_userInput():
return f"\n{data.start} {''.join(data.line)}{data.end}\n"
def enterPressed():
joinLine = " ".join(data.line)
if data.server:
if data.lineLength <= data.maxLineLength:
data.server.send(bytes(f"{data.username}: {joinLine}", "utf-8"))
data.line = []
else:
data.warning = "Your message is too long"
else:
if data.line[0] == "host":
port = data.line[1]
else:
IP = data.line[1]
port = data.line[2]
def getKeys():
specialKeys = ("backspace", "ctrl", "enter", "esc", "shift", "right shift", "space")
while True:
key = keyboard.read_event()
keyType = key.event_type
keyName = key.name
if keyType == "down":
if keyName not in specialKeys:
addKey(keyName)
elif keyName == "backspace":
if len(data.line) > 0:
del data.line[len(data.line) - 1]
data.lineLength -= 1
elif keyName == "enter":
enterPressed()
elif keyName == "shift":
if keyboard.is_pressed(f"shift+{keyName}") and keyName not in specialKeys:
addKey(keyName.upper)
elif keyName == "space":
addKey(" ")
class data:
chatLog = []
end = "_"
line = []
lineLength = 0
maxLineLength = 512
server = None
start = ">>>"
warning = "Make sure to either host a server using 'host (port)' or join one by using 'join (IP adress) (port)'"
getKeys_thread = threading.Thread(target = getKeys)
getKeys_thread.start()
while True:
cls()
print(display_chatLog(), display_userInput(), display_lineLength(), "\n", termcolor.colored(data.warning, "red", "on_white"))
import ctypes
def getWindow():
hwnd = ctypes.windll.user32.GetForegroundWindow()
length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
buff = ctypes.create_unicode_buffer(length + 1)
ctypes.windll.user32.GetWindowTextW(hwnd, buff, length + 1)
return (buff.value, hwnd) # buff.value is the title of the window, hwnd is the window handle
This code which I got from here and edited slightly allows me to capture the name and window handle of the currently focused window.

python simple help (NameError: name is not defined)

Whenever I run this is get:
Traceback (most recent call last):
File "main.py", line 130, in <module>
while is_playing_cg:
NameError: name 'is_playing_cg' is not defined
I want the user to be able to press 1 or 2 to select which game mode to use and then once pressed it starts. I don't know why it's doing this. Whenever it's fixed it should run through just fine.
New edit
Now it just loops and says 1 or 2 over and over again.
import random
is_playing_cg = False
is_playing_hg = False
def game_select_screen():
#Game Select Screen
print("""
._________________________________.
| |
| ~ Welcome To Guess-A-Number ~ |
| ~~~ |
| ~ Press 1 OR Press 2 ~ |
| You ^ Guess | PC ^ Guess |
|_________________________________|""")
selecting = True
while selecting:
print()
game_mode = input("1 OR 2: ")
try:
int(game_mode)
except ValueError:
print("This is not a Number.")
else:
game_mode = int(game_mode)
if game_mode == 1:
is_playing_hg = True
elif game_mode == 2:
is_playing_cg = True
#Defining Random Number for human guess
def play_human_guess():
num = random.randint (1,10)
print()
print("Im Thinking of a Number 1 Through 10.")
print("You Have 3 Chances.")
chances = 3
game_fisnished = False
#Game is playing (Human Guesses)
while not game_fisnished:
guess = input("> Take A Guess: ")
#Accept only numbers
try:
int(guess)
except ValueError:
print("This is not a Number.")
else:
guess = int(guess)
if guess < num:
chances -=1
if chances == 0:
print()
print("Sorry You Guessed Too Many Times.")
game_fisnished = True
elif chances !=0:
print()
print("You Guessed Too Low. ("+str(chances)+") Chance(s) Remaining.")
elif guess > num:
chances -=1
if chances == 0:
print()
print("Sorry You Guessed Too Many Times.")
game_fisnished = True
elif chances !=0:
print()
print("You Guessed Too High. ("+str(chances)+") Chance(s) Remaining.")
else:
print()
print("Congradulations, You Won!")
game_fisnished = True
#Game Ended
def end():
print()
print("Thanks For Playing!")
#Setting up for computer guess
def play_computer_guess():
print()
print("Pick a Number 1 Through 10")
print("I Have 3 Chances to Guess Your Number.")
chances = 3
game_fisnished = False
#Game is playing (Computer Guess)
while not game_fisnished:
guess1 = input("Is your number 5?")
#Show Game Select Screen
game_select_screen()
while is_playing_cg:
#Start Game
selecting = False
play_computer_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_cg = False
while is_playing_hg:
#Start Game
selecting = False
play_human_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_hg = False
end()
The variable is_playing_cg is only available in the "block" that creates it.
Block is function / loop / if statement / etc.
In your program you need to initialize the variable globally so you can call them in multiple functions.
Good luck!
You are defining is_playing_cg inside of a conditional statement at the top of your code. So if that option is not selected, then when you get to the latter conditional statement, it has never heard of that variable.... and it is not defined in the namespace. So you could either define it at the top and give it a default (False) or more better, because you only have 2 options, just use one variable to control the computer / human.
Here is a toy example:
selection = int(input('enter 1 for human, 2 for computer: '))
if selection == 1:
human_play = True
elif selection == 2:
human_play = False
else:
# make some loop that asks for input again or such...
pass
# later on...
if human_play:
# ask human for input...
else:
# have AI make turn
#if needed, you can also handle special cases like this:
if not human_play:
# do something unique to computer turn ...
Additional info...
So you got bit by the scope of the variables in your update. You are defining these variables inside of a function and when you put the defaults outside of the function, they are not in the same scope, so whatever you do inside the function is lost. So, you need to change your function into something that returns the mode you want, and catch that in the function call like such:
def ... :
# input ...
if game_mode == 1:
human_playing = True
selecting = False
elif game_mode == 2:
human_playing = False
selecting = False
return human_playing # this will return T/F back to the function call
And then later:
#Show Game Select Screen
human_playing = game_select_screen()
while not human_playing:
#Start Game
selecting = False
play_computer_guess()
answer = input("""
Do You Want to Play Again? (y/n) : """)
if answer == "n":
is_playing_cg = False
while human_playing:
#Start Game
This (above) works for me, but there are still other logic errors popping up! :) Have fun
This particular error is probably there because you have not defined is_playing_cg as global before using it in your function game_select_screen. Simply put global is_playing_cg at the start of your game_select_screen function to tell python you want to use the global variable instead of creating a scoped variable.

The position argument error and resolving it

I am trying to implement a shopping cart in python and have this code but the error is that when i am calling a print_menu function , the arguments are not correct.
class ItemToPurchase:
def __init__(self, item_name= 'none', item_price=0, item_quantity=0, item_description = 'none'):
self.item_name = item_name
self.item_price = item_price
self.item_quantity = item_quantity
self.item_description = item_description
def print_item_cost(self):
string = '{} {} # ${} = ${}'.format(self.item_name, self.item_quantity, self.item_price, (self.item_quantity* self.item_price))
cost = self.item_quantity * self.item_price
return string, cost
def print_item_description(self):
string = '{}: {}'.format(self.item_name, self.item_description)
print(string, end=' ')
return string
class ShoppingCart:
def __init__(self,customer_name= None ,current_date='January 1,2016',cart_items=[]):
self.customer_name = customer_name
self.current_date = current_date
self.cart_items = cart_items
def add_item(self):
print('\nADD ITEM TO CART', end='\n')
item_name = str(input('Enter the item name:'))
item_description = str(input('\nEnter the item description:'))
item_price = int(input('\nEnter the item price:'))
item_quantity = int(input('\nEnter the item quantity:\n'))
self.cart_items.append(ItemToPurchase(item_name, item_price, item_quantity, item_description))
def remove_item(self):
print()
print('REMOVE ITEM FROM CART', end='\n')
string = str(input('Enter name of item to remove:\n'))
i = 0
for item in self.cart_items:
if(item.item_name == string):
del self.cart_items[i]
i += 1
flag=True
break
else:
flag=False
if(flag==False):
print('Item not found in cart. Nothing removed.')
def modify_item(self):
print('\nCHANGE ITEM QUANTITY', end='\n')
name = str(input('Enter the item name:'))
for item in self.cart_items:
if(item.item_name == name):
quantity = int(input('Enter the new quantity:'))
item.item_quantity = quantity
flag=True
break
else:
flag=False
if(flag==False):
print('Item not found in cart. Nothing modified.')
def get_num_items_in_cart(self):
num_items = 0
for item in self.cart_items:
num_items += item.item_quantity
return num_items
def get_cost_of_cart(self):
total_cost = 0
cost = 0
for item in self.cart_items:
cost = (item.item_quantity * item.item_price)
total_cost += cost
return total_cost
def print_total(self):
total_cost = self.get_cost_of_cart()
if (total_cost == 0):
print('SHOPPING CART IS EMPTY')
else:
self.output_cart()
def print_descriptions(self):
print('OUTPUT ITEMS\' DESCRIPTIONS')
print('{}\'s Shopping Cart - {}'.format(self.customer_name, self.current_date),end='\n')
print('\nItem Descriptions', end='\n')
for item in self.cart_items:
print('{}: {}'.format(item.item_name, item.item_description), end='\n')
def output_cart(self):
new=ShoppingCart()
print('OUTPUT SHOPPING CART', end='\n')
print('{}\'s Shopping Cart - {}'.format(self.customer_name, self.current_date),end='\n')
print('Number of Items:', new.get_num_items_in_cart(), end='\n\n')
self.total_cost = self.get_cost_of_cart()
if (self.total_cost == 0):
print('SHOPPING CART IS EMPTY')
else:
pass
tc = 0
for item in self.cart_items:
print('{} {} # ${} = ${}'.format(item.item_name, item.item_quantity,
item.item_price, (item.item_quantity * item.item_price)), end='\n')
tc += (item.item_quantity * item.item_price)
print('\nTotal: ${}'.format(tc), end='\n')
def print_menu(ShoppingCart):
customer_Cart = newCart
string=' '
#declare the string menu
menu = ('\nMENU\n'
'a - Add item to cart\n'
'r - Remove item from cart\n'
'c - Change item quantity\n'
'i - Output items\' descriptions\n'
'o - Output shopping cart\n'
'q - Quit\n')
command = ''
#Using while loop
#to iterate until user enters q
while(command != 'q'):
string=''
print(menu, end='\n')
#Prompt the Command
command = input('Choose an option: ')
#repeat the loop until user enters a,i,r,c,q commands
while (command != 'a' and command != 'o' and command != 'i' and command != 'r' and command != 'c' and command != 'q'):
command = input('Choose an option: ')
#If the input command is a
if(command == 'a'):
#call the method to the add elements to the cart
customer_Cart.add_item(string)
#If the input command is o
if(command == 'o'):
#call the method to the display the elements in the cart
customer_Cart.output_cart()
#If the input command is i
if(command == 'i'):
#call the method to the display the elements in the cart
customer_Cart.print_descriptions()
#If the input command is i
if(command == 'r'):
customer_Cart.remove_item()
if(command == 'c'):
customer_Cart.modify_item()
if __name__ == "__main__":
customer_name = str(input('Enter customer\'s name:'))
current_date = str(input('\nEnter today\'s date:'))
print()
print()
print('Customer name:', customer_name, end='\n')
print('Today\'s date:', current_date, end='\n')
newCart = ShoppingCart(customer_name, current_date)
newCart.print_menu(newCart)
i have created an instance of class ShopppingCart but it is not working. i am trying to get a user input and then display the menu for user to choose and implement one of the functions defined in the shopping cart class . Can anyone help me with resolving this issue.
This issue is happening because of function's argument, ShoppingCart. You have called the first argument ShoppingCart, which in reality is the ShoppingCart object; usually this is the self argument. Python does not care what you name it: self, ShoppingCart, corona. The first argument will always be the object that called the function. When calling this function with these lines of code:
newCart = ShoppingCart(customer_name, current_date)
newCart.print_menu(newCart)
you are using the newCart object to call the function and then passing the newCart object as an argument. You don't need to do this. Python already passes the object, so you don't have to.
I'm assuming this is the error you received:
Traceback (most recent call last):
File "c:/Users/jeffg/Desktop/ProgrammingProjects/StackOverFlow/shoppingcart.py", line 246, in <module>
newCart.print_menu(newCart)
TypeError: print_menu() takes 1 positional argument but 2 were given
This error takes place because you're function is defined to only take one argument. You didn't account for the self argument. To fix this, the code would need to be modified to something like this:
def print_menu(self, newCart):
customer_Cart = newCart
Although as discussed before, you don't need the newCart object to be passed, since you already have access to the newCart object with self. You can then slim down the function to this:
def print_menu(self):
And instead of using customer_Cart to call the functions, you can use self:
while (command != 'a' and command != 'o' and command != 'i' and command != 'r' and command != 'c' and command != 'q'):
command = input('Choose an option: ')
if(command == 'a'):
self.add_item(string)
I would also recommend using elif statements instead of using numerous if statements inside your print_menu() function.

how to loop back to scetion if this is outcome

I want to loop the end section of the code if you get the 'Error, class not found'. I already tried a, for and while loop but i couldn't get it working.
Health = 0
Damage = 0
Classes = ['Mage','Knight']
Class = ''
print('Select Character Name.')
Name = input()
print('Hello',Name,'please choose your class.')
print('')
print('Mage: 5 Health: 7 Damage')
print('Knight: 7 Health : 5 Damage')
#looped section
Select = input()
if Select in ['Mage']:
print('Mage Selected')
Health = 5
Damage = 7
Class = 'Mage'
elif Select in ['Knight']:
print('Knight Selected')
Health = 7
Damage = 5
Class = 'Knight'
else:
print('Error, class not found')
#loop back if this is outcome
when facing problems like this, your default approach should be a while loop making sure that the loop will go on (virtually forever) if the defined conditions aren't met. so this is what you can do:
while True:
# looped section
Select = input()
if Select in ['Mage']:
print('Mage Selected')
Health = 5
Damage = 7
Class = 'Mage'
break # break the loop if selection is correct
elif Select in ['Knight']:
print('Knight Selected')
Health = 7
Damage = 5
Class = 'Knight'
break # break the loop if selection is correct
else:
print('Error, class not found, try again: ') # will start the loop over

Return to main function in python

Working on Python 3.4.3
Let's say I have created three fuctions:
def choosing(mylist=[]):
print("We will have to make a list of choices")
appending(mylist)
done = False
while(done == "False"):
confirm = input("Is your list complete?[Y/N]")
if(confirm == "Y"):
print("Yaay! Choices creation complete."
"{} choices have been added successfully".format(len(mylist)))
done = True
elif(confirm == "N"):
action = input("What do you want to do? [Append/Delete]")
if(action == "Append"):
appending(mylist)
done = False
elif(action == "Delete"):
removing(mylist)
done = False
def appending(mylist1 = []):
print("Please type EOF when you want to stop!")
while True:
c = input("Please enter EOF to stop adding. Please enter a choice: ")
if(c=="EOF"):
break
else:
mylist1.append(c)
print("You have inserted {} choices".format(len(mylist1)))
print("Please verify them below: ")
for x in range(0, len(mylist1)):
print(mylist1[x])
def removing(mylist2 = []):
print("Following are choices: ")
r = input("What do you want to remove? ")
mylist2.remove(r)
print("{} successfully removed!".format(r))
Now problem is I can't just call choices() in append or remove function as choices() function will call append again and again infinitely.
So how do I get back in choices after appending or removing data in list?
As suggested by tobias_k, you should add the contents of choices() into a while loop.
I also found
some other problems:
False does not equal "False", so your while loop never runs.
You use terms like mylist, mylist1, and mylist2 - it's better to rename these to choosing_list, appending_list, and removing_list, so it's clearer.
You also shouldn't use False to define a while loop - instead, make a variable, then set it to True. When you have to stop, set it to False.
Here is the code with those problems fixed:
def appending(appending_list = []):
print("Please type EOF when you want to stop!")
while True:
c = input("Please enter EOF to stop adding. Please enter a choice: ")
if(c=="EOF"):
break
else:
appending_list.append(c)
print("You have inserted {} choices".format(len(appending_list)))
print("Please verify them below: ")
for x in range(0, len(appending_list)):
print(appending_list[x])
return appending_list
def removing(removing_list = []):
print("Following are choices: ")
r = input("What do you want to remove? ")
removing_list.remove(r)
print("{} successfully removed!".format(r))
return removing_list
print("We will have to make a list of choices")
choosing_list = appending()
list_incomplete = True
while list_incomplete:
confirm = input("Is your list complete?[Y/N]")
if(confirm == "Y"):
print("Yaay! Choices creation complete."
"{} choices have been added successfully".format(len(choosing_list)))
list_incomplete = False
elif(confirm == "N"):
action = input("What do you want to do? [Append/Delete]")
if(action == "Append"):
choosing_list = appending(choosing_list)
elif(action == "Delete"):
choosing_list = removing(choosing_list)
Let me know if there's any problems with this code.

Resources