esercizi 2019-11-21

parent 133dd932
# Esercizi 21 novembre 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
## Esercizio 1 (struttura.go)
Riempire un array (max 50 elementi) di "persona" a partire da un file.
```
type persona struct{
nome string
cognome string
sesso string
età int
}
```
Esempio di file:
```
Mario Rossi M 34
Giovanni Bianchi M 67
Etelgunda Rosi F 56
```
*Suggerimento*: si potrebbe affrontare l'esercizio per gradi, ad esempio si potrebbe iniziare a implementare una soluzione che legge da da riga di comando oppure che legge da un file contentente un'unica riga
*Suggerimento*: per aprire file usare `file, _ := os.Open("dati.txt")`
### Soluzione 1
```
package main
import (
"fmt"
)
type persona struct {
nome string
cognome string
sesso string
età int
}
func main() {
var x [5]persona
for i := 0; i < len(x); i++ {
fmt.Scan(&x[i].nome)
fmt.Scan(&x[i].cognome)
fmt.Scan(&x[i].sesso)
fmt.Scan(&x[i].età)
}
// lo uso per controllare cosa mi mette negli array
for i := 0; i < len(x); i++ {
fmt.Println(x[i])
}
}
```
In questa soluzione si può eseguire il programma nel seguente modo:
```console
$ echo mario rossi M 67 maria lamberti F 34 | ./struttura
{mario rossi M 67}
{maria lamberti F 34}
{ 0}
{ 0}
{ 0}
```
Notare che le `persona` non inizializzate mostrano i valori di default (per le stringhe viene mostrata la stringa vuota e per gli int il numero zero)
### Soluzione 2 (NON funziona!)
```
package main
import (
"fmt"
"os"
"bufio"
"strings"
"unicode"
)
type ID struct{
name string
surname string
gender string
age int
}
func main() {
var struttura [50]ID
s:=bufio.NewScanner(os.Stdin)
n:=1
for s.Scan(){
p:=new(ID)
line:=s.Text()
*p=strings.Split(line,unicode.IsSpace) // errore QUI
struttura[n-1]=*p
n++
}
fmt.Println(struttura)
}
```
### Soluzione 3
```
package main
import "fmt"
import "bufio"
import "os"
import "strings"
import "strconv"
type persona struct {
nome string
cognome string
sesso string
eta int
}
func main() {
var line string
var t persona
var x []persona
fileHandle, _ := os.Open("file.txt")
scanner := bufio.NewScanner(fileHandle)
for scanner.Scan() {
line = scanner.Text()
y := strings.Fields(line)
t.nome = y[0]
t.cognome = y[1]
t.sesso = y[2]
t.eta, _ = strconv.Atoi(y[3])
x = append(x, t)
}
for i := 0; i < len(x); i++ {
fmt.Println(x[i])
}
fileHandle.Close()
}
```
### Soluzione 4
```
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
type persona struct {
nome string
cognome string
sesso string
eta int
}
func main() {
var persone []persona
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
for scanner.Scan() {
var p persona
p.nome = scanner.Text()
scanner.Scan()
p.cognome = scanner.Text()
scanner.Scan()
p.sesso = scanner.Text()
scanner.Scan()
p.eta, _ = strconv.Atoi(scanner.Text())
persone = append(persone, p)
}
fmt.Println("--------------------------------------------------------")
for j := 0; j < len(persone); j++ {
fmt.Println(persone[j].nome, persone[j].cognome, persone[j].sesso, persone[j].eta)
}
}
```
## Esercizio 2 (strutturaStat.go)
Sulla base dell'esercizio precedente, dopo aver riempito la struttura stampare l'item con l'età maggiore e quello con la minore.
### Soluzione 1
```
package main
import "fmt"
import "bufio"
import "os"
import "strings"
import "strconv"
type persona struct {
nome string
cognome string
sesso string
eta int
}
func estremi (x *[]persona, max *persona, min *persona){
*max = (*x)[0]
*min = (*x)[0]
for i:=1;i<len((*x));i++{
if (*x)[i].eta < (*min).eta {
*min = (*x)[i]
} else if (*x)[i].eta > (*max).eta {
*max = (*x)[i]
}
}
return
}
func main() {
var line string
var t persona
var x []persona
var max,min persona
fileHandle, _ := os.Open("file.txt")
scanner := bufio.NewScanner(fileHandle)
for scanner.Scan() {
line = scanner.Text()
y := strings.Fields(line)
t.nome = y[0]
t.cognome = y[1]
t.sesso = y[2]
t.eta, _ = strconv.Atoi(y[3])
x = append(x, t)
}
estremi(&x,&max,&min)
fmt.Println("piu' vecchio: ",max)
fmt.Println("piu' giovane: ",min)
fileHandle.Close()
}
```
## Esercizio 3 (strutturaStat2.go)
Sulla base dell'esercizio precedente aggiungere anche calcolo media e deviazione standard delle età, numero di maschi/femmine, lunghezza media dei cognomi.
### Soluzione 1
```
package main
import "fmt"
import "bufio"
import "os"
import "strings"
import "strconv"
import "math"
type persona struct {
nome string
cognome string
sesso string
eta int
}
func num (y []persona) (media float64,dev float64, numM int,numF int,mediaCognomi float64) {
var t,s int
var scarto float64
var L float64
L = float64(len(y))
for i:=0;i<len(y);i++ {
t+=y[i].eta
s+=len(y[i].cognome)
if y[i].sesso == "M" {
numM++
} else {
numF++
}
}
media = float64(t) / L
mediaCognomi = float64(s) / L
for i:=0;i<len(y);i++ {
scarto += (media-float64(y[i].eta))*(media-float64(y[i].eta))
}
dev = math.Sqrt(scarto/L)
return
}
func main() {
var line string
var t persona
var x []persona
fileHandle, _ := os.Open("file.txt")
scanner := bufio.NewScanner(fileHandle)
for scanner.Scan() {
line = scanner.Text()
y := strings.Fields(line)
t.nome = y[0]
t.cognome = y[1]
t.sesso = y[2]
t.eta, _ = strconv.Atoi(y[3])
x = append(x, t)
}
for i := 0; i < len(x); i++ {
fmt.Println(x[i])
}
fileHandle.Close()
media,dev,numM,numF,mediaCognomi := num(x)
fmt.Println(media,dev,numM,numF,mediaCognomi)
}
```
## Esercizio 4 (remake.go)
Prendere ultimo esercizio e sostituire (ove possibile) i for "normali" con dei "for range"
------
## "Arrotarsi" sui puntatori
### Versione "arrotata"
```
package main
import (
"fmt"
"os"
"bufio"
"strings"
"strconv"
)
type persona struct{
name string
surname string
gender string
age int
}
// esistono i valori di ritorno di una funzione ;)
func assign (p **persona, s []string){
var pers persona
pers.name=s[0]
pers.surname=s[1]
pers.gender=s[2]
pers.age,_=strconv.Atoi(s[3])
*p=&pers
}
func main() {
var struttura [50]persona
var p *persona
n:=0
s:=bufio.NewScanner(os.Stdin)
for s.Scan(){
line:=strings.Split(s.Text()," ")
assign(&p,line)
struttura[n]=*p
n++
}
fmt.Println(struttura)
}
```
### Versione "sanitized"
```
package main
import (
"fmt"
"os"
"bufio"
"strings"
"strconv"
)
type persona struct{
name string
surname string
gender string
age int
}
func assign (s []string)persona{
var pers persona
pers.name=s[0]
pers.surname=s[1]
pers.gender=s[2]
pers.age,_=strconv.Atoi(s[3])
return pers
}
func main() {
var struttura [50]persona
var p persona
n:=0
s:=bufio.NewScanner(os.Stdin)
for s.Scan(){
line:=strings.Split(s.Text()," ")
p=assign(line)
struttura[n]=p
n++
}
fmt.Println(struttura)
}
```
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type Persona struct {
nome string
cognome string
sesso string
età int
}
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