venerdì 11 febbraio 2022

Rest Client in Python

Dopo la versione in Go la medesima funzione in Python 


import requests
from requests.structures import CaseInsensitiveDict
import json

url = "http://xxxxxxxxxxxxx/api/v1/authentication/"

headers = CaseInsensitiveDict()


headers["api-key"] = "apikey"
headers["Accept"] = "application/json"
headers["api-version"] = "v1"
headers["device-language"] = "it"
headers["id-user-session"] = "guest"
headers["Authorization"] = "Basic Z2xxxxxxxxxxxxxxxxxxxxxxxxxxx=="



resp = requests.get(url, headers=headers)

print(resp.content)
if(resp.ok):
    jData = json.loads(resp.content)

    print("The response contains {0} properties".format(len(jData)))
    print("\n")
    for key in jData:
        print(str(key) + " : " + str(jData[key]))
else:
    resp.raise_for_status()

TicTacToe Go

 Volevo provare a creare una macchina di apprendimento per il gioco TicTacToe (Tris) 

Il passo e' stato quello di creare il gioco per umani...la cosa che mi ha dato piu' soddisfazione e' stata la funzione per determinare la condizione di vittoria dei giocatori

In pratica ogni casella del gioco e' associata ad una potenza di 2...si sommano i valori delle caselle e si fa un AND con la maschera di bit delle condizioni di vittoria

il prossimo passo e' salvare le varie partite con una Trie 

---------------------------

Il nome delle caselle e' cosi' ordinato

0 | 1 | 2
______
3 | 4 | 5
______
6 | 7 | 8



package main

import (
    "fmt"
    "math"
    "os"
    "strconv"
)

var display [9]int // array per mostrare il gioco
var step int       // numero di mossa
var giocatore int
var mossa_valida bool

func reset() {
    for k := 0; k < 9; k++ {
        display[k] = 0
    }
    step = 1
    giocatore = 3
    mossa_valida = false
}

func controlla_vittoria() int {
    totale_1 := 0
    totale_2 := 0

    // per il calcolo della scacchiera ad ogni casella corrispondente un valore di potenza di 2
    // si sommano tutti le caselle occupate da un giocatore
    // poi si effettua un AND logic con le 8 posizioni vincenti

    // giocatore 1
    for k := 0; k < 9; k++ {
        if display[k] == 3 {
            totale_1 = totale_1 + int(math.Pow(float64(2), float64(k)))
        }
    }

    if (totale_1 & 448) == 448 {
        return 1
    }
    if (totale_1 & 56) == 56 {
        return 1
    }
    if (totale_1 & 7) == 7 {
        return 1
    }
    if (totale_1 & 292) == 292 {
        return 1
    }
    if (totale_1 & 146) == 146 {
        return 1
    }
    if (totale_1 & 73) == 73 {
        return 1
    }
    if (totale_1 & 273) == 273 {
        return 1
    }
    if (totale_1 & 84) == 84 {
        return 1
    }

    // giocatore 2
    for k := 0; k < 9; k++ {
        if display[k] == 2 {
            totale_2 = totale_2 + int(math.Pow(float64(2), float64(k)))
        }
    }

    if (totale_2 & 448) == 448 {
        return 2
    }
    if (totale_2 & 56) == 56 {
        return 2
    }
    if (totale_2 & 7) == 7 {
        return 2
    }
    if (totale_2 & 292) == 292 {
        return 2
    }
    if (totale_2 & 146) == 146 {
        return 2
    }
    if (totale_2 & 73) == 73 {
        return 2
    }
    if (totale_2 & 273) == 273 {
        return 2
    }
    if (totale_2 & 84) == 84 {
        return 2
    }

    return 0 // se ritorna 0 nessuno ha vinto
}

func casella(c int) string {
    switch c {
    case 0:
        return (" ")
    case 3:
        return ("X")
    case 2:
        return ("O")
    }
    return " "
}

