Missing print task when generator is invoked - generator

I have written the following code to produce pascal-triangle like pattern for three different heights. Each time, a different character is used to get the pattern. I am able to get the ones with '*' and '&', but the second call for printing with '=' never gets invoked. So, the corresponding pattern is missing on the screen. Tried to debug by interleaving input() statement between the three calls, but of no avail. Please help.
def draw_triangle(pattern_values):
def draw(ht, ch):
for i in range(1, ht+1):
print('{txt:^{wid}}'.format(txt=i*(ch+' '),wid=2*ht))
draw(pattern_values[0], pattern_values[1])
yield pattern_values
while True:
pattern_values = yield pattern_values
draw(pattern_values[0], pattern_values[1])
pattern_series = draw_triangle([10, '*'])
next(pattern_series)
pattern_series.send([12, '=']) # This does not produce any output
pattern_series.send([14, '&'])

So you can just use this fuction as generator without initial values.
def draw_triangle(pattern_values=""):
def draw(ht, ch):
for i in range(1, ht+1):
print('{txt:^{wid}}'.format(txt=i*(ch+' '),wid=2*ht))
while True:
pattern_values = yield pattern_values
draw(pattern_values[0], pattern_values[1])
pattern_series = draw_triangle()
next(pattern_series)
pattern_series.send([10, '*'])
pattern_series.send([12, '=']) # This does not produce any output
pattern_series.send([14, '&'])

Related

Why am I not being able of detecting a None value from a dictionary

I have seen this issue many times happening to many people (here). I am still struggling trying to validate whether what my dictionary captures from a JSON is "None" or not but I still get the following error.
This code is supposed to call a CURL looking for the 'closed' value in the 'status' key until it finds it (or 10 times). When payment is done by means of a QR code, status changes from opened to closed.
status = (my_dict['elements'][0]['status'])
TypeError: 'NoneType' object is not subscriptable
Any clue of what am I doing wrong and how can I fix it?
Also, if I run the part of the script that calls the JSON standalone, it executes smoothly everytime. Is it anything in the code that could be affecting the CURL execution?
By the way, I have started programming 1 week ago so please excuse me if I mix concepts or say something that lacks of common sense.
I have tried to validate the IF with "is not" instead of "!=" and also with "None" instead of "".
def show_qr():
reference_json = reference.replace(' ','%20') #replaces "space" with %20 for CURL assembly
url = "https://api.mercadopago.com/merchant_orders?external_reference=" + reference_json #CURL URL concatenate
headers = CaseInsensitiveDict()
headers["Authorization"] = "Bearer MY_TOKEN"
pygame.init()
ventana = pygame.display.set_mode(window_resolution,pygame.FULLSCREEN) #screen settings
producto = pygame.image.load("qrcode001.png") #Qr image load
producto = pygame.transform.scale(producto, [640,480]) #Qr size
trials = 0 #sets while loop variable start value
status = "undefined" #defines "status" variable
while status != "closed" and trials<10: #to repeat the loop until "status" value = "closed"
ventana.blit(producto, (448,192)) #QR code position setting
pygame.display.update() #
response = requests.request("GET", url, headers=headers) #makes CURL GET
lag = 0.5 #creates an incremental 0.5 seconds everytime return value is None
sleep(lag) #
json_data = (response.text) #Captures JSON response as text
my_dict = json.loads(json_data) #creates a dictionary with JSON data
if json_data != "": #Checks if json_data is None
status = (my_dict['elements'][0]['status']) #If json_data is not none, asigns 'status' key to "status" variable
else:
lag = lag + 0.5 #increments lag
trials = trials + 1 #increments loop variable
sleep (5) #time to avoid being banned from server.
print (trials)
From your original encountered error, it's not clear what the issue is. The problem is that basically any part of that statement can result in a TypeError being raised as the evaluated part is a None. For example, given my_dict['elements'][0]['status'] this can fail if my_dict is None, or also if my_dict['elements'] is None.
I would try inserting breakpoints to better assist with debugging the cause. another solution that might help would be to wrap each part of the statement in a try-catch block as below:
my_dict = None
try:
elements = my_dict['elements']
except TypeError as e:
print('It possible that my_dict maybe None.')
print('Error:', e)
else:
try:
ele = elements[0]
except TypeError as e:
print('It possible that elements maybe None.')
print('Error:', e)
else:
try:
status = ele['status']
except TypeError as e:
print('It possible that first element maybe None.')
print('Error:', e)
else:
print('Got the status successfully:', status)

When using the frame skipping wrapper for OpenAI Gym, what is the purpose of the np.max line?

