So I have been trying to find out a more beautiful way to actually do some fault and errors in a script I am working on.
Basically I have a json_resp = resp.json() who either gives me values or [] meaning either there is something or not.
Now the question I am having trouble with is that I don't know which way is the best to repeat a function if it is empty, shall I repeat the whole function or what else would be most "best reason" to solve it in a good way?
What I have done is that I changed the objects from the json resp to a len. If its 0 then repeat else do other stuff:
#json_resp['objects'] either has empty [] or not always.
json_resp = resp.json()
if len(json_resp['objects']) == 0:
print('Sleeping in 2 sec')
time.sleep(2)
run_method() #Shall I call the function to start over?
else:
print(len(json_resp['objects']))
continue do rest of the code
As you can see right now I am compare with len of the json_resp but what makes me unsure is that if it is a good way to actually call the function again? Wouldn't it have a limit or maybe delay the whole process... Im not sure but what is your thoughts of making this function "better, smarter, faster"?
My thought was maybe to either put a try except or while loop that? Let me know what you guys think
Python lists are faulty so you can just use if json_resp:
You can use recursion. Just make sure you have somewhere to break
I'd like to revise your code into:
max_iteration = 5
current_iteration = 0
def run_method():
current_iteration += 1
# Do other stuff. Requests I guess?
response = resp.json
if response:
# do something with the response
else:
if current_iteration == max_iteration:
return 'Maximum iterations reached: {}'.format(max_iteration)
timer = 2
print('Sleeping in {} seconds'.format(timer))
time.sleep(timer)
run_method()
Related
I might be asking a simple question. I have a python program that runs every minute. But I would like a block of code to only run once the condition changes? My code looks like this:
# def shortIndicator():
a = int(indicate_5min.value5)
b = int(indicate_10min.value10)
c = int(indicate_15min.value15)
if a + b + c == 3:
print("Trade posible!")
else:
print("Trade NOT posible!")
# This lets the processor work more than it should.
"""run_once = 0 # This lets the processor work more than it should.
while 1:
if run_once == 0:
shortIndicator()
run_once = 1"""
I've run it without using a function. But then I get an output every minute. I've tried to run it as a function, when I enable the commented code it sort of runs, but also the processing usage is more. If there perhaps a smarter way of doing this?
It's really not clear what you mean, but if you only want to print a notification when the result changes, add another variable to rembember the previous result.
def shortIndicator():
return indicate_5min.value5 and indicate_10min.value10 and indicate_15min.value15
previous = None
while True:
indicator = shortIndicator()
if previous is None or indicator != previous:
if indicator:
print("Trade possible!")
else:
print("Trade NOT possible!")
previous = indicator
# take a break so as not to query too often
time.sleep(60)
Initializing provious to None creates a third state which is only true the first time the while loop executes; by definition, the result cannot be identical to the previous result because there isn't really a previous result the first time.
Perhaps also notice the boolean shorthand inside the function, which is simpler and more idiomatic than converting each value to an int and checking their sum.
I'm guessing the time.sleep is what you were looking for to reduce the load of running this code repeatedly, though that part of the question remains really unclear.
Finally, check the spelling of possible.
If I understand it correctly, you can save previous output to a file, then read it at the beginning of program and print output only if previous output was different.
I am currently working on a function that is to loop through a list of functions and then restart back at the top once it reaches the bottom. So far this is the code that I have:
import time
createLimit = 100
proxyFile = 'proxies.txt'
def getProxies():
proxyList = []
with open(proxyFile, 'r') as f:
for line in f:
proxyList.append(line)
return proxyList
proxyList = getProxies()
def loopProxySwitch():
print("running")
current_run = 0
while current_run <= createLimit:
if current_run >= len(proxyList):
lengthOfList = len(proxyList)
useProxy = proxyList[current_run%lengthOfList]
print("Current Ip: "+useProxy)
print("Current Run: "+current_run)
print("Using modulus")
return useProxy
else:
useProxy = proxyList[current_run]
print("Current Ip: "+useProxy)
print("Current Run: "+current_run)
return useProxy
time.sleep(2)
print("Script ran")
loopProxySwitch()
The problem that I am having is that the loopProxySwitch function does not return or print anything within the while loop, however I don't see how it would be false. Here is the format of the text file with fake proxies:
111.111.111.111:2222
333.333.333.333:4444
444.444.444.444:5555
777.777.777.777:8888
919.919.919.919:0000
Any advice on this situation? I intend to incorporate this into a program that I am working on, however instead of cycling through the file on a timed interval, it would only loop on a certain returned condition (such as a another function letting the loop function know that some function has ran and that it is time to switch to the next proxy). If this is a bit confusing, I will be happy to elaborate and clear any confusion. Any suggestions, ideas, or fixes are appreciated. Thanks!
EDIT: Thanks to the comments below, I fixed the printing issue. However, the function does not loop through all the proxies... Any suggestions?
Nothing is printed because you return something before printing.
The loop will break the first time condition is met as it will return a value and exit the function without reaching the print statements(functions) and/or the next iteration.
BTW if you actually want to print the returned value you can print the function itself:
print(loopProxySwitch())
Having a little trouble parsing JSON with Python and I'm not really sure what the syntax is I'd need.
The structure looks like this
name = (json_data['JsonResultTitle']['Loc']['List'][0]['Events'][0]['Name'])
The numbers after List and Events can both change.
I was able to iterate through the List ones using something ugly like:
namecounter = 0
try:
name = (json_data['JsonResultTitle']['Loc']['List'][namecounter]['Events'][0]['Name'])
namecounter +=1
except:
print "stop"
And I could technically embed another loop in there which runs until another exception for the Events counter but there has to be a neater way of doing this.
Something like this might be neater but it still doesn't strike me as the right way of doing things either:
counter = 0
secondcounter = 0
for i in json_data['JsonResultTitle']:
try:
print i['Loc']['List'][counter]['Events'][0]['Name']
except:
print "no first"
counter +=1
try:
print i['Loc']['List'][counter]['Events'][secondcounter]['Name']
except:
print "no second"
secondcounter +=1
This might be blindingly obvious but I can't see the proper way of doing this.
I'd really appreciate a nudge in the right direction.
Seems like you just want a nested loop.
for item in json_data['JsonResultTitle']['Loc']['List']:
for event in item['Events']:
print event['Name']
I have the following piece of code:
for x in Listofurls:
function(urlquery)
function(htmlmining)
how the statement in function should be written
so that i can continue the loop moving to the next item
when the query does not match my research like
def(urlquery):
url=urlquery
Urlopen = urllib.request.urlopen(url)
Url_read = parse(Urlopen)
if 'text' not in Url_read.read():
#here is where i want a statement to stop and go to the next
#item in the loop like 'continue' in a for loop
You can use StopIteration to exit from all loops until it's caught;
try:
for i in range(10):
if i == 5:
raise StopIteration
else:
print i
except StopIteration:
print "Caught"
gives:
0
1
2
3
4
Caught
The StopIteration Exception is exactly that, an exception, not an error;
Raised by an iterator‘s next() method to signal that there are no
further values. This is derived from Exception rather than
StandardError, since this is not considered an error in its normal
application.
You can put it as deeply as you want in your nested loops, but you have to catch it at the level you want to break out of (i.e. the level at which you want to stop iteration) to.
Looking at your question, and trying to make sense of what you've written, it looks like you want to do something like this (maybe?)
for url in listOfURLs:
if urlquery(url):
htmlmining(url)
def urlquery(url):
page = parse(urllib.request.urlopen(url))
return 'text' in page.read():
#here is where i want a statement to stop and go to the next
#item in the loop like 'continue' in a for loop
This will then only run htmlmining(url) when 'text' is in the page you're parsing. If it's not, it will skip that entry and move onto the next one.
Have the inner function return True if you want to continue:
def urlquery(url):
urlopen = urllib.request.urlopen(url)
url_read = parse(urlopen)
if 'text' not in url_read.read():
# here is where I want a statement to stop and go to the next
return True
Then, the outer function can be:
for x in list_of_urls:
if urlquery(x):
continue
htmlmining(x)
Note that the code you posted was not valid Python. The above is my best guess as to what you meant.
Also, please read the Python style guide.
i finally found a solution to the question:
def urlquery(url):
urlopen = urllib.request.urlopen(url)
url_read = parse(urlopen)
if 'text' not in url_read.read():
return
else:
myurl='text' in url_read.read()
return myurl
and the for loop as follows:
for x in Listofurls:
TextAvailable=function(urlquery)
if not TextAvailable:
continue
function(htmlmining)
i am not sure this is the cleanest way to proceed but it works.
I have an IRC bot that I made for automating stuff.
Here's a snippet of it:
def analyseIRCText(connection, event):
global adminList, userList, commandPat, flood
userName = extractUserName(event.source())
userCommand = event.arguments()[0]
escapedChannel = cleanUserCommand(config.channel).replace('\\.', '\\\\.')
escapedUserCommand = cleanUserCommand(event.arguments()[0])
#print userName, userCommand, escapedChannel, escapedUserCommand
if flood.has_key(userName):
flood[userName] += 1
else:
flood[userName] = 1
... (if flood[userName] > certain number do...)
So the idea is that flood thing is a dictionary where a list of users who have entered in a command to the bot in the recent... some time is kept, and how many times they've said so and so within that time period.
Here's where I run into trouble. There has to be SOMETHING that resets this dictionary so that the users can say stuff every once in awhile, no? I think that a little thing like this would do the trick.
def floodClear():
global flood
while 1:
flood = {} # Clear the list
time.sleep(4)
But what would be the best way to do this?
At the end of the program, I have a little line called:
thread.start_new_thread(floodClear,())
so that this thing doesn't get called at gets stuck in an infinite loop that halts everything else. Would this be a good solution or is there something better that I could do?
Your logic should be enough. If you have say:
if flood.has_key(userName):
flood[userName] += 1
else:
flood[userName] = 1
if flood[userName] > say 8:
return 0
That should make your bot ignore the user if he has spammed too many times within your given time period. What you have there should also work to clear up your flood dictionary.