Permalänk

Python och type casts

Använder Python 3.6 (krav) och ska anropa en funktion api.connect_to_emu_with_snr(snr) och denna parameter måste vara en uint32. Den kommer in som en parameter från överliggande program som en str. Sen försöker jag på olika sätt få anropet att fungera men Python skriker om att det är ett type fel. Det ska var uint32. Jag googlar och provar det mesta. Inget fungerar. Jag har fått det att fungera EN gång och parametern såg ut så här ((int)24523913). Det fungerade. Provade och återställa denna händelse och det funkade inte. Haha.
Vet nån om det finns nån mer information som delas och inte bara dessa 4 byten? Kan man styra Phyton på ett annat sätt?
Obegripligt.

Jag har provat två lösningar där den ena baseras på struct och den andra på x+2**32.

Tacksam för alla tips som kan finnas.

Permalänk
Medlem

Python har väl inte uint32 som datatyp, vilket bibliotek använder du?
Fungerar det när du bara skickar in en siffra mellan [0,2^32)?

Permalänk
Hedersmedlem

Du får jättegärna:

1. Posta ett kort program som visar problemet.
2. Posta felmeddelanden du får
3. Annan bra info

Som du skrivit din fråga idag går det inte riktigt att svara på, får inte grepp om vad det är som går fel.

Permalänk
Hedersmedlem

Vänta lite, googlade på det där funktionsnamnet, och tror jag hittat något. Kan det vara pynrfjprog som du försöker använda?

Om man läser källkoden för funktionen så framgår det att libben anropar is_u32 på argumentet, och den funktionen ser ut så här:

def is_u32(value): return isinstance(value, int) and 0 <= value <= 0xFFFFFFFF

Du måste helt enkelt se till att du har en int. Jag ser att du försökte skriva ((int)24523913) för att konvertera serienumret, och nej, det kommer inte funka. Det är inte så typkonverteringar ser ut i Python. Men du kan prova int(24523913)? Funkar på strängar också.

Permalänk
Skrivet av pv2b:

Vänta lite, googlade på det där funktionsnamnet, och tror jag hittat något. Kan det vara pynrfjprog som du försöker använda?

Om man läser källkoden för funktionen så framgår det att libben anropar is_u32 på argumentet, och den funktionen ser ut så här:

def is_u32(value): return isinstance(value, int) and 0 <= value <= 0xFFFFFFFF

Du måste helt enkelt se till att du har en int. Jag ser att du försökte skriva ((int)24523913) för att konvertera serienumret, och nej, det kommer inte funka. Det är inte så typkonverteringar ser ut i Python. Men du kan prova int(24523913)? Funkar på strängar också.

Du har alldeles rätt. Det är dessutom rätt lib nu nämner.
Jag tror jag skrev (int)234242 på andra försöket och då blev det fel. Det ska givetvis vara int(42314234) som jag skrev första gången då det funkade..
Ja jag har slitit med olika int-försök. Ska läsa på lite mer om det du skickade.

Permalänk
Skrivet av pv2b:

Vänta lite, googlade på det där funktionsnamnet, och tror jag hittat något. Kan det vara pynrfjprog som du försöker använda?

Om man läser källkoden för funktionen så framgår det att libben anropar is_u32 på argumentet, och den funktionen ser ut så här:

def is_u32(value): return isinstance(value, int) and 0 <= value <= 0xFFFFFFFF

Du måste helt enkelt se till att du har en int. Jag ser att du försökte skriva ((int)24523913) för att konvertera serienumret, och nej, det kommer inte funka. Det är inte så typkonverteringar ser ut i Python. Men du kan prova int(24523913)? Funkar på strängar också.

Nu när jag tänker efter kan jag eventuellt ha hela eftermiddagen idag använt formatet (int)(xxxxxxx) och inte int(xxxxxxx). Så där galet blir det när jag sitter o nöter med ett problem. Bättre o gå o lägga sig en stund och reflektera.

Permalänk
Hedersmedlem
Skrivet av Sweedland:

Nu när jag tänker efter kan jag eventuellt ha hela eftermiddagen idag använt formatet (int)(xxxxxxx) och inte int(xxxxxxx). Så där galet blir det när jag sitter o nöter med ett problem. Bättre o gå o lägga sig en stund och reflektera.

Du det galna är att det faktiskt fungerar!

pvz@pvz-ryzen:~$ python3 Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> (int)(1234) 1234 >>>

Men det funkar inte av anledningen du kanske tror. I ett språk som C så är ju (int) hur du gör en typecast, och om du, i C, skriver (int)(1234) så kommer det parsas så här:

(int)(1234) ^^^^ Typecast till int ^^^^^^ Paranteserna här grupperar ett (matematiskt) uttryck, som bara innehåller en term, 1234.

Men i Python blir det istället så här:

(int)(1234) ^^^^ Paranteserna runt int grupperar ett uttryck, resultatet av detta blir "int". Ungefär som en funktionspekare. ^^^^^^ Här representerar parantesen en argumentlista, inte ett uttryck, och paranteserna behövs

