as you can see i am writing the same code over and over again, how can i make an algorithm so to say, to iterate just a list of the parameters through the same line of code. Is that possible in this scenario or not. What i am doing is i am programming some values into a device through a serial connection. I want to automate it so yeah. This code works perfectly fine but i want to know how to write an algorithm to iterate through only the parameters. as yo can see only the .encode() value and the ft value is different in every line An example would be very helpful.
def write_par(self):
try:
reset_input = self.ser.reset_input_buffer()
reset_input
self.ser.write('\r\nft_seton ordoxo '.encode() self.artikel_va.encode() '\r\n'.encode())
reset_input
time.sleep(1.0)
self.ser.write('ft_seton hrdver '.encode() self.HVVV.encode() '\r\n'.encode())
reset_input
time.sleep(1.0)
self.ser.write('ft_seton hrdbrd '.encode() self.HWB.encode() '\r\n'.encode())
reset_input
time.sleep(1.0)
self.ser.write('ft_seton srll '.encode() self.serien_nummer.encode() '\r\n'.encode())
reset_input
time.sleep(1.0)
self.ser.write('ft_seton addr '.encode() self.mac.encode() '\r\n'.encode())
reset_input
time.sleep(1.0)
except Exception:
print('Device parameters were not written')
pass
CodePudding user response:
Just use the Python for
functionality - it will always work as a "for each" and give you each element in a series.
You can either organize the names and attributes as tuples, or use the zip
call:
def write_par(self):
try:
reset_input = self.ser.reset_input_buffer # <- NB. no () in this line, otherwise it is called a single time
self.ser.write("\r\n")
for name, value in [
("ortodoxo", self.artikel_va),
("hrdver", self.HVVV),
("hrdbrd", self.HWB),
("srll", self.serien_nummer),
("addr", self.mac),
]:
self.ser.write(f'nft_seton {name} {value)\r\n'.encode()
reset_input()
time.sleep(1.0)
except Exception as error:
print(f'Device parameters were not written: at {name} we got {error}')
pass
As you can see, also: Python is not Basic, and there is no need to concatenate strings by opening and closing quotations and using the operator. The "f-string" syntax will serve you well.
Another good practice is to print out what went wrong: you have that information while the program is running, and it is basically free to print it. If you print just "could not do it", that just means headaches that could have been avoided downstream.
Also, the first string to be printed out is different in your code: "nft_seto" vs "nt_seton" in your code. I assumed that was a typo. Otherwise, if you really need then to be different, just include this first string in the tuples, in the for loop and add another variable to carry it.
CodePudding user response:
As others commented, put the statements to be executed repeatedly into a separate function. Something like this:
def write_something(self, name, value):
self.ser.write(name.encode() value.encode() '\r\n'.encode())
self.ser.reset_input_buffer()
time.sleep(1.0)
def write_par(self):
try:
write_something('\r\nft_seton ordoxo ', self.artikel_va)
write_something('ft_seton hrdver ', self.HVVV)
...
except Exception:
print('Device parameters were not written')
pass
CodePudding user response:
Ignoring the sleep() calls (not sure why they're there) and also the NOOPs.
Build a control structure and iterate over it like this:
def write_par(self):
CONTROL = {
'\r\nft_seton ordoxo': 'artikel_va',
'ft_seton hrdver': 'HVVV',
'ft_seton hrdbrd': 'HWB',
'ft_seton srll': 'serien_nummer',
'ft_seton addr': 'mac'
}
try:
self.ser.reset_input_buffer()
for k, v in CONTROL.items():
self.ser.write(f'{k} {getattr(self, v)}\r\n'.encode())
except Exception:
print('Device parameters were not written')
CodePudding user response:
When you are trying to remove repetition from code there are two general approaches:
Create a helper function
In this method we create a function which we call multiple times
This makes our code cleaner and easier to understand
If we wanted to apply this to your codedef write_par(self): try: reset_input = self.ser.reset_input_buffer() reset_input self.write_ser('\r\nft_seton ordoxo ', self.artikel_va.encode()) self.write_ser('ft_seton hrdver ', self.HVVV.encode()) self.write_ser('ft_seton hrdbrd ', self.HWB.encode()) self.write_ser('ft_seton addr ', self.mac.encode()) except Exception: print('Device parameters were not written') pass ### Helper Methods ### def write_ser(self, text, frmt): """ Writes a piece of text in encoded format Inputs :text: <str> to be written, i.e '\r\nft_seton ordoxo ' :frmt: <obj> to use for encoding, i.e self.artikel_va.encode() """ # TODO: think about how you would implement this # (hint: you already have) pass
Use a loop
With a loop we are able to reduce the number of times we repeat a piece of code
This is done by storing the different parts in each line inside some variable, usually a list, and iterating through it.
At every iteration you will perform what is shared by each of the lines.
If we wanted to apply this to your codedef write_par(self): try: reset_input = self.ser.reset_input_buffer() reset_input inputs = [ ('\r\nft_seton ordoxo ', self.artikel_va.encode()), ('ft_seton hrdver ', self.HVVV.encode()), ('ft_seton hrdbrd ', self.HWB.encode()), ('ft_seton hrdbrd ', self.HWB.encode()), ('ft_seton addr ', self.mac.encode()) ] for text, frmt in inputs: # TODO: Again you think about how you would implement this except Exception: print('Device parameters were not written') pass
Which approach you should take will depend on what your code does, in your case either option would work, even a mix of both approaches would work!
CodePudding user response:
Define a function to handle this like so
def write_encoded_values(str_a, str_b):
self.ser.write(f'{str_a}{str_b}\r\n'.encode())
then you can call it like this for example
self.write_encoded_values('\r\nft_seton ordoxo ', self.artikel_va)