esercizi 5 dicembre

parent 00fb563c
# Esercizi 05 dicembre 2019
## Note prima degli esercizi
- Caricarli su https://upload.di.unimi.it
- Molte volte nel testo dell'esercizio si specificano dei vincoli sull'input. Occorre verificarne sempre la veridicità. Nel caso in cui l'input inserito non rispetti il vincolo, stampare un messaggio di errore e chiederne il reinserimento, fino a quando non viene fornito un input valido. Ad esempio, se il programma *pippo.go* attende in input un numero pari, un possibile scenario potrebbe essere il seguente:
```console
$./pippo
Inserire un numero n pari:
3
Numero non valido
Inserire un numero n pari:
5
Numero non valido
Inserire un numero n pari:
2
```
- Se non vengono specificati vincoli sull'input, si può assumere che sia privo di errori
- Evitare di inserire stampe non richieste
- Ricordatevi di usare sempre `gofmt` per formattare correttamente il file
- Se un esercizio vi sembra troppo difficile da risolvere al primo colpo, provate a "scomporlo" in sottoproblemi più semplici e a risolverlo per passi
## Esercizio 1 (``occorrenze.go``)
Scrivere programma che prende parametro \<nomefile\> a linea di comando e poi conta le occorrenze delle parole (distinguendo maiuscole e minuscole) nel file indicato.
### Esempio di esecuzione
```shell
$ ./occorrenze testo.txt
ciao: 1
a: 1
tutti: 1
```
(dove il file contiene solo la riga "ciao a tutti")
*Nota*: per dichiarare una mappa usare ```make(map[String]int)``` (in poche parole, state dichiarando una mappatura da stringhe a interi).
*Nota*: per riempire una mappa usare ```m[<chiave>] = <valore>``` dove ```m``` è il nome che abbiamo assegnato alla mappa.
*Nota*: per la stampa si può utilizzare un ```for range```
### Soluzione 1
```go
package main
import (
"fmt"
"bufio"
"os"
)
func main() {
var m map[string]uint
m=make(map[string]uint)
s,_:=os.Open(os.Args[1])
t:=bufio.NewScanner(s)
t.Split(bufio.ScanWords)
for t.Scan() {
m[t.Text()]++
}
for word,occurrence:=range m {
fmt.Println(word,":",occurrence)
}
}
```
### Soluzione 2
```go
package main
import (
"bufio"
"fmt"
"os" )
func agg(x map[string]int,s string) {
i:=x[s]
x[s]=i+1
}
func main() {
m := make(map[string]int)
var NF string
fmt.Println("inserisci nome del file")
fmt.Scan(&NF)
f, err := os.Open(NF)
if err != nil {
fmt.Printf("error opening file: %v\n",err)
os.Exit(1)
}
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
s:= scanner.Text()
agg(m,s)
}
for j,i:=range m{
fmt.Print(j,":")
for z:=0;z<15-len(j);z++{
fmt.Print(" ")
}
fmt.Println(i)
}
}
```
## Esercizio 2 (countdown.go)
Scrivere un programma che prende due parametri numerici a linea di comando, il primo è un numero di secondi il secondo è la lunghezza della barra da disegnare.
Il programma deve fare un conteggio alla rovescia sul numer di secondi, disegnando una barra che inizialmente è lunga 0 caratteri e man mano si "riempie" fino a raggiungere la lunghezza massima passata.
### Esempio
```shell
$ ./countdown 60 50
(1.2 arrotondato al + vicino):|
(2.4 arrotondato al + vicino):||
(3.6 arrotondato al + vicino):|||
...
```
(50 tacche in 60 secondi)
```shell
$ ./countdown 120 20
6:|
12:||
18:|||
...
```
(20 tacche in 120 secondi)
*Nota*: Per far "aspettare" un certo numero di secondi, utilizzare la funzione ```time.Sleep()```. Per maggiorni informazioni: https://golang.org/pkg/time/#Sleep
Facciamo un esempio. Proviamo ad eseguire una ```Sleep``` che dura 5 secondi. Avete due modi per far funzionarlo:
- ```go
fmt.Println("inizio")
n := 5 //è un intero
time.Sleep(time.Duration(n) * time.Second)
fmt.Println("fine") ```
- ```go
fmt.Println("inizio")
n,_ := time.ParseDuration("5s")
/*NOTA BENE: gli stiamo passando la stringa "5s", 5 non
sarebbe andato bene. LEGGETE SEMPRE LA DOCUMENTAZIONE */
time.Sleep(n * time.Second)
fmt.Println("fine")
```
Per la ParseDuration: https://golang.org/search?q=ParseDuration.
### Soluzione parziale
```go
package main
import (
"fmt"
"os"
"strconv"
"time"
"time.Duration" as Pippo // controllare sintassi (questa è circa python)
)
func main() {
//var timer, barra int
//timer, errt := strconv.Atoi(os.Args[1])
//
//
//
//
//fmt.Println(errt);
var t time.Duration
barra, errb := strconv.Atoi(os.Args[2])
fmt.Println(errb);
delay, errd := time.ParseDuration(os.Args[3])
fmt.Println(errd);
//fmt.Println(timer);
for i := 0; i < barra; i++ {
fmt.Print("@")
time.Sleep(delay)
}
}
```
### Soluzione 2
```go
package main
import "fmt"
import "time"
import "os"
import "strconv"
func main() {
sec,_ := strconv.Atoi(os.Args[1])
num,_ := strconv.Atoi(os.Args[2])
padding := len(os.Args[1])+2
aspetto := float64(sec)/float64(num)
aspettoDuration,_ := time.ParseDuration(fmt.Sprintf("%f", aspetto)+"s")
for i:=1;i<num+1;i++{
time.Sleep(aspettoDuration)
for k:=0; k<=padding-len(fmt.Sprintf("%.1f,",float64(i)*aspetto));k++{
fmt.Print(" ")
}
fmt.Printf("%.1f,",float64(i)*aspetto)
for j:=0;j<i;j++ {
fmt.Print("|")
}
fmt.Println()
}
}
```
## Continuo di ``tartaruga.go``
Riprendete l'esercizio ``tartaruga.go`` della scorsa lezione e modificate il programma in modo che venga evidenziata nella stampa il percorso seguito dalla tartaruga stessa. Riflettete bene su come modificare metodi / strutture dati utilizzate. In particolare, chiedetevi **dove** memorizzare il percorso seguito.
*Suggerimento*: utilizzate matrici / array bidimensionali ``mappa := [][]string``
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment