Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pub:labprog:2020-11-26 [2020/11/26 17:50] (current)
atrent created
Line 1: Line 1:
 +#  Note lezione (26/​11/​2020)
 +
 +lezione precedente sul wiki del corso: http://​sl-lab.it/​dokuwiki/​doku.php/​pub:​labprog:​home
 +
 +
 +## Mem
 +
 +Questo script funziona su linux, serve anche gnuplot.
 +
 +```bash
 +#!/bin/bash
 +# https://​stackoverflow.com/​questions/​7998302/​graphing-a-processs-memory-usage
 +
 +# IMPORTANTE! limitare mem altrimenti crasha pc
 +LIMIT=2000000 ​ # ok
 +#​LIMIT=20000 # troppo poco
 +ulimit -m $LIMIT
 +ulimit -v $LIMIT
 +ulimit -a
 +
 +#timeout 10 $* &  # non va bene perché osserva il timeout invece del processo
 +$* &
 +PID=$!
 +
 +echo ===
 +while
 + kill -0 $PID 2>/​dev/​null
 +do
 + echo $(date +%s) $(ps --pid $PID -o %mem=)
 + #echo $(date +%s) $(ps --pid $PID -o drs=)
 +
 + #ps --pid $PID -o pid=,​%mem=,​vsz=
 +done | tee prova.mon | gnuplot -p -e "set terminal x11 size 600,400; set yrange [0:3.2]; set ylabel '​mem';​ set xlabel '​timestamp';​ plot \"/​dev/​stdin\"​ with linespoints title '​memory'"​
 +
 +```
 +
 +
 +```go
 +package main
 +
 +import (
 + "​fmt"​
 + "​math/​rand"​
 + "​time"​
 +)
 +
 +const DIM = 10000000 // attenzione a non esagerare che un mio amico gli è morto il pc ;)
 +const SLEEP = 5      // nano
 +
 +func main() {
 + attendo()
 +
 + /* an int array with 5 elements */
 + var balance [DIM]int
 + //var avg float32
 +
 + rand.Seed(time.Now().Unix())
 +
 + fmt.Println("​riempio..."​)
 + for i, _ := range balance {
 + //​fmt.Println(i)
 + balance[i] = rand.Intn(10000)
 + time.Sleep(SLEEP) // nano
 + }
 +
 + attendo()
 +
 + // copy
 + //​fmt.Println(getAverage(balance))
 +
 + // pointer
 + fmt.Println(getAverage2(&​balance))
 +
 + attendo()
 +}
 +
 +func attendo() {
 + fmt.Println("​attendo..."​)
 + time.Sleep(3 * time.Second)
 + fmt.Println("​fine attesa"​)
 +}
 +
 +func getAverage(arr [DIM]int) float64 {
 + var avg float64
 + var sum int64
 +
 + fmt.Println("​calcolo..."​)
 + for i, _ := range arr {
 + sum += int64(arr[i])
 + time.Sleep(SLEEP) // nano
 + }
 +
 + avg = float64(sum) / DIM
 + return avg
 +}
 +
 +func getAverage2(arr *[DIM]int) float64 {
 + var avg float644
 + var sum int64
 +
 + for i, _ := range arr {
 + sum += int64(arr[i])
 + time.Sleep(SLEEP) // nano
 + }
 +
 + avg = float64(sum) / DIM
 + return avg
 +}
 +
 +```
 +
 +
 +## Note esercizi consegnati in settimana (scorsa lezione)
 +
 +### problema lettura specifiche? o concezione di "​specchio"?​
 +
 +```go
 +func specchiaPunto(p *Punto) {
 + (*p).x = -p.x // MANTERREI STESSA SINTASSI A DESTRA E SINISTRA
 + (*p).y = p.y // inutile perché non cambia lo stato
 + return
 +}
 +o
 +func specchiaPunto(p *Punto) {
 + p.x = 0 - (p.x)
 +}
 +o
 +func funzSpecchio(p1 Punto) Punto {  // restituisce invece di modificare
 + var p Punto
 + p.x = -p1.x
 + p.y = p1.y   <<<<<<<<<<<<<<​
 + return p
 +}
 +```
 +
 +
 +invece di 
 +
 +```go
 +func specchiaPunto(p *Punto) {
 + (*p).x *= -1  // corretto
 +}
 +o
 +func specchiaPunto(p *Punto) {
 + (*p).x = -(*p).x // corretto
 +}
 +```
 +
 +
 +
 +### passaggio per puntatore inutile
 +
 +```go
 +func main() {
 + var contaNumeri [10]int
 + var parola string
 + n := 0
 + fmt.Print("​\nInserire una serie di parole terminate da \x22stop\x22:​\n\n"​)
 + for {
 + fmt.Scan(&​parola)
 + if parola == "​stop"​ {
 + break
 + }
 + contaCifre(parola,​ &n, &​contaNumeri) //A COSA SERVE n QUI? meglio fare un return nella fn
 + }
 + fmt.Printf("​\n%d stringhe con cifre\n\n%v\n%v\n\n",​ n, numeri, contaNumeri)
 +}
 +
 +func contaCifre(s string, n *int, x *[10]int) {
 + check := false
 + for _, r := range s {
 + if unicode.IsDigit(r) {
 + appo, _ := strconv.Atoi(string(r))
 + (*x)[appo]++
 + check = true
 + }
 + }
 + if check {
 + (*n)++
 + }
 +}
 +```
 +
 +
 +### ottimizzazione
 +
 +```go
 +//QUI PROBLEMA DI SPECIFICHE, ANDAVA MODIFICATO L'​ARRAY SUL POSTO //AT: anche, ma mi ero concentrato sull'​invocazione multipla di len
 +
 +func reverse(a [DIM]int) [DIM]int { // passare per punt
 + for i := 0; len(a)-i-1 != i; i++ { //IO IN QUESTI CASI PREFERISCO IL > AL != //AT: claro!
 + a[i], a[len(a)-i-1] = a[len(a)-i-1],​ a[i]
 + }
 + return a
 +}
 +```
 +
 +
 +### delega (OK)
 +
 +```go
 +func countdown(c *Clock) {
 + (*c).sec--
 + if (*c).sec < 0 {
 + (*c).sec = 59
 + changeMin(&​c) // "​bastava"​ '​c'​ (è GIA' un puntatore, quindi '&​c'​ è puntatore a puntatore)
 + }
 +}
 +
 +func changeMin(c **Clock) { // idem
 + (**c).min--
 + if (**c).min < 0 {
 + (**c).min = 59
 + changeHour(&​c)
 + }
 +}
 +
 +func changeHour(c ***Clock) { // idem
 + (***c).hour--
 + if (***c).hour < 0 { // questo no se no non termina
 + (***c).hour = 23
 + }
 +}
 +```
 +
 +### compattabile
 +
 +```go
 +//INVITA A FARE GLI ESERCIZI TUTTI E NELL'​ORDINE IN CUI SONO PROPOSTI, LEGGENDO SUGGERIMENTI ECC // diventa istruzione singola (c'era esercizio che suggeriva il modo)
 +
 +
 + BASTAVA '​num_comparsi[char]++'​
 + al posto di:
 +
 + switch char {
 + case '​0':​
 + num_comparsi[0]++
 + case '​1':​
 + num_comparsi[1]++
 + case '​2':​
 + num_comparsi[2]++
 + case '​3':​
 + num_comparsi[3]++
 + case '​4':​
 + num_comparsi[4]++
 + case '​5':​
 + num_comparsi[5]++
 + case '​6':​
 + num_comparsi[6]++
 + case '​7':​
 + num_comparsi[7]++
 + case '​8':​
 + num_comparsi[8]++
 + case '​9':​
 + num_comparsi[9]++
 + default:
 + continue
 + }
 +
 +```
 +
 +### compattabile valori di n da 1 a 9 (oppure array! c'era indicazione nel testo)
 +
 +```go
 +func carta(n int) (carta Carta) {
 + switch n % VALORI {
 + case 0:
 + carta.valore = "​A"​
 + case 1:
 + carta.valore = "​2"​
 + case 2:
 + carta.valore = "​3"​
 + case 3:
 + carta.valore = "​4"​
 + case 4:
 + carta.valore = "​5"​
 + case 5:
 + carta.valore = "​6"​
 + case 6:
 + carta.valore = "​7"​
 + case 7:
 + carta.valore = "​8"​
 + case 8:
 + carta.valore = "​9"​
 + case 9:
 + carta.valore = "​10"​
 + case 10:
 + carta.valore = "​J"​
 + case 11:
 + carta.valore = "​Q"​
 + case 12:
 + carta.valore = "​K"​
 + }
 +
 + switch n / VALORI {
 + case 0:
 + carta.seme = CUORI
 + case 1:
 + carta.seme = QUADRI
 + case 2:
 + carta.seme = FIORI
 + case 3:
 + carta.seme = PICCHE
 + }
 +
 + return
 +}
 +```
 +
 +### trovare la variabile "​inutilizzata"​
 +
 +```go
 +func main() {
 + var s string
 + var nStringhe int
 + var count [DIM]int
 + arr := [DIM]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
 +
 + for {
 + fmt.Scan(&​s)
 + if s == "​stop"​ {
 + break
 + }
 +
 + temp, ok := contaCifre(s)
 + if !ok {
 + continue
 + }
 +
 + for i, x := range temp {
 + count[i] += x
 + }
 + nStringhe++
 + }
 +
 + fmt.Println(nStringhe,​ "​stringhe con cifre."​)
 + fmt.Println(arr) // per stampare una stringa formattata?​!?​
 + fmt.Println(count)
 +}
 +
 +// poi probabilmente l'​intenzione era di avere una "​stringa"​ da stampare sotto a nStringhe...
 +```
 +
 +### compattare
 +
 +(err è bool)
 +
 +```go
 + if err == true {
 + fmt.Println("​Errore,​ valore non valido. Esecuzione interrotta"​)
 + return
 + }
 +```
 +
 +
 +### lettura specifiche (o problemi implementazione)
 +
 +Era da fare SENZA array di appoggio
 +```go
 +/* scambia il primo con l'​ultimo dei valori in un array
 +di dimensione DIM */
 +func switchFirstLast(originale *[DIM]int) {
 + var ArrayDiAppoggio [DIM]int
 + ArrayDiAppoggio = *originale
 + originale[0] = ArrayDiAppoggio[DIM-1]
 + originale[DIM-1] = ArrayDiAppoggio[0]
 +}
 +
 +```
 +### non scalabile
 +
 +```go
 + var array [DIM]int
 + array[0] = 1
 + array[1] = 2
 + array[2] = 3
 + array[3] = 4
 + array[4] = 5
 + array[5] = 6
 +
 +// meglio usare un for
 +```
 +### ripensarlo?
 +```go
 +func estraiCarta(n int) Carta {
 + var carta Carta
 +
 + if n >= 0 && n <= 12 {
 + carta.seme = "di cuori"
 + } else if n >= 13 && n <= 25 {
 + carta.seme = "di quadri"​
 + } else if n >= 26 && n <= 38 {
 + carta.seme = "di fiori"
 + } else if n >= 39 && n <= 51 {
 + carta.seme = "di picche"​
 + }
 + if n == 0 || n == 13 || n == 26 || n == 39 {
 + carta.valore = "​Asso"​
 + } else if n == 1 || n == 14 || n == 27 || n == 40 {
 + carta.valore = "​Due"​
 + } else if n == 2 || n == 15 || n == 28 || n == 41 {
 + carta.valore = "​Tre"​
 + } else if n == 3 || n == 16 || n == 29 || n == 42 {
 + carta.valore = "​Quattro"​
 + } else if n == 4 || n == 17 || n == 30 || n == 43 {
 + carta.valore = "​Cinque"​
 + } else if n == 5 || n == 18 || n == 31 || n == 44 {
 + carta.valore = "​Sei"​
 + } else if n == 6 || n == 19 || n == 32 || n == 45 {
 + carta.valore = "​Sette"​
 + } else if n == 7 || n == 20 || n == 33 || n == 46 {
 + carta.valore = "​Otto"​
 + } else if n == 8 || n == 21 || n == 34 || n == 47 {
 + carta.valore = "​Nove"​
 + } else if n == 9 || n == 22 || n == 35 || n == 48 {
 + carta.valore = "​Dieci"​
 + } else if n == 10 || n == 23 || n == 36 || n == 49 {
 + carta.valore = "​J"​
 + } else if n == 11 || n == 24 || n == 37 || n == 50 {
 + carta.valore = "​Q"​
 + } else if n == 12 || n == 25 || n == 38 || n == 51 {
 + carta.valore = "​K"​
 + }
 + return carta
 +}
 +
 +```
 +
 +### switchabile ma cmq BASTA UNA SOLA ISTRUZIONE
 +
 +BASTAVA una cosa tipo:​ ```'​ripetizioniNumeri[strInput[i]-'​0'​]++'​ ```(a meno di una conversione)
 +
 +```go
 +    if strInput[i] == '​0'​ {
 +        ripetizioniNumeri[0]++
 +    } else if strInput[i] == '​1'​ {
 +        ripetizioniNumeri[1]++
 +    } else if strInput[i] == '​2'​ {
 +        ripetizioniNumeri[2]++
 +    } else if strInput[i] == '​3'​ {
 +        ripetizioniNumeri[3]++
 +    } else if strInput[i] == '​4'​ {
 +        ripetizioniNumeri[4]++
 +    } else if strInput[i] == '​5'​ {
 +        ripetizioniNumeri[5]++
 +    } else if strInput[i] == '​6'​ {
 +        ripetizioniNumeri[6]++
 +    } else if strInput[i] == '​7'​ {
 +        ripetizioniNumeri[7]++
 +    } else if strInput[i] == '​8'​ {
 +        ripetizioniNumeri[8]++
 +    } else if strInput[i] == '​9'​ {
 +        ripetizioniNumeri[9]++
 +    }
 +```
 +
 +## Note su slice e mappe
 +
 +#### Dichiarazione di una map:
 +
 +sintassi:​ `var map1 map[keytype]valuetype`
 +
 +es: `var map1 map[string]int`
 +
 +#### Allocazione(creazione)/​inizializzazione di una map
 +
 +sintassi:​ `map1 := make(map[keytype]valuetype)`
 +o anche:​ `map1 := map[keytype]valuetype{} // tra {} ci può essere una lista di coppie chiave-valore`
 +
 +es: `map1 := make(map[string]float64)`
 +o anche: `map1 := map[string]float64{}
 + map1 := map[string]float64{"​zero"​ : 0., "​uno"​ : 1.}
 +}`
 +
 +#### Dichiarazione di una slice:
 +
 +sintassi:​ `var slice []type`
 +
 +es: `var slice []int`
 +
 +#### Allocazione(creazione)/​inizializzazione di una slice
 +
 +sintassi:
 +```go
 +slice := make([]type,​ length, capacity)
 +slice := make([]type,​ length) //​la capacità può non essere specificata
 +        ​
 +slice := []type{} // tra {} ci può essere una lista di valori
 +```
 +
 +es:
 +```go
 +slice := make([]int, 0, 5) 
 +slice := []int{}
 +slice := []int{1, 2, 3, 4}
 +```
 +
 +#### Differenza tra ```new``` e ```make```:
 +
 +- ```new(T)``` alloca memoria per un nuovo elemento di tipo T e restituisce il suo indirizzo, quindi un valore di tipo *T (un puntatore)
 +
 +- ```make(T)``` restituisce un valore di tipo T; si applica solo ai tipi riferimento predefiniti:​ slice, mappe (e canali).
 +
 +In altre parole, ```new``` alloca, ```make``` inizializza
 +
 +
 +#### Funzioni built-in per slice
 +(vedi documentazione packages, sotto builtin)
 +
 +- ```func append(slice []Type, elems ...Type) []Type```
 +  es: 
 +    ```go
 + slice = append(slice,​ elem1, elem2)
 + slice = append(slice,​ anotherSlice...)
 +    ```
 +- ```func copy(dest, src []Type) int```
 +
 +## Note generali (slegate dagli esercizi)
 +
 +Non è necessario utilizzare una variabile di appoggio quando dovete scambiare di valore due variabili (*nota: non è possibile farlo in tutti i linguaggi, ma in questo si*)
 +
 +```go
 + a := 1
 + b := 2
 + a, b = b, a  // fantastico!
 +```
 +
 +---
 +
 +I calcoli devono essere fatti dal computer, non da voi. Cercate sempre di trovare un *pattern/​formula* per risolvere i prolemi che si presentano, sopratutto se sono di assegnamento,​ tipo: si deve inizializzare un array di 5 elementi con i valori 0..4 -> usate un for, non inizializzate ogni posizione in modo esplicito
 +
 +Lo stesso discorso vale per lo switch: dove si può compattare, si compatta, senza mai fare calcoli espliciti.
 +
 +---
 +
 +Per stampare le rune:
 +
 +```go 
 +fmt.Printf("​%c",​ <​carattere>​)
 +//oppure
 +fmt.Println(string(<​carattere>​))
 +```
 +
 +---
 +
 +
 +
 +## FAQ
 +
 +### NumToText (svolto insieme)
 +
 +#### mappe - costruzione e uso
 +
 +Scrivere un programma ```num2text.go``` per convertire un numero
 +intero non negativo nella sequenza delle parole corrispondenti
 +alle sue cifre.
 +Il programma legge un intero non negativo da standard input,
 +per ogni nuova (non incontrata finora) cifra del numero
 +chiede il nome corrispondente (e alimenta un dizionario),​ e infine
 +stampa la sequenza delle parole corrispondenti alle sue cifre.
 +Ad esempio, per il numero 203, il programma stampa
 +due - zero - tre
 +
 +#### Esempio di esecuzione
 +
 +```
 +$ go run num2text.go
 +un numero: 622
 +parola per 2 ? due
 +parola per 6 ? sei
 +sei - due - due
 +```
 +
 +```go
 +package main
 +
 +import "​fmt"​
 +
 +func main(){
 +    ​
 +    var m map[int]string
 +    m = make(map[int]string)
 +    ​
 +    var n int
 +    var nome string
 +    fmt.Print("​Inserire un numero intero: ")
 +    fmt.Scan(&​n)
 +    ​
 +    parola := ""​
 +    for n!=0{
 +        cifra:=n%10
 +        //​fmt.Println(cifra)
 +        _,​ok:​=m[cifra] // cerca valore mappato di '​cifra',​ se non lo trova restituisce false
 +        if !ok{
 +            fmt.Printf("​parola per %d? ",​cifra)
 +            fmt.Scan(&​nome)
 +            m[cifra]=nome
 +        }
 +        parola = m[cifra] + " - " + parola
 +        n=n/10
 +    }
 +    ​
 +    fmt.Println(parola[:​len(parola)-3])
 +   // fmt.Println(m)
 +    ​
 +}
 +```
 +
 +### Vocali
 +
 +Nelle mappe, non c'è di norma un ordinamento delle chiavi
 +
 +---
 +
 +Potete implementare una funzione che stampa la mappa, al posto di usare `Print(mappa)`
 +
 +---
 +
 +Per la stampa ordinata: potete usare una stringa di appoggio, sapete già quali sono le vocali e in quale ordine sono
 +
 +### Anagrammi
 +
 +Per "​estrarre"​ una runa da una stringa: chiedetevi come sono "​definite"​ le stringhe..
 +
 +---
 +
 +Linea di comando = parametri del `main`
 +
 +### Galleggianti
 +
 +
 +---
 +
 +### Operazioni_slice
 +
 +---
 +
 +### Appello
 +
 +---
 +
 +### Temperature
 +
 +---
 +
 +### Posizioni_parole
  
pub/labprog/2020-11-26.txt · Last modified: 2020/11/26 17:50 by atrent
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0