Så det är bara av ren "tur" som (int)(1234) funkar i både C och Python.

(int)1234 däremot, vilket om jag ska gissa är vad du försökte skriva, funkar bara i C, eftersom paranteserna krävs för att det ska bli ett funktionsanrop i Python.

int(1234) funkar på samma sätt inte i C, eftersom paranteserna krävs för att det ska bli ett funktionsanrop.

Hoppas jag gissat rätt på vad som blev fel där igår

Permalänk
Skrivet av pv2b:

Du det galna är att det faktiskt fungerar!

pvz@pvz-ryzen:~$ python3 Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> (int)(1234) 1234 >>>

Men det funkar inte av anledningen du kanske tror. I ett språk som C så är ju (int) hur du gör en typecast, och om du, i C, skriver (int)(1234) så kommer det parsas så här:

(int)(1234) ^^^^ Typecast till int ^^^^^^ Paranteserna här grupperar ett (matematiskt) uttryck, som bara innehåller en term, 1234.

Men i Python blir det istället så här:

(int)(1234) ^^^^ Paranteserna runt int grupperar ett uttryck, resultatet av detta blir "int". Ungefär som en funktionspekare. ^^^^^^ Här representerar parantesen en argumentlista, inte ett uttryck, och paranteserna behövs

Så det är bara av ren "tur" som (int)(1234) funkar i både C och Python.

(int)1234 däremot, vilket om jag ska gissa är vad du försökte skriva, funkar bara i C, eftersom paranteserna krävs för att det ska bli ett funktionsanrop i Python.

int(1234) funkar på samma sätt inte i C, eftersom paranteserna krävs för att det ska bli ett funktionsanrop.

Hoppas jag gissat rätt på vad som blev fel där igår

Haha. Tack. Snurrigt värre. Jag kollade källkoden och där gör den ett typecast EFTER att den gjort kontrollen att det är en uint32. Fattar nada.
Jag håller på och jagar felet. Den returnerar följande "Python returned the following error: <class 'TypeError'>
bad argument type for built-in operation".
Att klistra in källkoden här från mitt Pythonscript är onödigt då koden bara är def funknamn(hex_file, sno) och sen funktionsanropet som spökar. Jag har inga konstiga typecasts etc.

Permalänk
Hedersmedlem
Skrivet av Sweedland:

Haha. Tack. Snurrigt värre. Jag kollade källkoden och där gör den ett typecast EFTER att den gjort kontrollen att det är en uint32. Fattar nada.
Jag håller på och jagar felet. Den returnerar följande "Python returned the following error: <class 'TypeError'>
bad argument type for built-in operation".
Att klistra in källkoden här från mitt Pythonscript är onödigt då koden bara är def funknamn(hex_file, sno) och sen funktionsanropet som spökar. Jag har inga konstiga typecasts etc.

Det är absolut inte onödigt att posta koden som orsakar felet, det är ju nödvändigt för att hitta vad du gör fel och utesluta attt det ärdin kod. (För vad skulle det annars vara?)

Du behöver dock inkludera varifrån hex_file och sno kommer dock

Permalänk
Skrivet av pv2b:

Det är absolut inte onödigt att posta koden som orsakar felet, det är ju nödvändigt för att hitta vad du gör fel och utesluta attt det ärdin kod. (För vad skulle det annars vara?)

Du behöver dock inkludera varifrån hex_file och sno kommer dock

Jag gjorde en entry point i filen så jag kunde anropa den från Terminalen. Då kunde den s.a.s rapportera vad som var fel på ett annat sätt och jag kunde sätta print(xxx) som debugutskrift. Anropande program (Labview, kan inte hantera print() med den metod jag använder för tillfället.) Det visade sig att den ena parametern innehåll en path och med den kom backslash. Det var felet. Fixade iordning py filen och ändrade parametern så path hade forward-slash. PY filen började programmerade målet. Mycket bra tänkte jag.
Gick tillbaks till anropande program (Labview) och lade in ett filter som bytte alla backslash mot forward-slash. Testade. Funkade!!
Gick tillbaka till labview koden och satte en label 0.3.06 som är en versionsbenämning. Då såg jag att jag satt backslash utbytet på fel parametar - det innebar att py-filen fick ändå backslash i parametern men ändå funkade.
Där är jag nu. Det funkar. Åtgärden gjorde ingen nytta och det funkar ändå. Jag blir galen.

Hur som helst. Anropen till den api-funktion som programmerar har två parametrar. int(sno) och int(4000). Det sista är prog.speeden.

edit: Jag tror jag ska byta ut Labviews modul som är skapad för att anropa PY-skript mot ett terminalobjekt. Labview har ett Terminalobjekt som tar emot kommandosträngar typ "Python pytonscript.py param1 param2". Sen har den en stdout. Den terminalen är ärligare. Jag vet inte riktigt vad modulen som Labview har speciellt för att anropa PY-script har för sig under huven.