I'm implementing the following wrapper used commonly in OpenAI's Gym for Frame Skipping. It can be found in dqn/atari_wrappers.py
I'm very confused about the following line:
max_frame = np.max(np.stack(self._obs_buffer), axis=0)
I have added comments throughout the code for the parts I understand and to aid anyone who may be able to help.
np.stack(self._obs_buffer) stacks the two states in _obs_buffer.
np.max returns the maximum along axis 0.
But what I don't understand is why we're doing this or what it's really doing.
class MaxAndSkipEnv(gym.Wrapper):
"""Return only every 4th frame"""
def __init__(self, env=None, skip=4):
super(MaxAndSkipEnv, self).__init__(env)
# Initialise a double ended queue that can store a maximum of two states
self._obs_buffer = deque(maxlen=2)
# _skip = 4
self._skip = skip
def _step(self, action):
total_reward = 0.0
done = None
for _ in range(self._skip):
# Take a step
obs, reward, done, info = self.env.step(action)
# Append the new state to the double ended queue buffer
self._obs_buffer.append(obs)
# Update the total reward by summing the (reward obtained from the step taken) + (the current
# total reward)
total_reward += reward
# If the game ends, break the for loop
if done:
break
max_frame = np.max(np.stack(self._obs_buffer), axis=0)
return max_frame, total_reward, done, info
At the end of the for loop the self._obs_buffer holds the last two frames.
Those two frames are then max-pooled over, resulting in an observation, that contains some temporal information.

Python how to define a function that only accepts an integer input that can be used for multiple lines

I am trying to make a program that has a user input numbers into multiple different lines of code and I am trying to make it so that if the user inputs something other than a number the program will ask the user again to input the number correctly. I was trying to define a function that I could use for all of them but every time I run the program, it crashes. Any help would be much appreciated, thank you.
My code:
def error():
global m1
global m2
global w1
global w2
while True:
try:
int(m1 or m2 or w1 or w2)
except ValueError:
try:
float(m1 or m2 or w1 or w2)
except ValueError:
m1 or m2 or w1 or w2=input("please input your response correctly...")
break
m1=input("\nWhat was your first marking period percentage?")
error()
w1=input("\nWhat is the weighting of the first marking period? (in decimal)")
error()
m2=input("\nWhat was your second marking period percentage?")
error()
w2=input("\nWhat is the weighting of the second marking period? (in decimal)")
error()
def user_input(msg):
inp = input(msg)
try:
return int(inp) if inp.isnumeric() else float(inp)
except ValueError as e:
return user_input("Please enter a numeric value")
m1=user_input("\nWhat was your first marking period percentage?")
w1=user_input("\nWhat is the weighting of the first marking period? (in decimal)")
m2=user_input("\nWhat was your second marking period percentage?")
w2=user_input("\nWhat is the weighting of the second marking period? (in decimal)")
You should write your function to get one number at a time. If at exception is triggered somewhere, it should be handled. Note how the get_number function shown below will keep asking for a number but also shows the prompt specified by its caller. If you are not running Python 3.6 or higher, you will need to comment out the call to print in the main function.
#! /usr/bin/env python3
def main():
p1 = get_number('What is your 1st marking period percentage? ')
w1 = get_number('What is the weighting of the 1st marking period? ')
p2 = get_number('What is your 2nd marking period percentage? ')
w2 = get_number('What is the weighting of the 2nd marking period? ')
score = calculate_score((p1, p2), (w1, w2))
print(f'Your score is {score:.2f}%.')
def get_number(prompt):
while True:
try:
text = input(prompt)
except EOFError:
raise SystemExit()
else:
try:
number = float(text)
except ValueError:
print('Please enter a number.')
else:
break
return number
def calculate_score(percentages, weights):
if len(percentages) != len(weights):
raise ValueError('percentages and weights must have same length')
return sum(p * w for p, w in zip(percentages, weights)) / sum(weights)
if __name__ == '__main__':
main()
By the following code you can able to make a function that only accept integer value:
def input_type(a):
if(type(10)==type(a)):
print("integer")
else:
print("not integer")
a=int(input())
input_type(a)

World of tanks Python list comparison from json