func mostra_gioco() {
    fmt.Print(casella(display[0]))
    fmt.Print("|")
    fmt.Print(casella(display[1]))
    fmt.Print("|")
    fmt.Println(casella(display[2]))
    fmt.Println("-----")
    fmt.Print(casella(display[3]))
    fmt.Print("|")
    fmt.Print(casella(display[4]))
    fmt.Print("|")
    fmt.Println(casella(display[5]))
    fmt.Println("-----")
    fmt.Print(casella(display[6]))
    fmt.Print("|")
    fmt.Print(casella(display[7]))
    fmt.Print("|")
    fmt.Println(casella(display[8]))
}

func main() {

    var tasto int

    step = 1
    giocatore = 3
    mossa_valida = false
    mostra_gioco()
    fmt.Println("Turno al Giocatore " + strconv.Itoa(giocatore-2))

    for {
        for { // controlla se e' una mossa valida

            if !mossa_valida {
                fmt.Print("Enter move: ")
                fmt.Scanln(&tasto)
                // controlla se e' un tasto valido

                if display[tasto] == 0 { // controlla se la casella e' valida
                    mossa_valida = true
                    display[tasto] = giocatore
                    giocatore = ((giocatore + 1) % 2) + 2
                    fmt.Println("Turno al Giocatore " + string(giocatore+2))
                    break
                } else {
                    fmt.Println("Mossa non valida")
                }

            }
        }

        step++ // aumenta il numero della mossa
        mossa_valida = false
        mostra_gioco()
        v := controlla_vittoria()
        switch v {
        case 1:
            fmt.Println("****************************")
            fmt.Println("*** Vittoria Giocatore 1 ***")
            fmt.Println("****************************")
            reset()
            mostra_gioco()
            break
        case 2:
            fmt.Println("****************************")
            fmt.Println("*** Vittoria Giocatore 2 ***")
            fmt.Println("****************************")
            reset()
            mostra_gioco()
            break
        }
        if step == 9 {
            fmt.Println("***************************")
            fmt.Println("******** Pareggio *********")
            fmt.Println("***************************")
            reset()
            mostra_gioco()
            break
        }
    }
    os.Exit(0)
}

Rest client in GO

Un semplice di client di servizio Restful con GO


package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {
    client := http.Client{}
    req, err := http.NewRequest("GET", "http://xxxxxxxxxxxxxxxxx/api/v1/authentication/", nil)
    if err != nil {
        //Handle Error
    }

    req.Header = http.Header{
        "Host":                  []string{"http://xxxxxxxxxxxxxxxxxx/api/v1/authentication/"},
        "api-key":         []string{"axxxxxxxxxxxx"},
        "api-version":     []string{"v1"},
        "device-language": []string{"it"},
        "id-user-session": []string{"guest"},
        "Accept":                []string{"application/json"},
        "Authorization":         []string{"Basic Z2lvxxxxxxxxxxxxxxsaQ=="},
    }

    res, err := client.Do(req)

    if err != nil {
        fmt.Errorf("got error")
    } else {
        //fmt.Println("--------------------------")
        //fmt.Println(res)
    }
    defer res.Body.Close()

    b, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatalln(err)
    }

    fmt.Println(string(b))
}

JSon in Go

 Leggere Json in Go non e' esattamente banale perche' il linguaggio e' fortemente tipizzato

Se il tracciato record del Json e' fissato e' conosciuto si puo' fare un Unmarshal del tracciato altrimenti con Json dinamici o non conosciuti la situazione diventa piu' complessa

Partiamo da un Json complesso

---------------------------------------------------------------------------

 {
        "statusCode":200,
        "message":"OK",
        "dataValue":
            {
                "versionWS":"v1",
                "language":"it",
                "idUserSession":
                "wguest",
                "user":
                    {
                        "userId":27,
                        "userName":"G",
                        "userSurname":"G",
                        "idUserSession":"c4cefc3032e3f8e63f3ee320b81cf1d5"
                    }
            }
    }

