Python Forum

Full Version: pythonic way of coding
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
hello
i "came" from C, i just started with python 3.6 and i wrote this:
it is a script that running on my pc emulate the inizialize sequence of an ECU (the things that are into motorbike, cars ecc) and also send to a MCU an array of fake sensors data

# -*- coding: utf-8 -*-


import serial, time
from random import randint

startCom = ["0x81", "0x12", "0xf1", "0x81", "0x5"]
startCom_ok = [0x80, 0xF1, 0x12, 0x03, 0xC1, 0xEA, 0x8F, 0xC0]
requestSens = ["0x80", "0x12", "0xf1", "0x2", "0x21", "0x8", "0xae"]
fakeSens = [0x80, 0xF1, 0x12, 0x34]
request = [None]*7
ECUConnected = False
lastByte = False
byte = 0
default_port = '/dev/ttyUSB0' # ' ' for windows

print ("default port is: '"+default_port+"' write if different")
user_input = input("Serial:") or default_port
print('Choosed port:', user_input)

ser = serial.Serial(
    port=user_input,
    baudrate=115200,
    parity=serial.PARITY_NONE,
    stopbits=serial.STOPBITS_ONE,
    bytesize=serial.EIGHTBITS,
    timeout = None
    #timeout = 1
)


def send (toSend):
    #send an array of int as binary data
    for i in toSend:
        ser.write(i.to_bytes(1,byteorder='little'))
        #in python 2.7 use: ser.write(chr(i))  
        time.sleep(0.01)


def compare(received,correct,lengh):
    #compare two array
    #print ("received:",received)
    #print ("correct:",correct)
    coincident = 0
    for i in range(len(correct)):
        if received[i] == correct[i]:
            coincident = coincident+1
            
    if coincident == lengh:
        return True
    else:
        return False


def calc_cs (arr):
    #calculate checksum
    cs = 0
    for i in arr:
        cs += i
    cs &= 0xFF
    return cs


print("Starting ECU Emulator")

while 1:
    startTime = time.time()
    
    while ser.in_waiting > 0:
        #print "# incoming bytes:", ser.in_waiting
        currentTime = time.time()
        #print "time:", currentTime - startTime
        
        while (currentTime - startTime < 2) and (lastByte == False):
            in_bin = ser.read()
            in_hex = hex(int.from_bytes(in_bin,byteorder='little'))          
            #for python 2.x use: in_hex = "0x"+in_bin.encode('hex')
            #print ("incoming:", in_hex, " byte:", byte)

            request[byte] = in_hex

            byte += 1
            currentTime = time.time()
            
            if (in_hex == "0xae") or (in_hex == "0x5"):
                lastByte = True
            
        #print (request)
        byte = 0
        lastByte = False
        
        if ECUConnected == False and compare(request,startCom,len(startCom)):
            #time.sleep(0.04)
            send(startCom_ok)
            print('\nConnection established \n')
            ECUConnected = True
        
        if ECUConnected:
            if compare(request,requestSens,len(requestSens)):
                #time.sleep(0.04)
                print("\nSending fake sensor data \n")
               
                for i in range(0,52):
                    random = randint(0,255)
                    fakeSens.append(random)
               
                cs = calc_cs(fakeSens)
                fakeSens.append(cs)
                '''
                for i in fakeSens:
                    print (hex(i)),
                '''
                send(fakeSens)
                del fakeSens[4:]
                
would you do something in a different way? if yes what?
Quote:for i in range(len(correct)):
no one in python uses range(len()) in a for loop, more info here

Quote:if ECUConnected == False
if not ECUConnected
thanks, i already knew about the smart for loop in python but i am not able to use it to accomplish my task, i wrote it again in a cleaner way so if you want you could test it

startCom = [0x81, 0x12, 0xf1, 0x81, 0x5]
request = ["0x81", "0x12", "0xf1", "0x81", "0x5"]

def compare(received,correct):
  #this function should compare two array and say me if they are equal or not
    coincident = 0
    lengh = len(correct)
    
    for i in correct:
      #how could i compare here the two array without writing it in the C way?
            
    if coincident == lengh:
        return True
    else:
        return False

print (compare(request,startCom))
for item, check in zip(received, correct):
    if item == check:
        coincident += 1
wow... i have to admit python is nice
another way to strip your C style
Quote: if (in_hex == "0xae") or (in_hex == "0x5"):
            if in_hex in ['0xae','0x5']:
Any time you are branching on a Boolean where the value of the Boolean is what you want;

not this:
if coincident == lengh:
    return True
else:
    return False
But this:
return coincident == length
instead of

 
 
def compare(received,correct,lengh):
    #compare two array
    #print ("received:",received)
    #print ("correct:",correct)
    coincident = 0
    for i in range(len(correct)):
        if received[i] == correct[i]:
            coincident = coincident+1
             
    if coincident == lengh:
        return True
    else:
        return False
 
better

def compare(received,correct):
    return all((r==c for r,c in zip(received, correct)))
in any case, third argument length is not necessary - i.e. it's the length of correct anyway....
Also, instead

 
def calc_cs (arr):
    #calculate checksum
    cs = 0
    for i in arr:
        cs += i
    cs &= 0xFF
    return cs
def calc_cs (arr):
    return sum(arr) & 0xFF
(Sep-18-2017, 11:33 AM)metulburr Wrote: [ -> ]another way to strip your C style
Quote: if (in_hex == "0xae") or (in_hex == "0x5"):
            if in_hex in ['0xae','0x5']:
thanks

(Sep-18-2017, 12:34 PM)Mekire Wrote: [ -> ]Any time you are branching on a Boolean where the value of the Boolean is what you want;

not this:
if coincident == lengh:
    return True
else:
    return False
But this:
return coincident == length
yes it is the same in C


(Sep-18-2017, 12:47 PM)buran Wrote: [ -> ]instead of

 
 
def compare(received,correct,lengh):
    #compare two array
    #print ("received:",received)
    #print ("correct:",correct)
    coincident = 0
    for i in range(len(correct)):
        if received[i] == correct[i]:
            coincident = coincident+1
             
    if coincident == lengh:
        return True
    else:
        return False
 
better

def compare(received,correct):
    return all((r==c for r,c in zip(received, correct)))
in any case, third argument length is not necessary - i.e. it's the length of correct anyway....
uhhhhh incredibly stripped Pray but it is not immediate to read for user not used with high level languages

(Sep-18-2017, 12:53 PM)buran Wrote: [ -> ]Also, instead

 
def calc_cs (arr):
    #calculate checksum
    cs = 0
    for i in arr:
        cs += i
    cs &= 0xFF
    return cs
def calc_cs (arr):
    return sum(arr) & 0xFF
i should have immagine that in a language such python there were something like sum()
Pages: 1 2