User Tools

Site Tools


pub:labprog:2020-11-26

# 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