ok I am trying to create a definition which will read a list of IDS from an external Json file, Which it is doing. Its even putting the data into the database on load of the program, my issue is this. I cant seem to match the list IDs to a comparison. Here is my current code:
def check(account):
global ID_account
import json, httplib
if not hasattr(BigWorld, 'iddata'):
UID_DB = account['databaseID']
UID = ID_account
try:
conn = httplib.HTTPConnection('URL')
conn.request('GET', '/ids.json')
conn.sock.settimeout(2)
resp = conn.getresponse()
qresp = resp.read()
BigWorld.iddata = json.loads(qresp)
LOG_NOTE('[ABRO] Request of URL data successful.')
conn.close()
except:
LOG_NOTE('[ABRO] Http request to URL problem. Loading local data.')
if UID_DB is not None:
list = BigWorld.iddata["ids"]
#print (len(list) - 1)
for n in range(0, (len(list) - 1)):
#print UID_DB
#print list[n]
if UID_DB == list[n]:
#print '[ABRO] userid located:'
#print UID_DB
UID = UID_DB
else:
LOG_NOTE('[ABRO] userid not set.')
if 'databaseID' in account and account['databaseID'] != UID:
print '[ABRO] Account not active in database, game closing...... '
BigWorld.quit()
now my json file looks like this:
{
"ids":[
"1001583757",
"500687699",
"000000000"
]
}
now when I run this with all the commented out prints it seems to execute perfectly fine up till it tries to do the match inside the for loop. Even when the print shows UID_DB and list[n] being the same values, it does not set my variable, it doesn't post any errors, its just simply acting as if there was no match. am I possibly missing a loop break? here is the python log starting with the print of the length of the table print:
INFO: 2
INFO: 1001583757
INFO: 1001583757
INFO: 1001583757
INFO: 500687699
INFO: [ABRO] Account not active, game closing......
as you can see from the log, its never printing the User located print, so it is not matching them. its just continuing with the loop and using the default ID I defined above the definition. Anyone with an idea would definitely help me out as ive been poking and prodding this thing for 3 days now.
the answer to this was found by #VikasNehaOjha it was missing simply a conversion to match types before the match comparison I did this by adding in
list[n] = int(list[n])
that resolved my issue and it finally matched comparisons.

How to obtain a random word using function and dictionary? (Python 3)

The user has to select a category. And from there, the program has to generate a random word from the category list. If the user selected an invalid category, the program will prompt the user to choose a category again (loop the askCat function again).
import random
#Make word dictionary
wordDict = {'Animals':['Giraffe','Dog','Dolphin','Rabbit','Butterfly'], \
'Fruits': ['Apple','Pineapple','Durian','Orange','Rambutan'], \
'Colours': ['Red','Blue','Yellow','Green','Purple'], \
'Shapes': ['Heart','Circle','Rectangle','Square','Diamond']}
#Determine word category and random word
def askCat (wordDict):
category = str( input ("To start the game, please choose a category: \n Animals (a), Fruits (f), Colours (c), Shapes (s) "))
print()
if category == 'a':
print ("You chose the Animals category.")
cat = (wordDict['Animals'])
elif category == 'f':
print ("You chose the Fruits category.")
cat = (wordDict['Animals'])
elif category == 'c':
print ("You chose the Colours category.")
cat = (wordDict['Animals'])
elif category == 's':
print ("You chose the Shapes category.")
cat = (wordDict['Animals'])
else:
print ("You entered an invalid category. Try again!")
print()
askCat(wordDict)
return random.choice(cat)
#Print random word
randWord = askCat(wordDict)
print (randWord)
When on the first try, the user enter a valid category, the program works just fine. However, the problem I'm facing is that, when the user enter an invalid category the first time, and when he enter a valid category the second time, the program don't work anymore.
Please do help! Thanks (:
else:
print ("You entered an invalid category. Try again!")
print()
askCat(wordDict)
return random.choice(cat)
In the else branch, you are recursively calling the function again—which is okay—and then you discard its return value and return cat instead which, in this call of the function, was never set.
Instead, you should return the value from the recursive call:
else:
print ("You entered an invalid category. Try again!")
print()
return askCat(wordDict)
return random.choice(cat)
That way, when you call it recursively, the result from that call will be used, and not the one you tried to get from the current cat.
Furthermore, in each of your branches, you are doing cat = (wordDict['Animals']); you probably want to change that so you actually get fruits for f etc.
And finally, while using recursion is okay, it’s not the best way to handle this. Recursion always has a maximum depth it can into, so in the worst case, a user could keep answering the wrong thing increasing the recursion stack further, until the program errors out. If you want to avoid that, you should use a standard loop instead:
cat = None
while not cat:
# You don’t nee to use `str()` here; input always returns a string
category = input("To start the game, please choose a category: \n Animals (a), Fruits (f), Colours (c), Shapes (s) ")
print()
if category == 'a':
print("You chose the Animals category.")
cat = wordDict['Animals'] # no need to use parentheses here
elif category == 'f':
# ...
# and so on
else:
print("You entered an invalid category. Try again!")
# the loop will automatically repeat, as `cat` wasn’t set
# when we reach here, `cat` has been set
return random.choice(cat)
In your function askCat, if the user first enter a wrong category, you call again askCat. However, you don't return the value returned by that call.
Replace (in the function askCat):
askCat(wordDict)
to:
return askCat(wordDict)
However, I would strongly recommend you to use a while loop instead.