Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
pythonic way of coding
#1
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?
Reply
#2
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
Recommended Tutorials:
Reply
#3
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))
Reply
#4
for item, check in zip(received, correct):
    if item == check:
        coincident += 1
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
wow... i have to admit python is nice
Reply
#6
another way to strip your C style
Quote: if (in_hex == "0xae") or (in_hex == "0x5"):
            if in_hex in ['0xae','0x5']:
Recommended Tutorials:
Reply
#7
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
Reply
#8
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....
Reply
#9
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
Reply
#10
(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()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  which is "better" (or more Pythonic)? Skaperen 2 2,017 Feb-01-2020, 03:10 PM
Last Post: Skaperen
  which is "better" (or more Pythonic)? Skaperen 7 3,143 Feb-01-2020, 03:51 AM
Last Post: Skaperen
  which is "better" (or more Pythonic)? Skaperen 8 3,229 Nov-16-2019, 06:46 PM
Last Post: Skaperen
  which is more Pythonic? Skaperen 5 2,781 Jul-16-2019, 01:00 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020