Correzione

Per prima cosa osserviamo le soluzioni agli esercizi precedenti.

Ripasso

Nella scorsa lezione ciò che abbiamo capito del linguaggio è che per stampare a video un messaggio occorre utilizzare una costruzione fatta così:

package main
import "fmt"

func main() {
	fmt.Println(<messaggio>)
	return
}

In realtà ciò che si occupa di stampare il messaggio è soltanto la riga

fmt.Println(<messaggio>)

tutto il resto è una construzione che si ripeterà sempre uguale nei nostri programmi e che serve a "far partire" il programma nel modo giusto.

Le variabili

In go ciascun dato che vogliamo utilizzare va racchiuso in un contenitore, detto variabile. Ogni variabile ha un tipo (ovviamente se voglio rappresentare un numero ho bisogno di un contenitore di un certo tipo, se voglio rappresentare una parola di un altro). Inizialmente ci occuperemo soltanto di numeri perchè i contenitori per le stringhe sono un pochino più complicati.

Dichiarare variabili

La parola chiave di Go per dichiarare una variabile è var, la sintassi è questa:

var nome tipo

Per dichiarare una variabile occorre darle un nome, in questo caso n; ogni volta che nel programma ci si riferisce ad n si sta parlando del valore che sta nel 'contenitore' di nome n. Per mettere un valore dentro n si usa l'operatore =. Ad esempio il seguente programma dichiara una variabile di tipo intero n, mette 10 dentro ne poi stampa il contenuto della variabile.

package main
import "fmt"

func main() {
	var n int
	n = 10
	fmt.Println(n)
	return
}

Tipi di variabili

Esistono diversi tipi di variabili definiti da Go: int, int64, uint,... Noi inizialmente ci occuperemo principalmente di 3 tipi: int, float64, bool; utili per rappresentare, rispettivamente, numeri interi, numeri decimali e valori di verità (true oppure false).

package main
import "fmt"

func main() {
	var n float64
	n = 1.10
	fmt.Println(n)
	return
}

Nota: dichiarazioni multiple

In una sola riga posso dichiarare più variabili dello stesso tipo, la sintassi è:

var nome1, nome2 tipo

Nota: omogeneità

In Go ogni espressione può contenere solo variabili dello stesso tipo: per esempio non posso sommare un intero ed un numero decimale. Lo stesso programma di prima, ma dichiarando le due variabili come intero e come float64 dà un errore.

package main
import "fmt"

func main() {
	var n int
	var m float64
	n = 10
	m = 20.0
	fmt.Println(n + m) // ERRORE
	return
}

Nota: variabili inizializzate

Molto spesso risulta utile dare valori iniziali alle variabili, per farlo occorre utilizzare l'operatore ':=' tra il nome della variabile ed il valore con cui la si vuole inizializzare. Go cercherà di capire il tipo della variabile e assegnerà il valore.

package main
import "fmt"

func main() {
	primo := 20
	fmt.Println(primo)
	return
}

Nota: identificatore blank

A volte occorre ignorare alcuni valori, poichè non vale la pena di salvarli in una variabile oppure perchè non verranno mai usati nel resto del programma. Per fare questa cosa, al posto del nome della variabile occorre mettere il simbolo _

package main
import "fmt"

func main() {
	_, n := 10, 20
	fmt.Println(n)
	return
}

Lettura da tastiera

L'argomento di oggi è la lettura di dati dall'utente, tutte le interazioni avvengono attraverso il terminale, quindi anche la lettura di valori avviene quando l'utente scrive qualcosa nel terminale. Leggere valori da tastiera nello specifico significa salvare l'input dell'utente in una variabile che abbia il tipo adatto. Se ci aspettiamo che l'utente inserisca un numero intero, prepariamo una variabile di tipo int, se ci aspettiamo che l'utente inserisca un numero con la virgola una variabile di tipo float64. Vedremo successivamente come controllare che l'utente abbia inserito un valore del tipo corretto, per ora diamo per scontato che sia così.

Per leggere valori dall'utente occorre utilizzare un costrutto molto simile a quello che utilizzavamo per scrivere in output, ad esempio un programma che legge da tastiera un numero intero e conserva il valore letto in una variabile è fatto così:

package main
import "fmt"

func main() {
	var numero int
	fmt.Scan(&numero)
	return
}

Alla fine del programma nella variabile numero sarà conservato il valore inserito dall'utente. Per inserire il valore letto all'interno di una variabile occorre quindi utilizzare un costrutto che ha la forma:

fmt.Scan(&<nome variabile>)

Nota utile per gli esercizi

L'operazione di divisione è definita in modo diverso per interi e per numeri decimali: su valori di tipo int l'operazione è quella della divisione intera: il risultato è un numero intero, eventualmente si può calcolare il resto con l'operazione % (detta modulo); su valori di tipo float64 l'operazione è quella usuale.

Esercizi

Esercizio 0 - Conversione da secondi in minuti

Problema: Scrivere un programma Go secondi_minuti.go che, preso in input un valore intero rappresentante una quantità in secondi, stampi in output il corrispondente valore in minuti.

Esempio di esecuzione:

Numero di secondi: 120

Numero di minuti: 2

Soluzione

package main

import "fmt"

