Topic: Convertire funzione da VB a Python  (Letto 686 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Bokka

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Convertire funzione da VB a Python
« il: Maggio 19, 2017, 08:57 »
Ciao a tutti!

Fino ad ora ho sempre programmato con Visual Basic, però ora mi è stato chiesto di "spostare" alcuni miei lavori su Python. Diciamo che sto imparando in maniera blanda questo linguaggio in questo periodo, mi sono anche iscritto a questo forum per chiedere eventnualmente alcune delucidazioni.

Il fatto è che dovrei convertire una vecchia funzione di VB a python, per il calcolo del modbus.

Il codice è il seguente:

Citazione
Sub Modbus_CRC(strInput As String) As String
    Dim RetCRC As String
    Dim RetStr As String
   
    Dim CRCREG As Int
    Dim MVAL As Int
   
    Dim R As Short
    Dim I As Short
    Dim A As Int
    Dim B As Int
   
    CRCREG = 0xFFFF
 
    For R = 0 To strInput.Length - 1 Step 2
        RetStr = strInput.SubString2(R, R + 2)
        MVAL = Bit.ParseInt(RetStr, 16)
       
        CRCREG = Bit.Xor(CRCREG, MVAL)
        CRCREG = Bit.And(CRCREG, 0xFFFF)
 
        For I = 1 To 8 Step 1
            If Bit.And(CRCREG, 0x01) = 1 Then
                CRCREG = Bit.Xor(Bit.UnsignedShiftRight(CRCREG, 1), 0xA001)
                CRCREG = Bit.And(CRCREG, 0xFFFF)
            Else
                CRCREG = Bit.UnsignedShiftRight(CRCREG, 1)
                CRCREG = Bit.And(CRCREG, 0xFFFF)
            End If
        Next
    Next
 
    A = Bit.And(CRCREG, 0xFF)
    B = Bit.And(CRCREG, 0xFF00)
    A = A * 256
    B = B / 256
 
    If (A + B) < 16 Then
        RetCRC = "000" & (A + B)
    Else If (A + B) < 256 Then
        RetCRC = "00" & Bit.ToHexString(A + B)
    Else If (A + B) < 4096 Then
        RetCRC = "0" & Bit.ToHexString(A + B)
    Else
        RetCRC = Bit.ToHexString(A + B)
    End If
   
    Return RetCRC.ToUpperCase
End Sub


C'è qualcuno che riuscirebbe in poco tempo a convertire questo codice? Grazie mille in anticipo!!

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.641
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:Convertire funzione da VB a Python
« Risposta #1 il: Maggio 19, 2017, 09:19 »
Per convertire questo codice basta studiare i primi capitoli di qualsiasi tutorial su python... Sono solo operazioni su interi e stringhe...

Offline Bokka

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Re:Convertire funzione da VB a Python
« Risposta #2 il: Maggio 19, 2017, 10:39 »
Per convertire questo codice basta studiare i primi capitoli di qualsiasi tutorial su python... Sono solo operazioni su interi e stringhe...

Avevo notato anche io, però non capisco questa parte di codice:

Citazione
  CRCREG = Bit.Xor(CRCREG, MVAL)
        CRCREG = Bit.And(CRCREG, 0xFFFF)
 
        For I = 1 To 8 Step 1
            If Bit.And(CRCREG, 0x01) = 1 Then
                CRCREG = Bit.Xor(Bit.UnsignedShiftRight(CRCREG, 1), 0xA001)
                CRCREG = Bit.And(CRCREG, 0xFFFF)
            Else
                CRCREG = Bit.UnsignedShiftRight(CRCREG, 1)
                CRCREG = Bit.And(CRCREG, 0xFFFF)

In python, come posso convertire "Bit.Xor", "Bit.And" ecc...?

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.641
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:Convertire funzione da VB a Python
« Risposta #3 il: Maggio 19, 2017, 12:32 »
xor è ^, and è &, shift right è >>, eccetera.

Occhio solamente che in python non esiste builtin il concetto di short, int, eccetera.

Offline Bokka

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Re:Convertire funzione da VB a Python
« Risposta #4 il: Maggio 22, 2017, 10:25 »
Ho provato a guardare per il codice, alla fine però con la seguente funzione, ricevo un generico "syntax error"...


def calc(data):
        crc_table=[0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040]
       

        crc_hi=0xFF
        crc_lo=0xFF

        for w in data:
                index=crc_lo ^ ord(w)
                crc_val=crc_table[index]
                crc_temp=crc_val/256
                crc_val_low=crc_val-(crc_temp*256)
                crc_lo=crc_val_low ^ crc_hi
                crc_hi=crc_temp

        crc=crc_hi*256 +crc_lo
        print (crc)
        return crc




Offline Giornale di Sistema

  • python sapiens sapiens
  • ******
  • Post: 3.124
  • Punti reputazione: 4
    • Mostra profilo
    • Distillato di Python
Re:Convertire funzione da VB a Python
« Risposta #5 il: Maggio 22, 2017, 13:03 »
Ho provato a guardare per il codice, alla fine però con la seguente funzione, ricevo un generico "syntax error"...

Talmente generico che non ti indica neanche la riga dov'è localizzato l'errore?

Offline Bokka

  • python unicellularis
  • *
  • Post: 7
  • Punti reputazione: 0
    • Mostra profilo
Re:Convertire funzione da VB a Python
« Risposta #6 il: Maggio 23, 2017, 09:38 »

Talmente generico che non ti indica neanche la riga dov'è localizzato l'errore?

Esatto!

In poche parole sto cercando di creare una funzione che calcoli il CRC16 di una stringa:

11 01 00 03 00 0C

Il CRC calcolato deve risultare

CE9F (CE High, 9F Low)

E per la stringa:
11 01 02 CD 0B

Il CRC calcolato deve essere

6D 68


....Sto facendo dei progressi, ma ancora nulla, mi sa che sono ancora lontano dal risultato finale.... :thinking:


Piccolo edit per dire che l'errore di sintassi l'ho risolto, era una cosa veramente stupida da parte mia. Però con i codice che ho scritto non calcola correttamente l'output....
« Ultima modifica: Maggio 23, 2017, 10:03 da Bokka »

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.641
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:Convertire funzione da VB a Python
« Risposta #7 il: Maggio 23, 2017, 12:05 »
Occhio solamente che in python non esiste builtin il concetto di short, int, eccetera.

Offline Claudio_F

  • python sapiens sapiens
  • ******
  • Post: 1.157
  • Punti reputazione: 2
    • Mostra profilo
Re:Convertire funzione da VB a Python
« Risposta #8 il: Maggio 27, 2017, 10:45 »
Citazione da: GlennHK
Occhio solamente che in python non esiste builtin il concetto di short, int, eccetera
In questo specifico caso non vi sono differenze di cui tener conto. Ci sono solo shift a destra, l'unico a sinistra è di un valore a 8 bit. Anche tutti gli and con 0xFFFF si possono omettere. Sicuramente in Python, spero anche in VB, altrimenti significherebbe che negli shift a destra VB immette a sinistra porkerie random.

Citazione da: Bokka
Talmente generico che non ti indica neanche la riga dov'è localizzato l'errore?
Esatto!
Errato!  Python dice *sempre* dove trova l'errore.

Citazione
Però con i codice che ho scritto non calcola correttamente l'output
Ci sono molti algoritmi diversi per il calcolo del CRC16 che danno risultati finali diversi. Se si vuole ottenere quello del Modbus bisogna usare l'algoritmo previsto dal Modbus (che è quello riportato nel codice VB).

Tra parentesi mi sembra che la riga
RetCRC = "000" & (A + B)
sia sbagliata... ma non conosco VB per esserne assolutamente certo.

È possibile una traduzione "letterale" di quel codice, pari pari riga per riga, salvo le dichiarazioni delle variabili (e i vari end if e next) che in Py non esistono.

Le uniche traduzioni che possono essere "ostiche" per un Pyprincipiante sono i for:
for R in range(0, len(strInput), 2):

e la conversione di interi in stringhe esadecimali:
RetCRC = "000" + hex(A + B)[2:]

Tutte le altre operazioni sono semplici espressioni, così la riga seguente:
CRCREG = Bit.Xor(Bit.UnsignedShiftRight(CRCREG, 1), 0xA001)

diventa:
CRCREG = (CRCREG >> 1) ^ 0xA001
« Ultima modifica: Maggio 27, 2017, 11:14 da Claudio_F »