Created: 2021-12-25 sab 02:06
L'informatica è un campo di studio estremamente vasto, che ogni anno continua a crescere di ampiezza, profondità e portata.
È difficile oramai pensare ad un contesto che non sia stato minimamente cambiato dai continui sviluppi dell'informatica.
Dai primi mainframes degli anni 50 (TX-0), oramai la maggior parte di noi porta con sé uno smartphone in tasca.
TX-0 mainframe (1960s @ MIT)
\[\longrightarrow\]
Smartphones moderni
Col progredire dell'influenza che l'informatica ha nella quotidianità delle nostre vite, diventa sempre più importante lo sviluppo di conoscenze informatiche basate su delle solide fondamenta.
Ad esempio, avere una conoscenza basilare di come funziona internet è fondamentale per iniziare a sviluppare dei comportamenti più sicuri e tutelare al meglio i nostri dati critici.
Nel suo continuo progresso, l'informatica ha anche influenzato sé stessa, rendendo sempre più facile lo sviluppo di prodotti e servizi digitali tramite varie tecnologie, come ad esempio i frameworks javascript per sviluppare Web-Apps.
ReactJS (by Facebook)
AngularJS (by Google)
VueJS (community-based)
Oppure l'utilizzo di CMS (Content-Management-System) come WordPress per gestire blogs e siti online.
Source: wordpress
Bisogna però stare attenti.
Imparare il più popolare framework javascript per sviluppare una web app infatti non è la stessa cosa che conoscere le più importanti tecnologie che stanno dietro al funzionamento di internet.
L'obiettivo finale di un informatico non si dovrebbe limitare allo sviluppo di applicazioni commerciali.
Piuttosto, un informatico si deve concentrare nel cercare di capire cosa sta succedendo in profondità, dietro tutte le astrazioni e semplificazioni.
Questo è chiaramente un obiettivo ideale, in quanto il più delle volte è estremamente difficile capire esattamente cosa sta succedendo in un sistema, sia a livello software che a livello hardware.
L'importante, comunque, è avere sempre in mente quell'obiettivo di comprensione totale.
L'importante è cercare di capire, modellare e spiegare al limite delle nostre capacità, ciò che sta succedendo in ogni dato momento nel particolare sistema che stiamo analizzando.
Per quanto complessi possano sembrare i moderni sistemi digitali infatti, questa tipologia di sistemi hanno una preziosa caratteristica:
possono essere ridotti alla somma delle loro parti
Se ci si concentra sulle singole parti, che per costruzione sono più semplici da capire, e se si analizza come queste parti sono combinate tra loro, si ha la vera speranza di capire anche il funzionamento del tutto.
Al fine di raggiungere questo obiettivo diventa necessario sviluppare una serie di strumenti e conoscenze più approfondite.
Per iniziare questo percorso ci possiamo chiedere:
Come possiamo caratterizzare la conoscenza studiata e avanzata dall'informatica?
Per cercare di capire la natura della conoscenza studiata dall'informatica consideriamo un particolare problema.
Per iniziare, ricordiamo la definizione matematica di radice quadrata.
Definizione: Diciamo che \(y\) è la radice quadrata di \(x\) se e solo se vale la seguente equazione
\[y^2 = x\]
In questi casi indichiamo con il simbolo \(\sqrt{x}\) la radice quadrata di \(x\).
\[y = \sqrt{x} \overset{\; \Delta}{\iff} y^2 = x\]
Ripassiamo alcuni ben noti valori di radici quadrate.
\[\begin{array}{c | c | c} x & \sqrt{x} & \text{(spiegazione)}\\ \hline 1 & \pm 1 & 1^2 = 1, \;\; (-1)^2 = 1 \\ 4 & \pm 2 & 2^2 = 4, \;\; (-2)^2 = 4 \\ 9 & \pm 3 & 3^2 = 9, \;\; (-3)^2 = 9 \\ 16 & \pm 4 & 4^2 = 16, \;\; (-4)^2 = 16 \\ \end{array}\]
Consideriamo adesso un particolare valore per \(x\).
Diciamo \(x = 5\).
Con la definizione appena data sappiamo che:
\(7\) non è la radice quadrata di \(5\). Infatti,
\[y^2 = 7^2 = 7 \cdot 7 = 49 \neq 5 = x \implies 7 \neq \sqrt{5}\]
\(3\) non è la radice quadrata di \(5\). Infatti,
\[y^2 = 3^2 = 3 \cdot 3 = 9 \neq 5 = x \implies 3 \neq \sqrt{5}\]
Utilizando solamente la definizione di radice quadrata non siamo in grado di calcolare direttamente il valore di \(\sqrt{x}\). Possiamo solo escludere i numeri che non sono la radice quadrata di \(x\).
Questo tipo di conoscenza ci sta dicendo solamente cosa vuol dire essere la radice quadrata di \(x\), ma non come calcolare tale radice. Per questa regione questa tipologia di conoscenza è nota come
conoscenza dichiarativa
Se vogliamo capire effettivamente come calcolare \(\sqrt{x}\) una volta fissato \(x\), non ci basta la conoscenza dichiarativa. Abbiamo bisogno di un nuovo tipo di conoscenza, detta
conoscenza procedurale
A differenza di quella dichiarativa, la conoscenza procedurale ci dice esattamente come calcolare ciò che ci interessa.
Nel nostro caso particolare, dato che siamo interessati al calcolo delle radici quadrate, la conoscenza procedurale che stiamo cercando ci dovrebbe dire esattamente come calcolare tali radici.
In altre parole, vogliamo trovare un metodo automatico (o algoritmo) per passare da un dato numero alla sua radice quadrata
\[5 \longrightarrow \sqrt{5} \approx 2.2360679775\]
Un algoritmo molto famoso per il calcolo delle radici quadrate è chiamato Metodo di Netwon.
Il Metodo di Netwon funziona così (1/2):
Lo step (2) viene ripetuto fino a quando si raggiunge un determinato criterio di terminazione.
Il Metodo di Netwon funziona così (2/2):
Tra i possibili criteri di terminazione troviamo anche i seguenti due:
La differenza dei valori calcolati tra due iterazioni successive è "abbastanza piccola".
\[|g_{i+1} - g_i| < \epsilon\]
La differenza tra \(g^2\) e \(x\) è "abbastanza piccola".
\[|g^2 - x| < \epsilon\]
Esempio #1: Sia \(x=5\)
\[\begin{split} g_1 &= 1 \\ \end{split}\]
Esempio #1: Sia \(x=5\)
\[\begin{split} g_1 &= 1 \\ \\ g_2 &= \frac{(g_1 + (\frac{5}{g_1}))}{2} = \frac{(1 + (\frac{5}{1}))}{2} = 3 \\ \end{split}\]
Esempio #1: Sia \(x=5\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 3 \\ \\ g_3 &= \frac{(g_2 + (\frac{5}{g_2}))}{2} = \frac{(3 + (\frac{5}{3}))}{2} = 2.3333 \\ \end{split}\]
Esempio #1: Sia \(x=5\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 3, \;\;\; g_3 = 2.3333 \\ \\ g_4 &= \frac{(g_3 + (\frac{5}{g_3}))}{2} = \frac{(2.3333 + (\frac{5}{2.3333}))}{2} = 2.2381 \\ \end{split}\]
Esempio #1: Sia \(x=5\)
Notiamo che
\[\sqrt{5} \approx 2.2360679775\]
mentre il valore calcolato alla terza iterazione è
\[g_4 = 2.2381\]
In sole \(4\) iterazioni ci siamo avvicinati abbastanza all'effettivo valore.
\[|g_4 - \sqrt{5}| = 0.0020320225\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1 \\ \\ g_2 &= \frac{(g_1 + (\frac{42}{g_1}))}{2} = \frac{(1 + (\frac{42}{1}))}{2} = 21.5 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 21.5 \\ \\ g_3 &= \frac{(g_2 + (\frac{42}{g_2}))}{2} = \frac{(21.5 + (\frac{42}{21.5}))}{2} = 11.7267 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 3, \;\;\; g_3 = 11.7267 \\ \\ g_4 &= \frac{(g_3 + (\frac{42}{g_3}))}{2} = \frac{(11.7267 + (\frac{42}{11.7267}))}{2} = 7.6541 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 3, \;\;\; g_3 = 11.7267, \;\;\; g_4 = 7.6541 \\ \\ g_5 &= \frac{(g_4 + (\frac{42}{g_4}))}{2} = \frac{(7.6541 + (\frac{42}{7.6541}))}{2} = 6.5706 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
\[\begin{split} g_1 &= 1, \;\;\; g_2 = 3, \;\;\; g_3 = 11.7267, \;\;\; g_4 = 7.6541, \;\;\; \\ g_5 &= 6.5706 \\ \\ g_6 &= \frac{(g_5 + (\frac{42}{g_5}))}{2} = \frac{(6.5706 + (\frac{42}{6.5706}))}{2} = 6.4813 \\ \end{split}\]
Esempio #2: Sia \(x=42\)
Dopo \(6\) iterazioni…
\[g_6 = 6.4813\]
mentre il valore richiesto è
\[\sqrt{42} \approx 6.4807\]
dunque,
\[|g_6 - \sqrt{42}| = |6.4813 - 6.4807| = 0.0006\]
Il metodo di Netwon è un chiaro esempio di algoritmo, in quanto descrive una ricetta per risolvere un problema computazionale, ovvero un problema di calcolo.
La descrizione di un algoritmo è un esempio di conoscenza procedurale, in quanto sta descrivendo la procedura per effettuare un calcolo.
Per calcolare la radice quadrata di x: Sia g = 1 Sia precision = 0.001 Ripeti fino a quando |g^2 - x| < precision: g = (g + x/g)/2 Esci e ritorna g
L'informatica studia esattamente questo tipo di conoscenza.
Per quanto la comprensione e l'analisi teorica degli algoritmi è una parte fondamentale dell'informatica, un informatico deve anche essere in grado di implementare gli algoritmi studiati in modo da poterli eseguire su dei computer reali.
A differenza di noi esseri umani infatti i computers sono molto bravi a fare i calcoli velocemente.
Possiamo dunque lasciare a loro l'arduo compito di calcolare; a noi umani basta solamente capire il funzionamento dell'algoritmo una volta.
L'implementazione di un algoritmo (teorico) in un programma (reale) avviene tramite l'utilizzo dei linguaggi di programmazione.
Sono tanti e vari i linguaggi di programmazione che un informatico può utilizzare.
Nei prossimi video discuteremo meglio che cosa sono i linguaggi di programmazione, andando a vedere come poter implementare il metodo di Netwon in tre diversi linguaggi di programmazione:
Python3
print("Hello World!")
C
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World!");
return 0;
}
Emacs-Lisp
(message "Hello World!")