func main() {
	var secondi int
	fmt.Println("Numero di secondi: ")
	fmt.Scan(&secondi)
	fmt.Println("Numero di minuti: ", secondi/60)
	return
}

Esercizio 1 - Conversione da ore in giorni

Problema: Scrivere un programma Go minuti_ore.go che, preso in input un valore intero rappresentante una quantità in ore, stampi in output il corrispondente valore in giorni.

Esempio di esecuzione

Numero di ore: 48

Numero di giorni: 2

Soluzione

package main

import "fmt"

func main() {
	var ore int
	fmt.Println("Numero di ore:")
	fmt.Scan(&ore)
	fmt.Println("Numero di giorni: ", ore/24)
	return
}

Esercizio 2 - Consumo medio e resa di un motore

Problema: Scrivere un programma Go consumo_resa.go che calcola il consumo medio e la resa di un motore date la distanza totale percorsa (in km) e la quantità di carburante utilizzata (in litri). I valori in input sono di tipo float64.

Nota: Il consumo medio di carburante si esprime in l/km ed è la quantità di carburante che occorre in media per percorrere un km di strada. La resa di un motore è data dalla distanza percorsa in media con un litro di carburante e si esprime con km/l.

Esempio di esecuzione:

Distanza percorsa (in km): 50

Quantità di carburante utilizzata (in l): 10

Consumo medio: 0.2 l/km

Resa media: 5 km/l

Soluzione

package main

import "fmt"

func main() {
	var distanza, carburante float64
	fmt.Println("Distanza percorsa (in km): ")
	fmt.Scan(&distanza)
	fmt.Println("Quantità di carburante utilizzata (in l): ")
	fmt.Scan(&carburante)

	fmt.Println("Consumo medio: ", carburante/distanza, "km/l")
	fmt.Println("Resa media: ", distanza/carburante, "l/km")
}

Esercizio 3 - Media di due voti

Problema: Scrivere un programma Go media_due_voti.go che, letti due voti (di tipo float64), ne calcola la media.

Esempio di esecuzione:

Primo voto: 6

Secondo voto: 7

Media: 6.5

Soluzione

package main

import "fmt"

func main() {
	var primoVoto, secondoVoto float64

	fmt.Println("Primo voto: ")
	fmt.Scan(&primoVoto)

	fmt.Println("Secondo voto: ")
	fmt.Scan(&secondoVoto)

	fmt.Println("Media: ", (primoVoto+secondoVoto)/2)
	return
}

Esercizio 4 - Velocità

Problema: Scrivere un programma Go velocita.go che calcola la velocità media su un tratto di strada, dopo aver letto in input la lunghezza del tratto (in km) e il tempo trascorso nel percorrerlo (in ore). I valori letto sono di tipo float64.

Nota: La velocità media si esprime in km/h e si calcola dividendo la lunghezza dell tratto percorso per il tempo necessario a percorrerlo

Bonus: Utilizzando i risultati di conversione degli esercizi precedenti, come ricavereste la velocità in m/s.

Esempio di esecuzione:

Lunghezza del percorso (in km): 72

Tempo trascorso (in h): 2

Velocità media: 36 km/h

Velocità media: 10 m/s

Soluzione

package main

import "fmt"

func main() {
	const SECONDI_IN_ORE = 3600 // 60 * 60
	const METRI_IN_CHILOMETRO = 1000

	var chilometri, ore float64

	fmt.Println("Lunghezza del percorso (in km): ")
	fmt.Scan(&chilometri)

	fmt.Println("Tempo trascorso (in h): ")
	fmt.Scan(&ore)

	fmt.Println("Velocità media: ", chilometri/ore, "km/h")

	secondi := ore * SECONDI_IN_ORE
	metri := chilometri * METRI_IN_CHILOMETRO
	fmt.Println("Velocità media: ", metri/secondi, "m/s")

	return
}

Esercizio 5 - Conversione da secondi a giorni, ore, minuti

Problema: Scrivere un programma Go secondi_giorni.go che, preso in input un valore intero rappresentante una quantità in secondi, stampi in output il corrispondente valore in giorni, ore, minuti, secondi.

Bonus: Provate a farlo senza usare mai l'operazione di sottrazione.

Esempio di esecuzione:

Numero di secondi: 123456

g:h:m:s = 1:10:17:36

Soluzione

package main

import "fmt"

func main() {
	const ORE_IN_GIORNI = 24
	const MINUTI_IN_ORE = 60
	const SECONDI_IN_MINUTO = 60

	var secondiTotali int

	fmt.Println("Numero di secondi:")
	fmt.Scan(&secondiTotali)

	secondi_in_ore := MINUTI_IN_ORE * SECONDI_IN_MINUTO
	secondi_in_giorni := ORE_IN_GIORNI * secondi_in_ore

	giorni := secondiTotali / secondi_in_giorni
	resto := secondiTotali % secondi_in_giorni

	ore := resto / secondi_in_ore
	resto = resto % secondi_in_ore

	minuti := resto / SECONDI_IN_MINUTO
	secondi := resto % SECONDI_IN_MINUTO

	fmt.Println("g:h:m:s -", giorni, ":", ore, ":", minuti, ":", secondi)
	return
}