How do I loop my python code a specific number of times? - python

I've been struggling to loop my code a specific number of times. I've YouTubed mulitple videos on while statements for looping but it never works. I have gotten to a point where I managed to run the code but then once it ran once it started looping and listing number 1 - 10. I'm assuming this is because I specified <10 to loop. I don't think I'm understanding but I am a visual learner and the text examples aren't helping. Here's the code I would like to loop.
import urllib.request
import os
urllib.request.urlretrieve("https://websitewithimageonit.com/", "")
i = 0
while os.path.exists("image%s.jpg" % i):
i += 1
fh = open("image%s.jpg" % i, "w")
I tried to do it myself and used a while loop like this below. The code ran, saved 1 image but then just listed 1 - 10 in the PyCharm console.
import urllib.request
import os
import time
urllib.request.urlretrieve("https://websitewithimageonit.com/", "")
i = 0
while os.path.exists("image%s.jpg" % i):
i += 1
fh = open("image%s.jpg" % i, "w")
condition = 1
while condition < 10:
print(condition)
condition += 1
After it runs the code it prints this in the console
1
2
3
4
5
6
7
8
9
Process finished with exit code 0
Which I'm assuming is me messing up the while loop. Where am I going wrong? Thanks

I think you wanted to do something like:
i = 0
while os.path.exists(f"image{i}.jpg"):
with open(f"image{i}.jpg", "w") as fh:
#do stuff with the file here
#do other stuff here
#at the end of the loop, increment i
i += 1
Read the following for more info
https://www.geeksforgeeks.org/with-statement-in-python/
https://www.geeksforgeeks.org/formatted-string-literals-f-strings-python/

You can combine for loop with range function
so if you want to do 50 times something here is the loop
for times in range(50):
print("x")

Related

Conditionally increase integer count with an if statement in python

