#!/usr/bin/env python
import RPi.GPIO as GPIO
from time import sleep
my objective
"""
this is writen for the raspberry pi to get an input from two encoder and print a numberical
count. this will use with a telescope and stellarium
this need lot more work but just a beginner still
"""
set gpio on raspberry init self and main varible
class EncoderSetup:
def __init__(self, azm_a=27, azm_b=17, lat_a=20, lat_b=21, counter1=0, counter2=0):
self.azm_a = azm_a
self.azm_b = azm_b
self.lat_a = lat_a
self.lat_b = lat_b
self.counter1 = counter1
self.counter2 = counter2
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.azm_a, GPIO.IN)
GPIO.setup(self.azm_b, GPIO.IN)
GPIO.setup(self.lat_a, GPIO.IN)
GPIO.setup(self.lat_b, GPIO.IN)
this loop gets the state of a and b compares, get direction, counts and debounces
class Azimuth(EncoderSetup):
def azm_encoder(self):
Last_RoB_Status = GPIO.input(self.azm_b)
while not GPIO.input(self.azm_a): # starts encoder loop
Current_RoB_Status = GPIO.input(self.azm_b)
dtState = GPIO.input(self.azm_a)
if Current_RoB_Status != Last_RoB_Status:
if dtState != Current_RoB_Status:
self.counter1 += 1
else:
self.counter1 -= 1
Last_RoB_Status = Current_RoB_Status # deboucing
# sleep(0.01)
return self.counter1
this loop gets the state of a and b compares, get direction, counts and debounces
class Latitude(EncoderSetup):
def lat_encoder(self):
Last_RoC_Status = GPIO.input(self.lat_a)
while not GPIO.input(self.lat_b):
Current_RoC_Status = GPIO.input(self.lat_a)
dtState2 = GPIO.input(self.lat_b)
if Current_RoC_Status != Last_RoC_Status:
if dtState2 != Current_RoC_Status:
self.counter2 += 1
else:
self.counter2 -= 1
Last_RoC_Status = Current_RoC_Status # deboucing
# sleep(0.01)
return self.counter2
loop forever to get continous count from two encoders
def loop():
eset = EncoderSetup()
azm = Azimuth()
lat = Latitude()
while True:
print ('globalCounter1 = ' + str(azm.azm_encoder()) +
' globalCounter2 = ' + str(lat.lat_encoder()))
this doc explains my problem
"""
this is my problem i get a numerical output with none example
globalcounter1 = none globalcounter2 none
globalcounter1 = 0 globalcounter2 none
globalcounter1 = none globalcounter2 0
globalcounter1 = none globalcounter2 none
globalcounter1 = 4 globalcounter2 -1
globalcounter1 = 5 globalcounter2 none
the second problem is i got to turn lat_encoder first before
i get and out from azm_encoder. i think i need to implement threading
or the the same loop for both lat_encoder and azm_encoder
please help me i little lost at this point
"""
resets the gpio on the raspberry
def destroy():
GPIO.cleanup()
start the program
if __name__ == '__main__':
use to call loop to start
remove trace back error message
try:
loop()
except KeyboardInterrupt:
destroy()
i solved the first problem. this whats happening
Because there are two print statements. First is inside function and second is outside function. When function not return any thing that time it return None value.
i remove the print from loop() and replaced where return statement are for
example
print self.counter1 and print self.counter2
i wonder if is possible to use the same while loop for both encoders
Related
I have a piece of code as shown below:
#!/bin/python3
import math
import os
import random
import re
import sys
import logging
def consumer():
while True:
x = yield
print(x)
def producer(n):
for _ in range(n):
x = int(input())
yield x
def rooter():
logging.info("Running the rooter")
while True:
value = (yield)
yield math.sqrt(value)
def squarer():
logging.info("Running the squarer")
while True:
value = (yield)
print("from squarer: {}".format(value))
yield value * value
def accumulator():
logging.info("Running the accumulator.")
running_total = 0
while True:
value = (yield)
running_total += value
yield running_total
def pipeline(prod, workers, cons):
logging.info("workers: {}".format(workers))
for num in prod:
for i, w in enumerate(workers):
num = w.send(num)
cons.send(num)
for worker in workers:
worker.close()
cons.close()
if __name__ == '__main__':
order = input().strip()
m = int(input())
prod = producer(m)
cons = consumer()
next(cons)
root = rooter()
next(root)
accumulate = accumulator()
next(accumulate)
square = squarer()
next(square)
pipeline(prod, eval(order), cons)
Sample input
[square, accumulate]
3 <- Number of inputs coming further
1 <- actual inputs
2
3
Sample Output
*The output should be as below:*
1
5
14
but comes to
10(sum of the squares of 1 and 3) when it should actually be 14 (sum of the squares of 1, 2, 3)
So essentially the input 2 is missed (It's second in the line of inputs).
On debugging further I found that this is the case for every alternate iteration, not just for the provided inputs here.
I am not able to decipher what's happening. If it's of any help, the co-routine squarer is the one returning None in the second iteration.
I'd appreciate any help.
I found a solution to this.
It's that we prime the co-routine after use in the pipeline function so the code becomes as follows: I have marked the next(w) line within asterix for reference.
#!/bin/python3
import math
import os
import random
import re
import sys
import logging
def consumer():
while True:
x = yield
print(x)
def producer(n):
for _ in range(n):
x = int(input())
yield x
def rooter():
logging.info("Running the rooter")
while True:
value = (yield)
yield math.sqrt(value)
def squarer():
logging.info("Running the squarer")
while True:
value = (yield)
print("from squarer: {}".format(value))
yield value * value
def accumulator():
logging.info("Running the accumulator.")
running_total = 0
while True:
value = (yield)
running_total += value
yield running_total
def pipeline(prod, workers, cons):
logging.info("workers: {}".format(workers))
for num in prod:
for i, w in enumerate(workers):
num = w.send(num)
**next(w)**
cons.send(num)
for worker in workers:
worker.close()
cons.close()
if __name__ == '__main__':
order = input().strip()
m = int(input())
prod = producer(m)
cons = consumer()
next(cons)
root = rooter()
next(root)
accumulate = accumulator()
next(accumulate)
square = squarer()
next(square)
pipeline(prod, eval(order), cons)
As mentioned in PEP specification it says that a generator function's yield
is always None when resumed by a normal next call. So when explicitly made to yield, it'll be ready to handle the next input immediately in this case.
hello i have a code that looks like this
from multiprocessing import Process
from tkinter.messagebox import *
from time import sleep
def timerclose():
sumtimer = 0
while sumtimer <= 10 :
sleep(0.1)
sumtimer = sumtimer + 0.1
print("sumtimer",sumtimer)
return sumtimer
def conout():
confirmation = askokcancel ("confirmation","are you sure ?")
return confirmation
if __name__=='__main__':
p1 = Process(target=timerclose)
p1.start()
p2 = Process(target=conout)
p2.start()
I wanted to create an askokcancel message box with a timeout. i want the messagebox to popout to ask the user if we wants to exit or not and simultaneously starts a counter. after 10 seconds if the user does not press anything (ok or cancel) i would get the return value from the timerclose ignore the conout function and continue with the rest of the programm.
i solve it with one process and a shared value
def conout(n):
n.value = int(0)
confirmation = askokcancel ("confirmation","Σε 10 sec κλείνω Οκ ?")
if confirmation == True :
n.value = int(1)
else:
n.value = int(2)
if __name__=="__main__":
p2 = Process(target=conout, args=(num,))
p2.start()
timerls = 0
while timerls <= 10:
sleep(0.25)
timerls += 0.25
print("timerls",timerls)
if num.value == 1 :
print ("end true",num.value)
break
elif num.value == 2:
print ("end false", num.value)
break
else:
print ("end0", num.value)
Im trying to simulate two machines working, and failing at random times. When they fail they call assistance. These two machines is part of bigger system of different machines, which needs to know when its neighbor has failed to do its job.
So far, I have made the simulate of the two machines, but I cant figure out how to send messages to their neighbors without each machine needing to know the whole system?
This is what I have so far:
import simpy
import random
random_seed=42
MTTF = 3500
break_mean = 1 / MTTF
sim_time = 4 * 7*24*60 # 4 weeks 24/7
num_machines = 2
rep_time = 30
tpp = 20 #20 minutes to make each part
neighbour = 3 #How many should it send to?
#Creating a class called messaging which is an object.
class messaging(object):
#DEfing the initilizing function, and initilize self, Environment, and capacity which is set to infinity, by a simpy core-function.
def __init__(self, env, capacity=simpy.core.Infinity):
self.env = env
self.capacity = capacity
self.pipes = []
#Making a function which work on everything that is a part of the message. With name Put.
def put(self, value):
if not self.pipes: #How to get this error?
raise runtime_error('There are no output pipes.')
#Create a variable, events, store to it pipe values
events = broken_machine()
return self.env.all_of(events)
def get_output_conn(self):
#Set the capacity of pipe variable to store infinity.
pipe = simpy.Store(self.env, capacity=self.capacity)
#to each pipes, add(or append) pipe
self.pipes.append(pipe)
return pipe
def mesg_generator(number, env, out_pipe):
msg = ('Failed')
def message_reciever(name, env, in_pipe):
while True:
msg = yield in_pipe.get()
print("%s received message: %s" % (number, msg[1]))
def time_per_part():
return tpp
def ttf():
return random.expovariate(break_mean)
class Machine(object):
def __init__(self, env, number, repair):
#self.arg = arg
self.env = env
self.number = number
self.parts_made = 0
self.times_broken = 0
self.broken = False
self.process = env.process(self.working(repair))
env.process(self.broken_machine())
def working(self, repair):
while True:
work = time_per_part()
while work:
try:
begin = self.env.now
yield self.env.timeout(work)
work = 0
except simpy.Interrupt:
self.broken = True
work -= self.env.now - begin
with repair.request(priority = 1) as req:
yield req
yield self.env.timeout(rep_time)
self.times_broken +=1
yield message_reciever()
#print('Machine down')
self.broken = False #Machine fixed again
self.parts_made +=1
def broken_machine(self):
while True:
yield self.env.timeout(ttf())
if not self.broken:
self.process.interrupt()
def other_jobs(env, repair):
while True:
work = tpp
while work:
with repair.request(priority=2) as req:
yield req
try:
begin = env.now
yield env.timeout(work)
work = 0
except simpy.Interrupt:
work -= env.now - begin
print("This simulates machines 3 and 4 doing the same tasks.")
random.seed(random_seed)
env = simpy.Environment()
pipe = simpy.Store(env)
bc_pipe = messaging(env)
repair = simpy.PreemptiveResource(env, capacity = 1)
machines = [Machine(env, 'Machine %d' % i, repair)
for i in range(num_machines)]
env.process(other_jobs(env, repair))
env.run(until=sim_time)
#Show how many times each machine failed:
for machine in machines:
print("%s broke down %d times" %(machine.number, machine.times_broken))
I am trying to implement bitonic with the python multiprocessing library and a shared resource array that will be sorted at the end of the program.
The problem I am running into is that when I run the program, I get an prompt that asks "Your program is still running! Are you sure you want to cancel it?" and then when I click cancel N - 1 times (where N is the amount of processes I am trying to spawn) then it just hangs.
When this is run from the command line, it just outputs the unsorted array. Of course, I expect it to be sorted at the program's finish.
I've been using this resource to try and get a firm grasp on how I can mitigate my errors but I haven't had any luck, and now I am here.
ANY help would be appreciated, as I really don't have anywhere else to turn to.
I wrote this using Python 3.6 and here is the program in its entirety:
from multiprocessing import Process, Array
import sys
from random import randint
# remember to move this to separate file
def createInputFile(n):
input_file = open("input.txt","w+")
input_file.write(str(n)+ "\n")
for i in range(n):
input_file.write(str(randint(0, 1000000)) + "\n")
def main():
# createInputFile(1024) # uncomment this to create 'input.txt'
fp = open("input.txt","r") # remember to read from sys.argv
length = int(fp.readline()) # guaranteed to be power of 2 by instructor
arr = Array('i', range(length))
nums = fp.read().split()
for i in range(len(nums)):
arr[i]= int(nums[i]) # overwrite shared resource values
num_processes = 8 # remember to read from sys.argv
process_dict = dict()
change_in_bounds = len(arr)//num_processes
low_b = 0 # lower bound
upp_b = change_in_bounds # upper bound
for i in range(num_processes):
print("Process num: " + str(i)) # are all processes being generated?
process_dict[i] = Process(target=bitonic_sort, args=(True, arr[low_b:upp_b]) )
process_dict[i].start()
low_b += change_in_bounds
upp_b += change_in_bounds
for i in range(num_processes):
process_arr[i].join()
print(arr[:]) # Print our sorted array (hopefully)
def bitonic_sort(up, x):
if len(x) <= 1:
return x
else:
first = bitonic_sort(True, x[:len(x) // 2])
second = bitonic_sort(False, x[len(x) // 2:])
return bitonic_merge(up, first + second)
def bitonic_merge(up, x):
# assume input x is bitonic, and sorted list is returned
if len(x) == 1:
return x
else:
bitonic_compare(up, x)
first = bitonic_merge(up, x[:len(x) // 2])
second = bitonic_merge(up, x[len(x) // 2:])
return first + second
def bitonic_compare(up, x):
dist = len(x) // 2
for i in range(dist):
if (x[i] > x[i + dist]) == up:
x[i], x[i + dist] = x[i + dist], x[i] #swap
main()
I won't go into all the syntax errors in your code since I am sure your IDE tells you about those. The problem that you have is that you are missing an if name==main. I changed your def main() to def sort() and wrote this:
if __name__ == '__main__':
sort()
And it worked (after solving all the syntax errors)
I am trying to create the GUI code for my connect four boardgame but error's keep on coming up that I don't know how to correct. Can anyone help? The error:
TypeError: init() missing 1 required positional argument: 'buttns_list'
Code:
def __init__(self):
self.mw = tkinter.Tk()
self.mw.title = ("Connect Four")
self.rows = 6
self.cols = 7
self.buttons_2d_list = []
for i in range (self.rows):
self.rows = ['']*self.cols
self.buttons_2d_list.append(self.rows)
self.gboard = ConnectFourBoard()
p1 = HumanPlayer("X")
p2 = ComputerPlayer("O", self.buttns_list)
self.players_1st = (p1, p2)
self.currnt_player_index = 0
self.winner = False
def clicked_btn(self, x, y):
p = self.players_1st[self.currnt_player_index]
button = self.buttons_2d_list[x][y]
if button["text"] == "":
button["text"] = p.get_player_symbol()
self.gboard.MakeMove(x, y, p.get_player_symbol())
winner = self.gboard.CheckForWin()
is_full = self.gboard.FullBoard()
if winner == True:
win_message = ("Player %s is the winner!" %p.get_player_symbol())
messagebox.showinfo("Winner Info", win_messge)
self.mw.destroy()
exit()
elif is_full == True:
messagebox.showinfo("Winner Info", "The game is a draw")
self.mw.destroy()
exit()
else:
pass
if self.currnt_player_index == 1:
self.currnt_player_index = 0
else:
self.currnt_player_index += 1
p = self.players_1st[self.currnt_player_index]
p.play()
import random
class ComputerPlayer(Player):
def __init__(self, letter, buttns_list):
Player.__init__(self, letter)
self.buttons_2d_list = buttns_list
def play(self):
pass
It's not clear to me from the rest of the code exactly what you should be passing here, but your init calls for a letter, which you do have, and a buttns_list, which you don't:
def __init__(self, letter, buttns_list):
So the error comes from this line:
p2 = ComputerPlayer("O")
Either:
1) Pass in a buttns_list if your ComputerPlayer class needs it
p2 = ComputerPlayer("O", self.buttons_2d_list)` # in GameGUI init
2) Get rid of it if this was added by mistake:
class ComputerPlayer(Player):
def __init__(self, letter):
Player.__init__(self, letter)