how to skip the rest of a sequence - python

I have a couple of functions that are being called recursively inside nested loops. The ultimate objective of my program is to:
a) loop through each year,
b) within each each year, loop through each month (12 total),
c) within each month, loop through each day (using a self generated day counter),
d) and read 2 files and merge them together into a another file.
In each instance, I am going down into the directory only if exists. Otherwise, I'm to just skip it and go to the next one. My code does a pretty good job when all the files are present, but when one of the files is missing, I would like to just simply skip the whole process of creating a merged file and continue the loops. The problem I am getting is a syntax error that states that continue is not properly in the loop. I am only getting this error in the function definitions, and not outside of them.
Can someone explain why I'm getting this error?
import os, calendar
file01 = 'myfile1.txt'
file02 = 'myfile2.txt'
output = 'mybigfile.txt'
def main():
#ROOT DIRECTORY
top_path = r'C:\directory'
processTop(top_path)
def processTop(path):
year_list = ['2013', '2014', '2015']
for year in year_list:
year_path = os.path.join(path, year)
if not os.path.isdir(year_path):
continue
else:
for month in range(1, 13):
month_path = os.path.join(year_path, month)
if not os.path.isdir(month_path):
continue
else:
numDaysInMth = calendar.monthrange(int(year), month)[1]
for day in range(1, numDaysInMth+1):
processDay(day, month_path)
print('Done!')
def processDay(day, path):
day_path = os.path.join(path, day)
if not os.path.isdir(day_path):
continue
else:
createDailyFile(day_path, output)
def createDailyFile(path, dailyFile):
data01 = openFile(file01, path)
data02 = openFile(file02, path)
if len(data01) == 0 or len(data02) == 0:
# either file is missing
continue
else:
# merge the two datalists into a single list
# create a file with the merged list
pass
def openFile(filename, path):
# return a list of contents of filename
# returns an empty list if file is missing
pass
if __name__ == "__main__": main()

You can use continue only plainly inside a loop (otherwise, what guarantee you have that the function was called in a loop in the first place?) If you need stack unwinding, consider using exceptions (Python exception handling).
I think you can get away with having your functions return a value that would say if operation was completed successfully:
def processDay(day, path):
do_some_job()
if should_continue:
return False
return True
And then in your main code simply say
if not processDay(day, path):
continue

You are probably getting that error in processDay and createDailyFile, right? That's because there is no loop in these functions, and yet you use continue. I'd recommend using return or pass in them.

The continue statement only applies in loops as the error message implies if your functions are structured as you show you can just use pass.

continue can only appear in a loop since it tells python not to execute the lines below and go to the next iteration. Hence, this syntax here is not valid :
def processDay(day, path):
day_path = os.path.join(path, day)
if not os.path.isdir(day_path):
continue # <============ this continue is not inside a loop !
else:
createDailyFile(day_path, output)enter code here
Same for your createDailyFile function.
You may want to replace it with a return ?

Related

How do I run a conditional statement "only once" and every time it changes?

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.

Python - Recursive Loop is stuck