---------------------------------------------------------------------------

per fare l'Unmarshal del Json si deve definire tramite Struct il tracciato record con indicato anche il tipo di variabile associata ad ogni campo...in questo campo essendoci piu' livelli si devono creare delle Struct intermedie per i livelli piu' interni. Da notare che le variabilenelle Struct hanno la prima lettera maiuscola per l'esportazione ed il tag Json corrispondente

Interessa arriva a leggere la proprieta' idUserSession dell'utente (si tratta di gestire una authorization da un servizio Restful)

---------------------------------------------------------------------------

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    UserId        int32  `json:"userId"`
    UserName      string `json:"userName"`
    UserSurname   string `json:"userSurname"`
    IdUserSession string `json:"idUserSession"`
}

type dataValue struct {
    VersionWS            string `json:"versionWS"`
    Language             string `json:"it"`
    IdUserSession        string `json:"idUserSession"`
    Wguest string `json:"wguest"`
    User                 User   `json:"user"`
}

type messaggio struct {
    StatusCode int32     `json:"statusCode"`
    Message    string    `json:"message"`
    DataValue  dataValue `json:"dataValue"`
}

func main() {
    b := []byte(`    {
        "statusCode":200,
        "message":"OK",
        "dataValue":
            {
                "versionWS":"v1",
                "language":"it",
                "idUserSession":"",
                "guest":"",
                "user":
                    {
                        "userId":27,
                        "userName":"G",
                        "userSurname":"G",
                        "idUserSession":"c"
                    }
            }
    }`)
    var mes messaggio
    json.Unmarshal(b, &mes)
    fmt.Println(mes.DataValue.User.IdUserSession)

}

---------------------------------------------------------------------------

fino a qui e' abbastanza lineare. Senza il tracciato record non si puo' fare Unmarshal di una Struct ma si deve passare attraverso una interface e gestire i vari livelli di map fino a trovare il valore richiesto


---------------------------------------------------------------------------
package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    b := []byte(`    {
        "statusCode":200,
        "message":"OK",
        "dataValue":
            {
                "versionWS":"v1",
                "language":"it",
                "idUserSession":"":
                "guest":"",
                "user":
                    {
                        "userId":27,
                        "userName":"G",
                        "userSurname":"G",
                        "idUserSession":"c"
                    }
            }
    }`)

    var dat map[string]interface{}

    if err := json.Unmarshal(b, &dat); err != nil {
        panic(err)
    }
    test := dat["dataValue"].(map[string]interface{})["user"]
    if rec, ok := test.(map[string]interface{}); ok {
        for key, val := range rec {
            if key == "idUserSession" {
                fmt.Printf(" %s = %s", key, val)
                fmt.Println()
            }

        }
    }

}

---------------------------------------------------------------------------



sabato 29 gennaio 2022

Setpixel su C64 (2)

 In un precedente post  avevo gia' affrontato il problema ...leggendo su codebase64 viene proposta una variante che usa delle tabelle di lookup per velocizzare il programma ma non viene presentato il codice completo. Questa e' una implementazione


.macro ClearScreen(screen, clearByte) {
lda #clearByte
ldx #0
!loop:
sta screen, x
sta screen + $100, x
sta screen + $200, x
sta screen + $300, x
sta screen + $400, x
sta screen + $500, x
sta screen + $600, x
sta screen + $700, x
sta screen + $800, x
sta screen + $900, x
sta screen + $a00, x
sta screen + $b00, x
sta screen + $c00, x
sta screen + $d00, x
sta screen + $e00, x
sta screen + $f00, x
sta screen + $1000, x
sta screen + $1100, x
sta screen + $1200, x
sta screen + $1300, x
sta screen + $1400, x
sta screen + $1500, x
sta screen + $1600, x
sta screen + $1700, x
sta screen + $1800, x
sta screen + $1900, x
sta screen + $1a00, x
sta screen + $1b00, x
sta screen + $1c00, x
sta screen + $1d00, x
sta screen + $1e00, x
sta screen + $1f00, x
inx
bne !loop-
}

