In a previous question, the issue was how to implement a conditional loop (a simple for loop) to affect the onMessage event calling function, which was resolved. However, my current issue is in trying to implement time as the determinant in the conditional loop.
Currently, the code runs but only seems to do the while loop that rechecks the time, ignoring the code before it. I suspect that the issue is in the location that I have placed the time rechecking loop?
Any clarity on this issue would be appreciated!
import ch
import time
class bot(ch.RoomManager):
timeleft = 0
starttime = 0
def onMessage(self, room, user, message):
print("[{0}] {1}: {2}".format(room.name, user.name.title(), message.body))
if 100 >= timeleft >= 1:
print('success')
else:
print('fail')
loop = 1
while loop == 1 :
timeleft = starttime - int(time.clock())
if timeleft <=0:
timeleft = 200
starttime = 200
rooms = ["testgroup444"]
username = "user"
password = "name"
bot.easy_start(rooms,username,password)
For clarity on the methods used, the entire ch.py library can be found here: https://pastebin.com/8ukS4VR1
I think you still have an issue with the Python syntax. In Python whitespace is very important as it defines scope. The way your code is written, the while loop is executed at the time the class is defined, before anything is started.
Further, the code gets into an infinite loop, as while loop == 1 will be always True. This is why you see that your code gets stuck. From the discussion in the comments, I imagine you want to write something like:
import ch
import time
import enum
class State(enum.Enum):
idle = 0
nominating = 1
voting = 2
watching = 3
class bot(ch.RoomManager):
state = State.idle
movie_length = 20
def updateState(self):
if self.state in [State.idle, State.nominating]:
self.state = State.voting
timeout = 10
elif self.state == voting:
self.state = State.watching
timeout = self.movie_length - 15
else: # if self.state == watching
self.state = State.nominating
timeout = 15
self.setTimeout(timeout*60, bot.updateState, self)
def onConnect(self, room):
# Redirect through event loop, not strictly nessecary
self.setTimeout(0, bot.updateState, self)
def onMessage(self, room, user, message):
print("[{0}] {1}: {2}".format(room.name, user.name.title(), message.body))
print("Current state is {0}".format(self.state))
rooms = ["testgroup444"]
username = "user"
password = "name"
bot.easy_start(rooms,username,password)
Here, the setTimeout method defined in the ch (bot) class is used, to allow messages to be passed at certain times. At every timeout the state is updated. The actual state is then available in all internal methods, e.g. in onMessage and updateState.
As I do not use the chat network or client I cannot guarantee that the solution works, though.
Related
I'm quite new on python and working on a school project with this logic: Users have to answer a series of questions as fast as they can, within the given time.
For instance, the time allotted is 30 seconds, I wood loop through a dictionary of questions and get the answer. On timeout, the loop will start, even if the script is still waiting for an input.
def start_test():
for item on questions:
print(item)
answers.append(input(' : '))
I've tried using multiprocessing and multithreading, but I found out that stdin doesn't work subprocesses.
I'm looking for something like:
while duration > 0:
start_test()
def countdown():
global duration
while duration > 0:
duration -= 1
time.sleep(1)
# something lime start_test().stop()
But I can't figure out how to run the countdown function in parallel with the start_test function.
Any ideas?
So as far as I know the input is accessible via main thread only. I might be wrong.
However if that is the case, you need a non-blocking input.
Check this blog. The answer below is based on that.
Note: This is a really quick and dirty solution.
I have checked this on Linux.
If it doesn't work on Windows try this
link for further reference.
import _thread
import sys
import select
import time
def start_test():
questions = ['1','2','3']
answers = []
for item in questions:
print(item)
# Input in a non-blocking way
loop_flag = True
while loop_flag:
# Read documenation and examples on select
ready = select.select([sys.stdin], [], [], 0)[0]
if not ready:
# Check if timer has expired
if timeout:
return answers
else:
for file in ready:
line = file.readline()
if not line: # EOF, input is closed
loop_flag = False
break
elif line.rstrip():
# We have some input
answers.append(line)
# So as to get out of while
loop_flag = False
# Breaking out of for
break
return answers
def countdown():
global timeout
time.sleep(30)
timeout = True
# Global Timeout Flag
timeout = False
timer = _thread.start_new_thread(countdown, ())
answers = start_test()
print(answers)
I'm creating a platform using flask+python where each loggedin user can add several social media accounts to be used for analysis. Each account added starts a new thread with the account name, which then is saved into a dic (key=account name and value=the thread). HOWEVER, when I do a hard refresh/reload on the homepage, the dic that references all the threads gets reset and returns None. I can make modifications, like get variable values from the threads or call the kill function to end the threads.I've been looking everywhere here on this site and I can't find the solution.
I've simplified my code:
class threads_manager(threading.Thread):
def __init__(self):
super(threads_manager, self).__init__()
self.cancelled = False
self.accounts = {}
def is_loggedin(self, username):
if not self.accounts:
return self.accounts[username].logged_in()
def add_account(self, usname, uspass, PROXY):
# AddAccount runs on a seperate thread that is managed by this thread
acc = AddAccount(usname, uspass, '')
acc.start()
self.accounts.update({usname: acc})
def kill_account(self, username):
if self.accounts[username] != None:
self.accounts[username].cancel()
return True
else:
return False
def run(self):
# make sure that the thread kill it self after 1 min as I cant
#get access to it later
while not self.cancelled:
if self.timeout > 0:
time.sleep(2)
self.timeout -= 1
else:
self.cancelled = True
# create new instance as global variable
manager = threads_manager()
#app.route('/addAccounts/')
def addAccounts():
global manager
# for displaying the accounts that are already stored in the server
#shows the names of the running threads (ajax call)
if request.args.get('command') == 'GETACCOUNTS':
tnames = []
for t in threading.enumerate():
tnames.append(t.name)
# prints the names as a flash/toast
return jsonify({'success' : tname})
if request.args.get('command') == 'ADDACCOUNT':
#ajax call
manager.add_account('username', 'password', 'proxy')
else:
#when reloading the website
return render_template('addAccounts.html')
Any help, ideas?
How I can stop threading by clicking a wxButton?
Here is my code:
def startMonitor(self,event):
selectedInterface = self.interfaces_cblist.GetValue()
Publisher().sendMessage(("test"),selectedInterface)
self.Close()
selectInterfaceStr = str(selectedInterface)
if len(selectedInterface) == 0:
noSelect_error = wx.MessageDialog(None,"Please select an interface","",wx.OK|wx.ICON_ERROR)
noSelect_error.ShowModal()
else:
monitorStarted = wx.MessageDialog(None,"Monitor on %s started"%selectInterfaceStr,"",wx.OK|wx.ICON_ERROR)
monitorStarted.ShowModal()
self.monitorInterface_button.Disable()
threading.Thread(target=self.camtableDetection,args=(selectInterfaceStr,)).start()
threading.Thread(target=self.dhcpexhaustion,args=(selectInterfaceStr,)).start()
def camtableDetection(self,getInterface):
global interface
interface = str(getInterface)
THRESH=(254/4)
START = 5
def monitorPackets(p):
if p.haslayer(IP):
hwSrc = p.getlayer(Ether).src
if hwSrc not in hwList:
hwList.append(hwSrc)
delta = datetime.datetime.now() - start
if((delta.seconds > START) and ((len(hwList)/delta.seconds) > THRESH)):
print "[*]- Detected CAM Table Attack."
#camAttackDetected = wx.MessageDialog(None,"Cam Attack Detected","",wx.ICON_ERROR)
#camAttackDetected.ShowModal()
hwList = []
start = datetime.datetime.now()
sniff(iface=interface,prn=monitorPackets)
def dhcpexhaustion(self,getInterface):
interface = str(getInterface)
global reqCnt
global ofrCnt
reqCnt = 0
ofrCnt = 0
def monitorPackets(p):
if p.haslayer(BOOTP):
global reqCnt
global ofrCnt
opCode = p.getlayer(BOOTP).op
if opCode == 1:
reqCnt=reqCnt+1
elif opCode == 2:
ofrCnt=ofrCnt+1
print "[*] - "+str(reqCnt)+" Requests, "+str(ofrCnt)+" Offers."
sniff(iface=interface,prn=monitorPackets)
I am thinking to stop the threading when I click on a button, but have no idea how can it can be done.
There are self.abort techniques, but I'm not sure how to apply it in my code.
As I said in a comment:
If [sniff is] a function that you have no control over (e.g., from a C extension module) and it loops forever, then it must have some way to cancel it. Maybe it's having your callback return a special value, maybe it's calling a control function, maybe it's closing the object it's working on… whatever it is, you have to do that.
So, why not read the documentation for scapy.sniff to see how to cancel it?
Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
count: number of packets to capture. 0 means infinity
store: wether to store sniffed packets or discard them
prn: function to apply to each packet. If something is returned,
it is displayed. Ex:
ex: prn = lambda x: x.summary()
lfilter: python function applied to each packet to determine
if further action may be done
ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
opened_socket: provide an object ready to use .recv() on
stop_filter: python function applied to each packet to determine
if we have to stop the capture after this packet
ex: stop_filter = lambda x: x.haslayer(TCP)
So, the way to stop it sniffing forever is to pass it a stop_filter function, which will return True when you want to stop it. So that function is where you're going to check your stop flag. For example:
def __init__(self, whatever):
self.stopflag = False
self.stoplock = threading.Lock()
# rest of your init
def stop(self):
with self.stoplock:
self.stopflag = True
def stop_filter(self):
with self.stoplock:
return self.stopflag
def dhcpexhaustion(self, getInterface):
# etc.
sniff(iface=interface,prn=monitorPackets, stop_filter=self.stop_filter)
You're probably going to want to store the two Thread objects at start time, so you can join them at stop time, rather than just leaking them until your program exits. But otherwise, this should do it.
I am having an issue where when i return 2 variables from one class to another function causing it to run it doesn't seem to run properly. I think the issue is with my if statement but i cant get it to work. when i print the variables before the if statement they show the correct things. however when i moved the print section into the statement it showed that only the else part was running every time. it is the MotorControl function i am referring to, i included the rest in case the issue lies else where.
These set of functions control the pin inputs which choose the direction of the motor.
def clockwise():
io.output(in1_pin, True)
io.output(in2_pin, False)
def counter_clockwise():
io.output(in1_pin, False)
io.output(in2-pin, True)
def stop():
io.output(in1_pin, False)
io.output(in2_pin, False)
This class is my server section of a socket server which receives the control commands from another program running on my laptop.
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.DriveSend = self.request.recv(1024).strip()
self.SteeringSend = self.request.recv(1024).strip()
#print("{} wrote:".format(self.client_address[0]))
self.SteeringSend = self.request.recv(1024).strip()
#print("{} wrote:".format(self.client_address[0]))
#print(self.DriveSend)
#print(self.SteeringSend)
#self.request.sendall(self.DriveSend.upper())
#self.request.sendall(self.SteeringSend.upper())
MotorControl(self)
return (self.DriveSend,self.SteeringSend)
This function takes the return outputs from the server class and is meant to cause the clockwise and anticlockwise functions to cause the motors to turn 'forward' and 'reverse'.
def MotorControl(motor_var):
speed = 1
#print(motor_var.SteeringSend)
#print(motor_var.DriveSend)
print('test')
Drive = str(motor_var.DriveSend)
if Drive == "reverse":
speed = 99
print(Drive)
counter_clockwise()
elif Drive == "forward":
speed = 99
print(Drive)
clockwise()
else:
stop()
set("duty", str(speed))
I'm writing the code for a robot which my college is entering into a competition. I'm currently trying to build some wheel encoders using reflectance sensors. I realised a while back that I would probably need to use threading to achieve this, seeing as the robot needs to monitor both the left and right encoders at the same time. The code below is what I have so far:
from __future__ import division
import threading
import time
from sr import *
R = Robot()
class Encoder(threading.Thread):
def __init__(self, motor, pin, div=16):
self.motor = motor
self.pin = pin
self.div = div
self.count = 0
threading.Thread.__init__(self)
def run(self):
while True:
wait_for(R.io[0].input[self.pin].query.d)
self.count += 1
def rotations(self, angle, start_speed=50):
seg = 360/self.div
startcount = self.count
current_dist = angle #Distance away from target
R.motors[self.motor].target = start_speed
while current_dist > 360:
newcount = self.count - startcount
current_dist = angle - newcount*seg
R.motors[self.motor].target = 50
while abs(current_dist) > seg/2:
newcount = self.count - startcount
current_dist = angle - newcount*seg
current_speed = start_speed * current_dist / 360
if current_speed < 5:
R.motors[self.motor].target = 5
else:
R.motors[self.motor].target = current_speed
R.motors[self.motor].target = 0
WheelLeft = Encoder(0,0)
WheelLeft.start()
WheelRight = Encoder(1,3)
WheelRight.start()
WheelRight.rotations(720)
WheelLeft.rotations(720)
The sr module is provided by Southampton University, who are running the competition. It allows us to interact with the robot's hardware.
Now, the threads which get created seem to allow the two reflectance sensors to be monitored separately. This bit of code: R.io[0].input[self.pin].query.d works out whether the value coming from the reflectance sensor has changed. The 'rotations' method turns the wheel through a certain angle by constantly checking how many degrees the wheel has already turned through, and slowing it down as it reaches the end. I would like both wheels to start turning when I run the program, and then slow down and stop when they have gone through 2 rotations. Currently though, when I run the program, one wheel starts turning and slows down and stops, followed by the other wheel. It seems to me like the 'rotations' method is not running in a thread, like the 'run' method is. Is it only the code under the 'run' method that runs in a thread, or is it the whole class?
If it helps, I've been following this tutorial: http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/
Also, I would like to know why it is possible to start a thread only with Encoder(0,0).start(). Why do you not have to create an object using the class (e.g. Thread = Encoder(0,0).start() for a new thread to be created?
Sorry if the terminoligy I've used isn't up to scratch, as you can probably tell I'm quite new to threading, and programming in general.
Encoder(0,0).start() is a call to the method to start the thread. In turn, this method calls your run implementation, which doesn't use the rotations method. If you want to do so, then you have to call it in the while loop of run.
With Thread = Encoder(0,0).start() you store the value retrieved from that call (which is None), but to get it you need to start the new thread first anyway.
The run method is the thread of execution.
If you want something else to happen in that thread, you have to call it from Encoder.run().
Oh, and Encoder(0,0).start() does create an object. Just because you didn't bind that object to a local variable doesn't mean it doesn't exist. If it didn't exist you couldn't call its start method.
You have to be very careful about its lifetime though, without a local variable keeping it alive.
You can extend from SR's Poll class so that it can be used in a wait_for:
import poll
class Encoder(poll.Poll):
def __init__(self, motor, pin, div=16):
self.motor = motor
self.pin = pin
self.div = div
self.count = 0
self.target_reached = False
# kick off a thread to count the encoder ticks
self.counter_thread = threading.Thread(target=self._update_count)
self.counter_thread.start()
def _update_count(self):
while True:
wait_for(R.io[0].input[self.pin].query.d)
self.count += 1
def rotations(self, angle, start_speed=50):
if not self.target_reached:
raise Exception("Last motion still in progress!")
self.target_reached = False
# kick off a thread to control the speed
self.angle_thread = threading.Thread(
target=self._update_speeds,
args=(angle, start_speed)
)
self.angle_thread.start()
def _update_speeds(self, angle, start_speed):
# control the motor speed as before
...
# let things know we're done
self.target_reached = True
# implement poll methods
def eval(self):
return (self.target_reached, None)
Which then lets you do:
wheelLeft = Encoder(0,0)
wheelRight = Encoder(1,3)
wheelRight.rotations(720)
wheelLeft.rotations(720)
wait_for(wheelRight & wheelLeft)
Note that an encoder isn't itself a thread - it's a "has a" relationship, not an "is a" relationship