Python multiprocessing shared memory without copy - python

I'm currently working on a project for fun, involving calculating way too many numbers of the Fibonacci sequence. Thing is, I want it to go fast and I also don't want to loose too much progress if I have to do an update or have a computer issues....
So I over-engineered that, and I am currently looking to implement it with multiprocessing, but everywhere I look the only way to share memory in that case is to make a duplicate of it and that takes about an hour for (Yeah I have very big numbers)
Is there any way to share a dictionary with multiprocessing without making a copy of it?
Here is the code, currently with my last implementation using threading instead of using multiprocessing. (ignore the bad timekeeping of this, i'll fix it later)
import threading
import time
def printProgressBar(iteration, total, prefix="", suffix="", decimals=1, length=100, fill="█", printEnd="\r"):
"""
Call in a loop to create terminal progress bar
#params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + "-" * (length - filledLength)
print(
f"\r{prefix} |{bar}| {percent}% {suffix} {time.strftime('%dd %H:%M:%S', time.gmtime(time.time() - start_time - 86400)).replace('31d', '0d')}",
end=printEnd,
)
# Print New Line on Complete
if iteration == total:
print()
dict47 = {0: 0, 1: 1, 2: 1}
dict47[0] = 2
def fibSequence(n):
if n not in dict47:
dict47[n] = fibSequence(n - 1) + fibSequence(n - 2)
if n > dict47[0]:
dict47[0] = n
if n > 5 and not ((n - 3) % (iterations // 100) == 0) and not ((n - 2) % (iterations // 100) == 0):
dict47.pop(n - 3, None)
return dict47[n]
def makeBackup(start, num, total):
x = threading.Thread(target=writeBackup, args=(num,), daemon=False)
y = threading.Thread(target=writeBackup, args=(num - 1,), daemon=False)
x.start()
y.start()
x.join()
y.join()
time.sleep(1)
print(
f'{num/10000000}% done after {time.strftime("%dd %H:%M:%S", time.gmtime(time.time() - start - 86400)).replace("31d", "0d")}'
)
timings = open("times.txt", "a")
timings.write(str(int(time.time() - start)) + "\n")
timings.close()
def writeBackup(num):
file = open(f".temp/fib{num}.txt", "a")
file.write(str(num) + " : " + str(dict47[num]))
file.close()
dict47.pop(num, None)
def loadDict():
from pathlib import Path
maximum = 0
for n in range(1, 100):
if Path(f".temp/fib{n*10000000}.txt").is_file():
maximum = n * 10000000
print("Maximum number found:", maximum)
if maximum != 0:
file = open(f".temp/fib{maximum}.txt", "r")
temp = "".join(file.readlines())
dict47[maximum] = int(temp.lstrip(str(maximum) + " : "))
file.close()
file = open(f".temp/fib{maximum - 1}.txt", "r")
temp = "".join(file.readlines())
dict47[maximum - 1] = int(temp.lstrip(str(maximum - 1) + " : "))
file.close()
dict47[0] = maximum
print("Dictionary loaded at ", maximum)
else:
print("No dictionary found, starting from scratch")
if __name__ == "__main__":
try:
timings = open("times.txt", "r")
lastTime = int(timings.readlines()[-1])
start_time = time.time() - lastTime
timings.close()
except:
start_time = time.time() + 86400
print("Start duration:", time.strftime("%dd %H:%M:%S", time.gmtime(time.time() - start_time)).replace("31d", "0d"))
try:
iterations = int(input("Enter the number of iterations: "))
except:
iterations = 1000000000
print(iterations, "iterations will be performed")
loadDict()
num = dict47[0]
while num < iterations:
if num == 2:
num += 248
else:
num += 250
fibSequence(num)
if num % 1000 == 0:
printProgressBar(num, iterations, prefix="Progress:", suffix="Complete", length=100)
if num % (iterations // 100) == 0:
save = threading.Thread(
target=makeBackup,
args=(start_time, num, iterations),
daemon=False,
)
save.start()
file = open("fib.txt", "a")
file.write(str(iterations) + " : " + str(fibSequence(iterations)) + "\n")
file.close()
try:
save.join()
except:
print("No save thread running, exiting...")

Related

How do i deal with threading.Lock being super slow?

I wrote a singlethreaded prime-finding algorithm a while ago, and decided to try to optimise it using threading. Unfortunately, the multithreaded version is at best running 3/4 the speed of the singlethreaded one. After some research it seems that the 'threading.Lock' function is what slows it down so much. How can I improve the code?
The single-threaded code:
from math import sqrt, ceil
import time
import pickle
os.system("mode con: lines=8")
os.system("title Prime finder in Python")
primes = []
#Load primes from logprimes.data
with open("logprimes.data", "rb") as f:
primes = pickle.load(f)
if len(primes) < 4:
primes = [2, 3, 5, 7]
#Function to save results to logprimes.data
def SaveRes():
with open("logprimes.data", "wb") as f:
pickle.dump(primes, f)
return("Saved " + str(len(primes)) + " primes.")
#Function to find out if a number is a prime
def is_prime(n):
i = 0
while primes[i] < ceil(sqrt(n)):
if n % primes[i] == 0:
return False
i = i + 1
return True
starttime = time.time()
currentcheck = int(primes[len(primes) - 1])
lastsaved = time.time()
lastshowed = time.time()
#Main loop
os.system("cls")
while True:
try:
currentcheck = currentcheck + 1
if is_prime(currentcheck) == True:
primes.append(currentcheck)
if time.time() - lastshowed > 4:
print("\n\n\nTotal time: " + str(time.time() - starttime))
print("Currently checking: " + str(currentcheck))
print("Total number of primes: " + str(len(primes)))
print("Primes per sec: " + str(len(primes) / float(time.time() - starttime)))
print("Checks per sec: " + str(currentcheck / float(time.time() - starttime)))
print("Prime rarity: " + str(len(primes) / currentcheck) + "%")
lastshowed = time.time()
if time.time() - lastsaved > 300:
os.system("cls")
print(SaveRes())
lastshowed = time.time() + 2
lastsaved = time.time()
except (KeyboardInterrupt, SystemExit):
os.system("cls")
print(SaveRes())
lastsaved = time.time()
lastshowed = time.time() + 2
The multi-threaded code:
from math import sqrt, ceil
import time
import pickle
import threading
#os.system("mode con: lines=8")
os.system("title Prime finder in Python")
running = True
primes = []
threads = []
#Load primes from logprimes.data
with open("logprimes.data", "rb") as f:
primes = pickle.load(f)
if len(primes) < 4:
primes = [2, 3, 5, 7]
#Function to save results to logprimes.data
def SaveRes():
with open("logprimes.data", "wb") as f:
pickle.dump(primes, f)
return("Saved " + str(len(primes)) + " primes.")
#Function to find out if a number is a prime
def is_prime(n):
while primes[-1] < ceil(sqrt(n)): #Wait until we have enough primes to correctly deem wether or not 'n' is a prime. I know, not the most optimal solution, but it works.
pass
i = 0
while primes[i] < ceil(sqrt(n)):
if n % primes[i] == 0:
return False
i = i + 1
return True
def threadfunction(threadid, startnum = primes[-1] + 1):
global primes, running
currentcheck = startnum
with lock:
print(threadid)
while running:
if not currentcheck in primes:
if is_prime(currentcheck * (threadid + 1)):
with lock:
primes.append(currentcheck)
currentcheck += 1
exit()
startsize = len(primes)
starttime = time.time()
starthighestprime = primes[-1]
#currentcheck = int(primes[len(primes) - 1])
lastsaved = time.time()
lastshowed = time.time()
#Create threads
lock = threading.Lock()
for i in range(os.cpu_count()):
threads.append(
threading.Thread(
target=threadfunction,
args=(i,)
)
)
threads[-1].start()
#Main loop
os.system("cls")
while running and __name__ == "__main__":
try:
time.sleep(1)
if time.time() - lastshowed > 4:
print("\n\n\nTotal time: " + str(time.time() - starttime))
print("Last found prime: " + str(primes[-1]))
print("Total number of primes: " + str(len(primes)))
print("Primes per sec: " + str((len(primes) - startsize) / float(time.time() - starttime)))
print("Checks per sec: " + str((primes[-1] - starthighestprime) / float(time.time() - starttime)))
print("Prime rarity: " + str((len(primes) / primes[-1]) * 100) + "%")
lastshowed = time.time()
if time.time() - lastsaved > 300:
os.system("cls")
print(SaveRes())
lastshowed = time.time() + 2
lastsaved = time.time()
except (KeyboardInterrupt, SystemExit):
os.system("cls")
print(SaveRes())
lastsaved = time.time()
lastshowed = time.time() + 2
exit()```

Python while loop not terminating after defined amount of time

For this project, I have been making a vibration measurement device that plots high speed vibrations that are controlled by a motor. Here is the code below:
# Import the modules
from __future__ import division
import spidev, datetime, time
from sys import exit
import RPi.GPIO as GPIO
# Setup SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.mode = 3
# Constants
accres, accrate = 1, 15
# Set GPIO chip select pins
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
cs1, cs2, motor = 23, 24, 18
GPIO.setup(cs1, GPIO.OUT)
GPIO.setup(cs2, GPIO.OUT)
GPIO.setup(motor, GPIO.OUT)
# Note: the duty cycle goes from 0.0 to 100.0, with 100.0 being no motor movement,
# and 0.0 being the maximum motor speed.
motor_output = GPIO.PWM(motor, 60)
# Initialize the ADXL345
def initadxl345():
# Set data rate (accrate=15 -> 3200 Hz, 14=1600 Hz, 13=800 Hz, 12=400 Hz, 11=200 Hz, 10=100 Hz etc.)
spi.xfer2([44, accrate])
# Enable full range (10 bits resolution) and +/- 16g 4 LSB
spi.xfer2([49, accres])
# Read the first ADXL x-y-z axes
def readadxl345_1():
# Chip select pin ensures that the first sensor is being read by grounding its pin
GPIO.output(cs1, 0)
GPIO.output(cs2 ,1)
rx = spi.xfer2([242, 0, 0, 0, 0, 0, 0])
out = [rx[1] | (rx[2] << 8), rx[3] | (rx[4] << 8), rx[5] | (rx[6] << 8)]
# Format x-axis
if (out[0] & (1 << 16 - 1 )):
out[0] = out[0] - (1 << 16)
# Format y-axis
if (out[1] & (1 << 16 - 1 )):
out[1] = out[1] - (1<<16)
# Format z-axis
if (out[2] & (1 << 16 - 1 )):
out[2] = out[2] - (1 << 16)
# Return human readable values
return out
# Read the second ADXL x-y-z axes
def readadxl345_2():
# Chip select pin ensures that the first sensor is being read by grounding its pin
GPIO.output(cs1, 1)
GPIO.output(cs2 ,0)
rx = spi.xfer2([242, 0, 0, 0, 0, 0, 0])
out = [rx[1] | (rx[2] << 8), rx[3] | (rx[4] << 8), rx[5] | (rx[6] << 8)]
# Format x-axis
if (out[0] & (1 << 16 - 1 )):
out[0] = out[0] - (1 << 16)
# Format y-axis
if (out[1] & (1 << 16 - 1 )):
out[1] = out[1] - (1<<16)
# Format z-axis
if (out[2] & (1 << 16 - 1 )):
out[2] = out[2] - (1 << 16)
# Return human readable values
return out
print("Vibration Reader Initializing...")
time.sleep(1)
print(GPIO.RPI_INFO)
time.sleep(1)
response = input("Proceed measurements? [Y, n] ")
if response == "Y" or "y":
filename = input("Filename: ")
pwm_speed = float(input("Motor PWM value: "))
# Initialize the ADXL345 accelerometer
print("Initializing ADXL345s...")
initadxl345()
motor_output.start(pwm_speed)
print("Motor is up and running at {}".format(pwm_speed))
time.sleep(1)
timeout = 0.0003125 / 2 # timeout=1/samplerate=>not sufficient measurements. Half the time is sufficient (don't know why!)
timetosend = 1
while True:
with open('/proc/uptime', 'r') as f: # get uptime
uptime_start = float(f.readline().split()[0])
uptime_last = uptime_start
active_file_first = filename + '.csv'
file = open('/var/log/sensor/' + active_file_first, 'w')
while uptime_last < uptime_start + timetosend:
time1 = str(datetime.datetime.now().strftime('%S.%f'))
sensor1 = readadxl345_1()
sensor2 = readadxl345_2()
file.write(str(sensor1[0]) + ',' + str(sensor1[1]) + ',' + str(sensor1[2]) + ',' + str(sensor2[0]) + ',' + str(sensor2[1]) + ',' + str(sensor2[2]) + ',' + time1 + '\n')
# Print data every "timeout" second
elapsed = time.process_time()
current = 0
while(current < timeout):
current = time.process_time() - elapsed
motor_output.stop
print("Motor shutting off and cleaning up GPIO.")
GPIO.cleanup()
elif response == "N" or "n":
print("Quitting...")
time.sleep(1)
quit()
From this I get into trouble. The issue is that once I do choose to proceed, the print statement Motor is up and running at 100.0 displays and nothing happens until I press a random key on the keyboard in which is says
Traceback (most recent call last):
File "accelerometer.py", line 116, in <module>
current = time.process_time() - elapsed
KeyboardInterrupt
Its as if the code following that print statement didn't even exist, or the interpreter just ignored it completely. Does anyone have a coherent explanation of these problems?
Let's take a step back and think about what this block of code is doing:
while True:
### Block 1 ###
with open('/proc/uptime', 'r') as f: # get uptime
uptime_start = float(f.readline().split()[0])
uptime_last = uptime_start
active_file_first = filename + '.csv'
file = open('/var/log/sensor/' + active_file_first, 'w')
### Block 2 ###
while uptime_last < uptime_start + timetosend:
time1 = str(datetime.datetime.now().strftime('%S.%f'))
sensor1 = readadxl345_1()
sensor2 = readadxl345_2()
file.write(str(sensor1[0]) + ',' + str(sensor1[1]) + ',' + str(sensor1[2]) + ',' + str(sensor2[0]) + ',' + str(sensor2[1]) + ',' + str(sensor2[2]) + ',' + time1 + '\n')
# Print data every "timeout" second
elapsed = time.process_time()
current = 0
### Block 3 ###
while(current < timeout):
current = time.process_time() - elapsed
Block 1 checks an uptime file, reads the time and then opens a file. However, if this uptime_start variable never changes, then we can just set it once outside of (and instead of) the top while loop. Block 2 then checks uptime_last < uptime_start + x, but in the previous few lines, you've defined uptime_last = uptime_start. This means that for as long as the timetosend is not negative, this loop will execute infinitely unless an internal break condition is met. Block 2 writes sensor data to file. Block 3 does a time calculation until a condition is met, but doesn't really do anything with this information.
My guess as to what could be a good answer is this:
### Block 1 ###
with open('/proc/uptime', 'r') as f: # get uptime
uptime_start = float(f.readline().split()[0])
file = open('/var/log/sensor/' + filename + '.csv', 'w')
time_elapsed = 0
time_start = time.process_time()
### Block 2 ###
while time_elapsed < uptime_start:
time1 = str(datetime.datetime.now().strftime('%S.%f'))
sensor1 = readadxl345_1()
sensor2 = readadxl345_2()
file.write(str(sensor1[0]) + ',' + str(sensor1[1]) + ',' + str(sensor1[2]) + ',' + str(sensor2[0]) + ',' + str(sensor2[1]) + ',' + str(sensor2[2]) + ',' + time1 + '\n')
time_elapsed = time.process_time() - time_start

Calculating the amount of time left until completion

I am wondering how to calculate the amount of time it would take to example:
Complete a brute force word list.
I know how to use the time function and measure in time,
but the problem is i need to find out how long it would take in the program itself...
Here is the code i made this yesterday
import itertools, math
import os
Alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # Add or remove whatevs you think will be in the password you're cracking (example, [symbols])
counter = 1
CharLength = 1
range_num = int(raw_input("Enter range: "))
stopper = range_num + 1
filename = "bruteforce_%r.txt" % (range_num)
f = open(filename, 'a')
#n_1 = len(Alphabet)
#n_2 = n_1 - 1 # <-- total useless peice of garbage that could of been great in vurtual life
#n_3 = '0' * n_2
#n = '1' + n_3
x = range_num
y = len(Alphabet)
amount = math.pow(y, x)
total_items = math.pow(y, x)
for CharLength in range(range_num, stopper):
passwords = (itertools.product(Alphabet, repeat = CharLength))
for i in passwords:
counter += 1
percentage = (counter / total_items) * 100
amount -= 1
i = str(i)
i = i.replace("[", "")
i = i.replace("]", "")
i = i.replace("'", "")
i = i.replace(" ", "")
i = i.replace(",", "")
i = i.replace("(", "")
i = i.replace(")", "")
f.write(i)
f.write('\n')
print "Password: %r\tPercentage: %r/100\tAmount left: %r" % (i, int(percentage), amount)
if i == '0'* range_num:
print "*Done"
f.close()
exit(0)
else:
pass
This is my timer function i managed to make
#import winsound # Comment this out if your using linux
import os
import time
from sys import exit
print "This is the timer\nHit CTRL-C to stop the timer\nOtherwise just let it rip untill the time's up"
hours = int(raw_input('Enter the hours.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
minutes = int(raw_input('Enter the minutes.\n>>> '))
os.system('clear') # linux
#os.system('cls') # Windows
seconds = int(raw_input('Enter the seconds.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
stop_time = '%r:%r:%r' % (hours, minutes, seconds)
t_hours = 00
t_minutes = 00
t_seconds = 00
while t_seconds <= 60:
try:
os.system('clear') # Linux
#os.system('cls') # Windows
current_time = '%r:%r:%r' % (t_hours, t_minutes, t_seconds)
print current_time
time.sleep(1)
t_seconds+=1
if current_time == stop_time:
print "// Done"
#winsound.Beep(500,1000)
#winsound.Beep(400,1000)
break
elif t_seconds == 60:
t_minutes+=1
t_seconds=0
elif t_minutes == 60:
t_hours+=1
t_minutes = 00
except KeyboardInterrupt:
print "Stopped at: %r:%r:%r" % (t_hours, t_minutes, t_seconds)
raw_input("Hit enter to continue\nHit CTRL-C to end")
try:
pass
except KeyboardInterrupt:
exit(0)
Now i just cant figure out how to make this again but to calculate how long it will take rather than how long it is taking...
You cannot predict the time a script is going to take.
Firstly because two machines wouldn't run the script in the same time, and secondly, because the execution time on one machine can vary from on take to another.
What you can do, however, is compute the percentage of execution.
You need to figure out, for example, how many iterations your main loop will do, and calculate at each iteration the ratio current iteration count / total number of iterations.
Here is a minimalist example of what you can do:
n = 10000
for i in range(n):
print("Processing file {} ({}%)".format(i, 100*i//n))
process_file(i)
You can take it further and add the time as an additional info:
n = 10000
t0 = time.time()
for i in range(n):
t1 = time.time()
print("Processing file {} ({}%)".format(i, 100*i//n), end="")
process_file(i)
t2 = time.time()
print(" {}s (total: {}s)".format(t2-t1, t2-t0))
The output will look like this:
...
Processing file 2597 (25%) 0.2s (total: 519.4s)
Processing file 2598 (25%) 0.3s (total: 519.7s)
Processing file 2599 (25%) 0.1s (total: 519.8s)
Processing file 2600 (25%)
This is my implementation, which returns time elapsed, time left, and finish time in H:M:S format.
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
testimated = (telapsed/cur_iter)*(max_iter)
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated-telapsed # in seconds
return (int(telapsed), int(lefttime), finishtime)
Example:
import time
import datetime as dt
start = time.time()
cur_iter = 0
max_iter = 10
for i in range(max_iter):
time.sleep(5)
cur_iter += 1
prstime = calcProcessTime(start,cur_iter ,max_iter)
print("time elapsed: %s(s), time left: %s(s), estimated finish time: %s"%prstime)
Output:
time elapsed: 5(s), time left: 45(s), estimated finish time: 14:28:18
time elapsed: 10(s), time left: 40(s), estimated finish time: 14:28:18
time elapsed: 15(s), time left: 35(s), estimated finish time: 14:28:18
....
You will never ever be able to know exactly how long it is going to take to finish. The best you can do is calculate was percentage of the work you have finished and how long that has taken you and then project that out.
For example if you are doing some work on the range of numbers from 1 to 100 you could do something such as
start_time = get the current time
for i in range(1, 101):
# Do some work
current_time = get the current time
elapsed_time = current_time - start_time
time_left = 100 * elapsed_time / i - elapsed_time
print(time_left)
Please understand that the above is largely pseudo-code
The following function will calculate the remaining time:
last_times = []
def get_remaining_time(i, total, time):
last_times.append(time)
len_last_t = len(last_times)
if len_last_t > 5:
last_times.pop(0)
mean_t = sum(last_times) // len_last_t
remain_s_tot = mean_t * (total - i + 1)
remain_m = remain_s_tot // 60
remain_s = remain_s_tot % 60
return f"{remain_m}m{remain_s}s"
The parameters are:
i : The current iteration
total : the total number of iterations
time : the duration of the last iteration
It uses the average time taken by the last 5 iterations to calculate the remaining time. You can the use it in your code as follows:
last_t = 0
iterations = range(1,1000)
for i in iterations:
t = time.time()
# Do your task here
last_t = time.time() - t
get_remaining_time(i, len(iterations), last_t)

Extra newlines in python

I have this python code which is used to give direction to m to reach p.
Here is the code:
#!/bin/python
def displayPathtoPrincess(n,grid):
m = "m"
p = "p"
for i in range(n):
if(m in grid[i]):
m_column = grid[i].find(m)
m_row = int(i + 1)
#print "{0}x{1} \n".format(int(i + 1), m_position + 1)
if(p in grid[i]):
p_column = grid[i].find(p)
p_row = int(i + 1)
#print "{0}x{1} \n".format(int(i + 1), p_position + 1)
down_up = p_row - m_row
if(down_up > 0):
print "DOWN\n"*down_up
else:
print "UP\n"
right_left = p_column - m_column
if(right_left > 0):
print "RIGHT\n"*right_left
else:
print "LEFT\n"
m = input()
grid = []
for i in xrange(0, m):
grid.append(raw_input().strip())
displayPathtoPrincess(m,grid)
Input:
> 6
> ---
> ---
> -m-
> ---
> ---
> p--
Expected output:
DOWN
DOWN
DOWN
LEFT
My output:
DOWN
DOWN
DOWN
LEFT
As you can see in my output, the program adds a new line whenever it changes the direction. Any ideas on how to stop this new line from appearing?
You are hard-coding a newline after each 'DOWN' or 'RIGHT' every time you do this:
print "DOWN\n"*down_up
print "RIGHT\n"*right_left
The resulting strings will be 'DOWN' or 'RIGHT' followed by a newline, the specified number of times. That means that such strings will end with an unwanted newline. The smallest fix is to multiply by one fewer than the necessary number, and then add the last bit:
print "DOWN\n"*(down_up-1) + 'DOWN'
print "RIGHT\n"*(right_left-1) + 'RIGHT'
Or use str.join:
print '\n'.join("DOWN" for i in range(down_up))
print '\n'.join("RIGHT" for i in range(right_left))

Python For loop repeating endlessly

I'm currently writing a program to check speeds of cars and their license plates, and I want to repeat the function that does this x number of times, the problem I'm having though is that the function is repeating endlessly and is not adhering to the number of times I want it to loop.
Here is what I have so far:
if correctMatch:
pass
else:
with open('Camera Output.txt', 'a') as f:
print("DATA RECORDED TO: Camera Output.txt")
exactTime2 = datetime.now()
f.write("{} has a non-standard license plate and has been recorded at {}.".format(licensePlate,
exactTime2) + "\n")
f.write("---------------------------------------------------------\n")
if speedCarMph > 60:
with open('Camera Output.txt', 'a') as f:
print("DATA RECORDED TO: Camera Output.txt")
exactTime= datetime.now()
f.write("{} was travelling at {}MPH, recorded at {} and has broken the law.".format(licensePlate,
speedCarMph, exactTime) + "\n")
f.write("----------------------------------------------------------\n")
licensePlateCheck()
for x in range(N):
repeatNum = 0
while repeatNum < 10:
repeatNum += 1
licensePlateCheck()
if repeatNum == 10:
print("Completed generation")
I also attempted to use a thread but that didn't work. If you need any more of the code, just ask.
The full code is here (excluding an unrelated function and the function choice):
import re
import threading
from queue import Queue
def licensePlateCheck():
camInput1 = datetime.now()
print(camInput1)
print("Car is travelling...")
time.sleep(0.1)
print("Car has passed cam2")
camInput2 = timedelta(seconds = random.uniform(5, 10))
distance = 200
duration = camInput2.total_seconds()
print("Time Delta is equal to: {0}".format(duration))
speedCarMs = distance/duration
print("Car is travelling in m/s at: {0}".format(speedCarMs))
speedCarMph = 2.237*speedCarMs
print("Car is travelling in MPH at: {0}".format(speedCarMph))
licenseCharNum = randint(2,9)
licensePlate = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(licenseCharNum))
licensePlateLayout = re.compile('[A-Z][A-Z]\d\d[A-Z][A-Z][A-Z]')
correctMatch = licensePlateLayout.match(licensePlate)
if correctMatch:
pass
else:
with open('Camera Output.txt', 'a') as f:
print("DATA RECORDED TO: Camera Output.txt")
exactTime2 = datetime.now()
f.write("{} has a non-standard license plate and has been recorded at {}.".format(licensePlate,
exactTime2) + "\n")
f.write("----------------------------------------------------------\n")
if speedCarMph > 60:
with open('Camera Output.txt', 'a') as f:
print("DATA RECORDED TO: Camera Output.txt")
exactTime= datetime.now()
f.write("{} was travelling at {}MPH, recorded at {} and has broken the law.".format(licensePlate,
speedCarMph, exactTime) + "\n")
f.write("----------------------------------------------------------\n")
licensePlateCheck()
for x in range(N):
repeatNum = 0
while repeatNum < 10:
repeatNum += 1
licensePlateCheck()
if repeatNum == 10:
print("Completed generation")
In that case you have unnecessary used while loop:)
for x in range(N): // will iterate x times
licensePlateCheck()
print("Completed generation")
With nested while loop, your method would execute:
x * 10 times:
x - for loop
10 - while loop
Both For and While are correct, the choice is up to you.

Categories

Resources