.macro ClearColorRam(clearByte) {
lda #clearByte
ldx #0
!loop:
sta $0400, x
sta $0400 + $100, x
sta $0400 + $200, x
sta $0400 + $300, x
inx
bne !loop-
}


.macro Hires (){
lda $D018
//ora #%1000
ora #8
sta $D018 // VIC_ADDR + 24
}

.macro BMM (){
lda $D011
//ora #%100000
ora #32
sta $D011 // VIC_ADDR + 17
}


// costanti per la generazioni delle tabelle
// di lookup per calcolare la posizione del pixel
.const GFX_MEM = $2000

.const BitMask = $0a00
.const X_Table = $0b00
.const Y_Table_Lo = $0c00
.const Y_Table_Hi = $0d00

*=$0801 "Loader"
BasicUpstart($0810)


*=$0810 "Main" // SYS 2064

// generazione delle tabelle di lookup
ldx #$00
lda #$80
Loop1:
sta BitMask,x
ror
bcc Skip1
ror
Skip1:
tay
txa
and #%11111000
sta X_Table,x
tya
inx
bne Loop1

lda #<GFX_MEM // Can be replaced with a TXA if GFX_MEM is page aligned
Loop2:
ldy #$07
Loop3:
sta Y_Table_Lo,x
pha
SMC1:
lda #>GFX_MEM
sta Y_Table_Hi,x
pla
inx
dey
bpl Loop3
inc SMC1+1
clc
adc #$40
bcc Skip2
inc SMC1+1
Skip2:
cpx #8*25
bne Loop2

// ********************************************************
jsr $e544 // kernal clear screen
//:SetBorderColor(BLACK)
//:SetBackgroundColor(BLACK)


:Hires()
:BMM()

:ClearScreen($2000,0)
:ClearColorRam($3)



ldx #100 //posizione X del pixel
ldy #100 //posizione Y del pixel
jsr Plott

looper:
jmp looper
rts

Plott:
lda Y_Table_Hi,y
sta $fc
lda Y_Table_Lo,y
sta $fb

ldy X_Table,x
lda BitMask,x
ora ($fb),y
sta ($fb),y
rts





giovedì 27 gennaio 2022

Visual Code Assembler C64

Qualche tempo fa avevo provato CBM Prg Studio ma aveva diverse limitazioni (la prima fra tutte girare solo su Windows)



Per una soluzione multi piattaforma si puo' usare Visual Studio con l'estensione Kick Assembler 8-bit Retro Studio, Kick Assembler, Vice e C64 Debugger

Una volta installata la estensione si devono impostare nei settaggi del plugin le path dei vari componenti

Su Debian ho avuto diversi problemi con C64Debugger...installando la versione binaria viene generato il seguente errore 


sudo ln -sf libxcb-util.so.0 libxcb-util.so.1

il problema e' che la libreria non e' disponibile in apt e fare un symlink semplicemente blocca X al riavvio successivo

Per installare C64debugger da sorgenti si devono seguire i passi seguenti


apt install upx-ucl

git clone git://git.code.sf.net/p/c64-debugger/code c64-debugger-code
cd MTEngine

modificare Makefile aggiungendo -fcommon alle CFlags

make

Grandi poteri fanno grandi casini

 Stavo cercando di installare un software su Linux che viene distribuito in binario e che lamentava una versione di libxcb-util che ho disponibile in apt solo alla versione precedente


Speranzoso ho fatto un symlink con la release precedente ed ho per la prima volta visto questa schermata....libxcb-util e' una parte fondamentale di X ed ha inchiodato tutto  
Ripartito da Grub in recovery si deve prima riattivare a mano la rete (mi sono collegato via cavo) e poi ho forzato la reinstallazione della libreria

/etc/init.d/networking start
dhclient enp0s25
apt --reinstall install libxcb-util1




Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...