simple mqtt script in python [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed yesterday.
Improve this question
My code is working well as expected but i would like to improve it. When a loop enter in a big time sleep like 100s how can i force it to change imediatly. if i miss input and put 400s and not 4s i would have to restart the program it's anoying. Here you can see the code
I tried many things like making other variable etc but i'm new and quiet lost.
`import paho.mqtt.client
import time
import threading
monClientMqtt = paho.mqtt.client.Client()
monClientMqtt.connect("localhost",1883)
monClientMqtt.loop_start()
monClientMqtt.subscribe("option")
monClientMqtt.subscribe("periodeX")
monClientMqtt.subscribe("mesureX")
monClientMqtt.subscribe("periodeY")
monClientMqtt.subscribe("mesureY")
monClientMqtt.subscribe("valeurX")
monClientMqtt.subscribe("valeurY")
periodeX =1
mesureX=0
x=0
y=0
periodeY=1
mesureY=0
def CallBack (client, userdata,message) :
global x,periodeX,mesureX,y, periodeY,mesureY
print(message.topic)
print(message.payload)
if message.topic == "option" :
if message.payload.decode() == "restartX" :
x=0
if message.payload.decode()=="restartY":
y=0
if message.topic =="mesureX":
try:
mesureX=float(message.payload.decode())
except ValueError:
print("0 ou 1")
if message.topic =="periodeX" :
try:
periodeX=float(message.payload.decode())
except ValueError :
print("Veuillez entrer un nombre")
if message.topic =="mesureY":
try:
mesureY=float(message.payload.decode())
except ValueError:
print("0 ou 1")
if message.topic =="periodeY" :
try:
periodeY=float(message.payload.decode())
except ValueError :
print("Veuillez entrer un nombre")
def prendremesureX():
while True:
if mesureX==0:
global x,periodeX
x+=1
monClientMqtt.publish("valeurX",x)
time.sleep(periodeX)
def prendremesureY():
while True :
if mesureY==0:
global y,periodeY
y+=1
monClientMqtt.publish("valeurY",y)
time.sleep(periodeY)
threadX=threading.Thread(target=prendremesureX)
threadY=threading.Thread(target=prendremesureY)
monClientMqtt.on_message=CallBack
threadX.start()
threadY.start()

Please see the other comments directing you on how to properly ask questions/how to use stack overflow.
Question issues aside, if I am understanding your question correctly, you are asking; "How can I adjust the delay of my checks, in case there is an emergent need?"
The problem with your current implementation, is that you are using time.sleep(), which is functionally suspending any processing until the time frame expires. This won't work, as you have discovered, since no changes can be made mid-sleep.
What you are looking to do, is to create a task scheduler. You would want to assign a date or time to a specific task, and have a task handler that would do processing of each task, depending on the particular time.
Subsequently, if something needs to be urgently processed, you would update the scheduled time of the task, to be processed as needed.

Related

There is a faster way to use googlemaps API in Python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
Im currently using python to georefernce a dataset of 10512 observations, but is way slow using this code
gmaps = googlemaps.Client(key='APIKEYXXXXXXXXXXXXXXXXXXXXXX')
BD2021['lat']=0
BD2021['lon']=0
for i in range(len(BD2021)):
try:
geocode_result = gmaps.geocode(BD2021['DIRECCION'][i]+',Barranquilla, Colombia')
BD2021['lat'][i]=geocode_result[0]['geometry']['location']['lat']
BD2021['lon'][i]=geocode_result[0]['geometry']['location']['lng']
except:
try:
geocode_result = gmaps.geocode(BD2021['RAZON_SOCIAL'][i]+',Barranquilla, Colombia')
BD2021['lat'][i]=geocode_result[0]['geometry']['location']['lat']
BD2021['lon'][i]=geocode_result[0]['geometry']['location']['lng']
except:
pass
Theres is any faster way that you can recommend, that script have been loading for 30 mins and I dont know even its doing a good job.
Without knowing at all what BD2021 is in more detail, it's hard to definitively help, but a variation like this has more robust error handling, and also a cache, so if the same address happens to be multiple times in your dataset, the program will only geocode it once per run. (You could use a package like diskcache for a more persistent cache.)
from functools import cache
# ...
gmaps = googlemaps.Client(key="APIKEYXXXXXXXXXXXXXXXXXXXXXX")
#cache
def get_geocode(address):
return gmaps.geocode(address)
BD2021["lat"] = {}
BD2021["lon"] = {}
for i in range(len(BD2021)):
for possible_address in (
BD2021["DIRECCION"][i] + ",Barranquilla, Colombia",
BD2021["RAZON_SOCIAL"][i] + ",Barranquilla, Colombia",
):
try:
geocode = get_geocode(possible_address)
if geocode and geocode[0]:
BD2021["lat"][i] = geocode[0]["geometry"]["location"]["lat"]
BD2021["lon"][i] = geocode[0]["geometry"]["location"]["lng"]
break
except Exception as e:
print(f"Error processing {possible_address}: {e}")
else:
print(f"Could not find geocode for index {i}")

How do make text in print() and input() appear one by one? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Almost like an RPG game, I want to make text appear as if someone is typing them. I have an idea of how to do it with the print() function in python, something involving the sleep() and maybe with sys.stdout.flush?
How would I do it text coming before an input function?
For example, I want What is your name? to be typed out, and then the user would input his name.
You can use this:
text = 'What is your name? '
for x in text:
sys.stdout.write(x)
sys.stdout.flush()
time.sleep(0.00001)
name = input()
you can randomize the sleep time per loop as well to mimic typing even better like this:
import time,sys,random
text = 'What is your name? '
for x in text:
sys.stdout.write(x)
sys.stdout.flush()
time.sleep(random.uniform(.000001, .000019))
name = input()
as Tomerikoo pointed out, some systems have faster/slow delays so you may need to use uniform(.01, .5) on another system. I use OS/X.
On windows this probably works better. Thanks Tomerikoo:
import time,sys,random
text = 'What is your name? '
for x in text:
print(x, end="", flush=True)
time.sleep(random.uniform(.000001, .000019))
# or smaller sleep time, really depends on your system:
# time.sleep(random.uniform(.01, .5))
name = input()
You can use the following code:
import time,sys
def getinput(question):
text = input(question)
for x in text:
sys.stdout.write(x)
sys.stdout.flush()
time.sleep(0.00001) #Sets the speed of typing, depending on your system
Now everytime you call getinput("Sample Question"), you would get the user's input based on the question you passed to the function.

function start to run in the first second of the minute [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want a function start to run in the first second of the minute but i can't do it
this is my code
import datetime
now = datetime.datetime.now()
while not (now.second == "01"):now = datetime.datetime.now()
Your code doesn't work because you're comparing a number (now.second) to a string "01". In Python numbers and their string representations are not equal (unlike some other programming languages), so this will never work.
Try comparing with 1 (or maybe 0 if you really want the top of the minute). And maybe instead of busy-looping (which will use all of one core of your CPU while waiting), you should perhaps instead use time.sleep to wait until the start of the next minute.
import datetime
import time
now = datetime.datetime.now()
sec = now.second
if sec != 0:
time.sleep(60-sec)
# it should be (close to) the top of the minute here!
There's always some unpredictability when dealing with time on a computer, since your program might be delayed from running by the OS at any moment (more likely if your CPU is very busy). I'd not worry about it too much though, likely it's good enough to be very close to the right time.
import time
while True:
if time.strftime("%S") == "01":
#Run Your Code
time.sleep(59)
That would pound your system like crazy, give it a little room to breathe:
import time
while True:
current_seconds = time.gmtime().tm_sec
if current_seconds == 1:
print("The first second of a minute...")
time.sleep(0.9) # wait at least 900ms before checking again
You can further streamline it by calculating how much time to wait before you start checking again - if you're interested only in the first second you can safely sleep until the end of the minute.

Doing something after for loop finishes in same function? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is this possible? I'm doing an bukkit plugin now (in Python, yes :D), and I'm forced to do this within one function, so I can't separate it and call it later... For example, if I have loop that loops through players on server and adds everyone except one player, I want it to finish, and then teleport i.e. "Player1" to random player. At the moment, it teleports "Player1" to random player every time because of for loop... I'll give you just little of code, since It looks messy in preview due to many things that are not involved in problem and could be confusable to you... Here it is:
listica = []
for p1 in org.bukkit.Bukkit.getWorld(nextvalue).getPlayers():
if p1.getName() not in listica:
try:
listica.remove(event.getPlayer().getName())
randomtarget = choice(listica)
randomtargetreal = org.bukkit.Bukkit.getPlayer(randomtarget)
event.getPlayer().teleport(randomtargetreal)
event.getPlayer().sendMessage("%sYou teleported to: %s%s"% (bukkit.ChatColor.GREEN, bukkit.ChatColor.DARK_GREEN, randomtarget))
except ValueError:
randomtarget = choice(listica)
randomtargetreal = org.bukkit.Bukkit.getPlayer(randomtarget)
if event.getPlayer().getLocation() != randomtargetreal.getLocation():
event.getPlayer().teleport(randomtargetreal)
event.getPlayer().sendMessage("%sYou teleported to: %s%s"%(bukkit.ChatColor.GREEN, bukkit.ChatColor.DARK_GREEN, randomtarget))
What I want is:
run for loop:
when there is no more players to add a.k.a it finishes
do try loop
P.S. I can't do it in separate function.
Thanks in advance! :)
Do you mean:
def func(args):
for item in loop:
do something
try: # note indentation
something else

Appropriate Class Usage? - Python [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
So, I've been using a simple paradigm for my command line application. One base class called "Command" is inherited multiple times so I can use the child classes to do my dirty work in a while loop. This while loop asked for a command and ran that input through a dictionary to point to the correct class and call Command().run() (The classes needed to be initialized for several unimportant reasons). It looks something like this:
class Command(object):
#Some of these parent variables where used as constants and
#redefined in the global scope
dir = ""
password = ""
target = ""
status_msg = "only for child classes"
def __init__(self):
self.names = [self.__class__.__name__.lower()]
def run(self):
raise NotImplementedError("There has to be code for the program to run!")
class End(Command):
status_msg = "Closing program and resources ..."
def __init__(self):
Command.__init__(self)
names = [
"exit", "close", "quit"
]
self.names.extend(names)
def run(self):
#Do checks and close resources?
sys.exit()
while True:
command = input("What will you be doing with said folder? ")
try:
cmd = commands[strip(command.lower())]() # Strip is defined elsewhere in the code
print("\n", cmd.status_msg, "\n")
cmd.run()
except Exception as __e:
print("Error: \n " + str(__e))
print("Perhaps you misspelled something? Please try again \n")
and other classes would overwrite the run commands and the class variables.
I've been wondering whether or not this is a Pythonic use of classes, and whether or not is efficient. In the end this amounts to two questions.
Is this a pythonic use of classes?
Is this the most efficient way to code something like this?
Any help is welcome; I'm not a coding pro, but I always like to learn something new about one of my favorite coding languages! (I am willing to edit this post if you guys think the question is worded incorrectly, because I'm not completely confident it will make sense to everybody.)

Categories