I'm trying to increase the count of an integer given that an if statement returns true. However, when this program is ran it always prints 0.I want n to increase to 1 the first time the program is ran. To 2 the second time and so on.
I know functions, classes and modules you can use the global command, to go outside it, but this doesn't work with an if statement.
n = 0
print(n)
if True:
n += 1
Based on the comments of the previous answer, do you want something like this:
n = 0
while True:
if True: #Replace True with any other condition you like.
print(n)
n+=1
EDIT:
Based on the comments by OP on this answer, what he wants is for the data to persist or in more precise words the variable n to persist (Or keep it's new modified value) between multiple runs times.
So the code for that goes as(Assuming Python3.x):
try:
file = open('count.txt','r')
n = int(file.read())
file.close()
except IOError:
file = open('count.txt','w')
file.write('1')
file.close()
n = 1
print(n)
n += 1
with open('count.txt','w') as file:
file.write(str(n))
print("Now the variable n persists and is incremented every time.")
#Do what you want to do further, the value of n will increase every time you run the program
NOTE:
There are many methods of object serialization and the above example is one of the simplest, you can use dedicated object serialization modules like pickle and many others.
If you want it to work with if statement only. I think you need to put in a function and make to call itself which we would call it recursion.
def increment():
n=0
if True:
n+=1
print(n)
increment()
increment()
Note: in this solution, it would run infinitely.
Also you can use while loop or for loop as well.
When you rerun a program, all data stored in memory is reset. You need to save the variable somewhere outside of the program, on disk.
for an example see How to increment variable every time script is run in Python?
ps. Nowadays you can simply do += with a bool:
a = 1
b = True
a += b # a will be 2

Use MapReduce on list elements?

So I know how to use MapReduce for files where each element is on a line, but I'm trying to use MapReduce on a file with its entries like so:
74390,0,6,7,5,2,6,4,10,12,7,6,12,9,4,3,9,1,3,5,9,9,8,5,12,11,4,8,5,9,6,12,12,9,7,9,12,7,8,9,8,8
74391,1,4,2,9,3,5,12,7,6,9,6,8,9,10,12,7,9,9,9,9,5,1,8,4,5,12,6,5,4,3,9,6,8,7,12,11,12,7,8,12,8
74392,0,6,9,3,2,4,9,1,4,7,12,9,12,12,10,6,9,9,5,12,7,12,7,6,8,7,9,5,3,5,9,8,9,12,5,8,4,11,8,6,8
74393,0,8,9,9,7,12,7,12,12,2,9,7,10,7,9,9,9,9,6,4,9,5,6,4,8,8,5,3,5,6,4,1,12,8,12,12,3,8,6,11,5
74394,0,5,9,6,2,4,6,5,6,7,12,8,9,7,9,10,3,9,1,9,8,9,12,7,3,5,12,12,4,12,4,8,9,5,9,12,8,11,6,8,7
74395,1,7,6,7,6,5,2,9,7,1,7,9,12,6,3,9,3,12,10,12,9,9,8,4,12,4,9,6,8,4,9,5,8,12,11,12,8,5,9,8,5
The first entry is the index and the second is meaningless for this analysis, and in the following code I remove them. My file has hundreds of thousands of lines like this, and I need to figure out which number appears in each part of the line the most, as these correspond to slots.
Expected output:
0: 1
1: 11
2: 5
...
40: 9
What I've got so far:
from mrjob.job import MRJob
from mrjob.step import MRStep
class topPieceSlot(MRJob):
def mapper(self, _, line):
pieces = line.split(',')
pieces = pieces[2::]
for item in range(len(pieces)):
yield str(item)
def reducer(self, pieces):
for slot in range(len(pieces)):
element = str(slot)
numElements = 0
for x in pieces:
total += x
numElements += 1
yield element, numElements
if __name__ == '__main__':
topPieceSlot.run()
And it returns nothing. It tells me it needs more than one value to unpack, but I'm not sure why it is only getting one value or if it's even right to begin with. Should I be using 40 variables for it? That seems inefficient and wrong.

Python 2.7 : store the variable value permanently even when I run the session next time

Scenario: python code which checks the number of visitors entered through a gate.
depending on that number I build the next job.
EDIT 1 :
#
file1 :(
First Run
this file counts the number of visitors that are arriving default is 3 in my case. Now i execute the file and I found that visitors arrived are 4 . Now and export the same to file2 and print the visitor count as 4 at the same time the visitors value is changed to 4 now in file1.
Now the second run:
Now in file1 the visitors value is 4 and it is checking if visitors > 4 , now if the count is 4 then i export the same to file2 if count is 5 now then i export the same to file2 and retain the value as 5 **count of visitors completely depends on the URL) ####
datasource = "www.PPrestraunt.com/personsentered"
data = len(datasource) #gives me the live value of the number of persons entered
if(visitors > 3):
bottles = data
visitors = bottles
print bottles
else:
visitors = 3
this above code is imported to a another file which has the working
file2:
from file1 import visitors
number_of_bottles = visitors
print number_of_bottles
I have setup the same in jenkins job so it builds every 5 mins.
In the above code the value of visitors is not changing every time I am running the code value remains 3 even though the number is increased to 4.
expected case: If value is more than 3 value should be retained in next session too and the if condition should now check for the new value ex: (if(visitors > 4)
any help is appreciated.
This would be a great scenario for pickling. You can pickle data (in your case a counter) and store this data, then retrieve it at a later point in time:
import pickle
def your_code(counter):
# Replace this with your code and use the counter variable.
# Every time you execute the code it will increase
# e.g. 3, 4, 5, 6 ....
print(counter)
try:
counter = pickle.load(open('counter.pckl', 'rb'))
counter += 1
pickle.dump(counter, open('counter.pckl', 'wb'))
# Now execute your code with the new counter:
your_code(counter)
except:
counter = 3
pickle.dump(counter, open('counter.pckl', 'wb'))
# Execute your code for the first time. This will only happen once.
your_code(counter)
The first time you execute this code, the counter will be initialized to 3. You can then call your existing code as a function and use this counter. Whenever you run the script, the counter will increase and your code will use the new version of counter: e.g. 3, 4, 5, 6.
Like what #juanpa wrote.
Here is a small program that increments a counter, you can tailor it to your code
import os
data_file = "lower_bound.txt"
is_file_empty = (os.path.isfile(data_file)==False) or (os.stat(data_file).st_size == 0)
if (is_file_empty):
with open(data_file,"w") as f:
f.write("3");
datasource = "www.PPrestraunt.com/personsentered"
data = len(datasource) #gives me the live value of the number of persons entered
lower_bound = 0;
with open(data_file,"r") as f:
lower_bound = int(f.read());
if (visitors>lower_bound):
bottles = data
visitors = bottles
print bottles
// #Alex either lower_bound+=1; or lower_bound = visitors not sure what you want
else:
visitors = lower_bound;
with open(data_file,"w") as f:
f.write(str(lower_bound));
print lower_bound,"is the new minimum and",visitors,"is the current visitor count";

Python IF statement to see how long an input has been active

I am using a raspberry pi, a pi face and a python script to monitor several home sensors. I want to add the sensing wire from the smoke detectors to that list but I need a bit of help with the if statement.
I'm unsure how to tell the if statement to check how long the input has detected the signal. Under 4 seconds disregard (low battery chirp), over 4 seconds (smoke detected) alert me..
Basically I need help writing the if statement below.
if piface.digital_read(0)==0 >= 4 seconds:
# do x
else:
# do y
Do I need a loop and can it be as easy as what I have above? (Coded correctly of course!)
Something like this (untested pseudo-code):
counter = 0
while True: #your main loop
smoke = digital_read() #assume 0 = no alarm, 1 = alarm
if smoke:
counter += 1
else:
counter = 0
if counter >= 4: #there was smoke for the last 4 seconds
call_the_fire_brigade()
time.sleep(1) #wait one second
I guess you probably need some loop.
Well I think a good solution to this would be spawn a separate thread for each detector and then use a blocking for the number with a loop.. like
count = 0
while count < 4:
if piface.digital_read(0) == 0:
count += 1
else: count = 0
sleep(4000)
# ... rest of code ...

execute python script multiple times

Im not sure about the best way to do this but I have a python script saved as a .py. The final output of this script is two files x1.txt and y1.txt.
Basically I want to run this script say 1000 times and each run write my two text files with new names i.e x1.txt + y1.txt then second run x2.txt and y2.txt.
Thinking about this it seems it might be better to start the whole script with something like
runs=xrange(:999)
for i in runs:
##run the script
and then finish with something that does
for i in runs:
filnameA=prefix += "a"+i
open("filnamea.txt", "w").write('\n'.join('\t'.join(x for x in g if x) for g in grouper(7, values)))
for i in runs:
filnameB=prefix += "a"+i
open("filnameB.txt", "w").write('\n'.join('\t'.join(x for x in g if x) for g in grouper(7, values)))
Is this really the best way to do it? I bet its not..better ideas?
I know you can import time and write a filename that mathes time but this would be annoying for processing later.
If your computer has the resources to run these in parallel, you can use multiprocessing to do it. Otherwise use a loop to execute them sequentially.
Your question isn't quite explicit about which part you're stuck with. Do you just need advice about whether you should use a loop? If yes, my answer is above. Or do you also need help with forming the filenames? You can do that part like this:
import sys
def myscript(iteration_number):
xfile_name = "x%d.txt" % iteration_number
yfile_name = "y%d.txt" % iteration_number
with open(xfile_name, "w") as xf:
with open(yfile_name, "w") as yf:
... whatever your script does goes here
def main(unused_command_line_args):
for i in xrange(1000):
myscript(i)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
import subprocess
import sys
script_name = 'dummy_file.py'
output_prefix = 'out'
n_iter = 5
for i in range(n_iter):
output_file = output_prefix + '_' + str(i) + '.txt'
sys.stdout = open(output_file, 'w')
subprocess.call(['python', script_name], stdout=sys.stdout, stderr=subprocess.STDOUT)
On running this, you'll get 5 output text files (out_0.txt, ..., out_4.txt)
I'm not sure, but maybe, it can help:
Suppose, I want to print 'hello' 10 times, without manually writing it 10 times. For doing this, I can define a function :
#Function for printing hello 10 times:
def func(x):
x="hello"
i=1
while i<10 :
print(x)
i += 1
else :
print(x)
print(func(1))

Categories