I want to set up a recursive loop to iterate over different levels of a transaction tree until a predefined depth is reached.
Example:
A transfers funds to B and C (depth 1)
- B transfers funds to D and E (depth 2)
- C transfers funds to F and G (depth 2)
etc.
To do so, I have set up the following function:
def traverse(target, depth):
try:
print('Starting analysis of parent address {}'.format(target))
result=callAddress(target)
inner_transaction_targets=analyseTransaction(result)
traversed_addresses=compileAddresses(compiled_receiver_addresses,inner_transaction_targets) #Compile list of start addresses
if depth > 0:
for inner in inner_transaction_targets:
print('Starting analysis of child address {} at depth {}.'.format(inner,depth))
inner_transaction_targets=inner_transaction_targets.pop(0)
print(inner_transaction_targets)
return traverse(inner, depth-1)
else:
return traversed_addresses
except:
print('Could not traverse.')
The functions callAdress, analyseTransaction and compileAdresses themselves should not be relevant to this problem. However to offer a brief description:
analyseTransaction will offer a list of all receiver addresses involved in a given transaction
compileAdresses collects the scanned addresses in a master list
See here the other functions:
def callAddress(bitcoin_address): #This function serves to retrieve the JSON respose from blockchain.info
try:
r = requests.get("https://blockchain.info/address/{}?format=json".format(bitcoin_address))
unparsed=r.content
parsed = json.loads(unparsed)
return parsed
except: #unparsed.status=="400":
print ("Incorrect bitcoin address")
def compileAddresses(compiled_receiver_addresses,input_addr): #This function serves to add extracted transactions to a master list (compiled_receiver_addresses)
try:
compiled_receiver_addresses.append(input_addr)
return compiled_receiver_addresses
except:
print('Failed to compile')
def analyseTransaction(response): #This function serves to extract the wallet addresses that the specified wallet has sent funds to (transaction targets)
try:
transaction_targets=[]
wallet_transactions=response['txs']
for txs_entry in wallet_transactions:
print ("{:=^22}".format(""))
print ("Checking outgoing transaction with Hash: {}".format(txs_entry['hash']))
print ("Transaction occured at: {}".format(datetime.fromtimestamp(
int(txs_entry['time']) ).strftime('%Y-%m-%d %H:%M:%S')))
print ("{:=^22}".format(""))
for out in txs_entry['out']:
outbound_addr=out['addr']
print ("In this transaction funds were sent to this wallet: {}".format(out['addr']))
print ("Amount sent: {}".format(int(out['value']) * 10**-8))
transaction_targets.append(outbound_addr)
cleaned_transaction_targets = list(dict.fromkeys(transaction_targets))
return cleaned_transaction_targets
except:
print('Dead End')
My issue is that the recursive loop keeps getting stuck on the first value, i.e. it is looping the very first value of "inner" over and over again instead of going down the list that is inner_transaction_targets
I have tried to drop the very first value in this list by using inner_transaction_targets.pop(0) but to no effect.
How do I have to modify this function so that it does what I want?
Your code has some errors that are most likely hindering its successful completion, such as:
The return is within a loop.
The object returned is in fact a self-reference to the traverse() function.
The .pop() method is not a good practice.
I would suggest you create a separate function that will return a single object for each inner transaction, much like what compile_addresses() does.
You then add this new function into the for loop so that it iterates over the inner_transaction_targets and appends the results to a list. Finally, you return the list with all the results, indented aligned with the if statement, outside the for loop.

how to re-iterate a for loop within a method in python?

I am trying to create an image recognition bot using OpenCV. I use multiple templates, therefore I have two main parts of the code:
1 - I run a for loop to append all the templates into a list:
template_data=[] #global variable
files1 = glob.glob('templates\\img_*.png')
for myfile in files1:
image = cv2.imread(myfile,cv2.IMREAD_UNCHANGED)
template_data.append(image)
2 - I use a method to match the templates:
click = [] #global variable
def findClickPositions():
for tmp in template_data: #this for loop works fine
result = cv2.matchTemplate(test_image, tmp, method)
locations = np.where(result >= threshold)
locations = list(zip(*locations[::-1]))
rectangles = [] #local variable
for loc in locations: #this for loop iterates only once!!
rect = [int(loc[0]), int(loc[1]), tmp_w, tmp_h] #rect for each loc
rectangles.append(rect)
print('rectangles')
click.append((x,y))
return click
So in order to run it forever, I use the main function, eg:
def main():
while True:
click = findClickPositions()
and calling it like so:
if __name__ == '__main__': main()
When I run the code, it runs the method and for loop inside that method, but when it iterates second time and more, it does not reiterate the for loop within the method findClickPositions().
In other words, it reruns the method as intended, but it runs the for loop inside the method only during the first iteration.
I believe it has something to do with the local variable rectangles = [] But I haven't found a solution yet.
Can anyone explain me what am I doing wrong?

Looping through a list of proxies

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())

Trying to write python CSV extractor

I am complete newbie for programming and this is my first real program I am trying to write.
So I have this huge CSV file (hundreds of cols and thousands of rows) where I am trying to extract only few columns based on value in the field. It works fine and I get nice output, but the problem arises when I am try to encapsulate the same logic in a function.
it returns only first extracted row however print works fine.
I have been playing for this for hours and read other examples here and now my mind is mush.
import csv
import sys
newlogfile = csv.reader(open(sys.argv[1], 'rb'))
outLog = csv.writer(open('extracted.csv', 'w'))
def rowExtractor(logfile):
for row in logfile:
if row[32] == 'No':
a = []
a.append(row[44])
a.append(row[58])
a.append(row[83])
a.append(row[32])
return a
outLog.writerow(rowExtractor(newlogfile))
You are exiting prematurely. When you put return a inside the for loop, return gets called on the first iteration. Which means that only the firs iteration runs.
A simple way to do this would be to do:
def rowExtractor(logfile):
#output holds all of the rows
ouput = []
for row in logfile:
if row[32] == 'No':
a = []
a.append(row[44])
a.append(row[58])
a.append(row[83])
a.append(row[32])
output.append(a)
#notice that the return statement is outside of the for-loop
return output
outLog.writerows(rowExtractor(newlogfile))
You could also consider using yield
You've got a return statement in your function...when it hits that line, it will return (thus terminating your loop). You'd need yield instead.
See What does the "yield" keyword do in Python?

Categories