In matematica, il coefficiente binomiale è un numero intero non negativo definito dalla seguente formula:
Questo numero è dimostrato corrispondere alle combinazioni semplici di n elementi di classe k, che equivale a dire il numero di sottoinsiemi di k elementi estratti da un insieme di n elementi (non considerando rilevante l’ordine degli insiemi).
Le combinazioni sono parte del calcolo combinatorio, una branda della matematica che studia i modi per raggruppare e/o ordinare secondo date regole gli elementi di un insieme finito di oggetti. Esistono 3 principali categorie di raggrupamento, ognuna delle quali può essere considerata con o senza ripetizioni (ovvero permettendo o meno l’estrazione di uno stesso elemento di un insieme più di una volta). Si possono distinguere infatti:
Permutazioni:
semplici (senza ripetizioni)
con ripetizioni
Disposizioni:
semplici (senza ripetizioni)
con ripetizioni
Combinazioni:
semplici (senza ripetizioni)
con ripetizioni
Una permutazione di un insieme di oggetti è una presentazione ordinata, cioè una sequenza, dei suoi elementi nella quale ogni oggetto viene presentato una ed una sola volta. Nel caso in cui gli n elementi dell’insieme siano tutti diversi, si parla di permutazioni semplici e si calcolano con la formula:
Se invece l’insieme contiene delle ripetizioni, occorre utilizzare la formula per le permutazioni con ripetizione, poiché alcuni insiemi risulteranno uguali tra loro. Indicando con il numero di volte che si ripetono r elementi dell’insieme, la formula delle permutazioni sarà la seguente:
Una disposizione semplice di k elementi da un insieme di n è una collezione ordinata nella quale non si può avere la ripetizione di uno stesso oggetto e si calcola con la seguente formula:
Nel caso in cui invece fosse possibile avere le ripetizioni di uno stesso oggetto, allora bisognerà utilizzare la formula delle disposizioni con ripetizione:
Infine, le combinazioni semplici, come già detto, rappresentano il numero di sottoinsiemi non ordinati di k elementi estratti da un insieme di n elementi. La formula può essere ricavata attraverso le permutazioni e le disposizioni e, come si vedrà, coincide esattamente con il coefficiente binomiale. Infatti le combinazioni semplici possono essere viste come il numero di insiemi ordinati di k elementi che si possono ottenere da un insieme di n diviso il numero di permutazione di ogni sottoinsieme, ovvero attraverso il rapporto tra e :
Una delle proprietà principali del coefficiente binomiale è che permette di ricavare i coefficienti che precedono i termini ottenuti dallo sviluppo di un binomio di potenza p, permettendo di sviluppare il “Triangolo di Tartaglia”, ovvero una sorta di piramide dei coefficienti associati ad ogni esponente.
p = 0 1 p = 1 1 1 p = 2 1 2 1 p = 3 1 3 3 1 p = 4 1 4 6 4 1 p = 5 1 5 10 10 5 1 p = 6 1 6 15 20 15 6 1 p = 7 1 7 21 35 35 21 7 1
Il coefficiente binomiale presenta inoltre diverse proprietà molto utili. La prima riguarda la simmetria del coefficiente binomiale. Infatti:
Questa proprietà è vera poichè:
Inoltre, dato che 0! = 1 per definizione, è vera anche le seguente proprietà:
Questa proprietà è vera poichè:
Esistono anche delle proprietà che permettono il calcolo ricorsivo del coefficiente binomiale. Infatti, è possibile scomporre il coefficiente binomiale nel seguente modo:
In questo modo è possibile ottenere due strutture di ricorrenza per il coefficiente binomiale, ovvero:
La covarianza tra due variabili statistiche X e Y, indicata con è un indice di variabilità congiunta che fornisce una misura di quanto le due varino assieme, ovvero della loro dipendenza. Può essere calcolata solo su due insiemi con la stessa numerosità. è possibile costruire un indice relativo della covarianza, denominato indice di correlazione di Bravais-Pearson, in maniera tale che vari tra -1 e 1 (al fine di ottenere una miglior comprensione della dipendenza, essendo la covarianza legata all’ordine di grandezza delle osservazioni), dividendo il suo valore per il prodotto delle deviazioni standard delle due varibili. La formula dell’indice di correlazione è la seguente:
Indicando con la media della variabile X e con la media della variabile Y, date n osservazioni per entrambe le variabili, la formula per calcolare la covarianza è la seguente:
Questa formula, come anche la media e la varianza, presenta diversi limiti in un contesto informatico. Infatti, è necessario la conoscenza preliminare del numero di osservazioni, cosa che non sempre è realizzabile. Per ovviare a questo problema si utilizza una relazione di ricorrenza, ovvero una formula ricorsiva che esprime il valore del termine n-esimo di una successione in funzione dei termini precedenti (in particolare, in questo caso, solo del termine precedente). In questo modo non è più necessaria la conoscenza preliminare del numero di dati che verranno forniti in input, ma è possibile aggiornare ricorsivamente il valore della covarianza ad ogni nuova coppia di osservazioni.
Possiamo riscrivere la somma dei prodotti delle osservazioni di due variabili X e Y, a cui sono state sottratte due costanti arbitrarie e , nel seguente modo:
Dove indica la somma dei prodotti ad un dato passo n. Ponendo e pari alle medie delle variabili al passo n-1, ovvero e , possiamo riscrivere la formula come segue:
è quindi possibile aggiornare la somma dei prodotti in due diversi modi equivalenti:
Quando si scrive un programma, è essenziale ricordare che potrebbe essere riletto numerose volte, ed eventualmente anche modificato. Si rende quindi necessario scrivere un codice facilmente leggibile da tutti, per poter comprendere cosa il codice fa in minor tempo. In questo contesto nascono le convenzioni sui nomi, che forniscono uno standard nella scrittura dei programmi. Tra le diverse convenzioni sui nomi adottate dai programmatori, le più diffuse sono:
Camel Case
Pascal Case
Snake Case
Kebab Case
Screaming Case
Hungarian Notation
Prima di vedere nel dettaglio le diverse convenzioni, occorre sottolineare che esse vengono divise in due macro-categorie:
Tipografiche: Fa riferimento all’uso delle diverse dimensioni del carattere e ai simboli quali trattino basso, punto e trattino.
Grammatiche: Fa riferimento alla semantica e allo scopo. Ad esemio, le classi dovrebbero essere sostantivi o frasi nominative per identificare l’entità, i metodi e le funzioni dovrebbero essere verbi per identificare l’azione compiuta.
Camel case
Il camel case (o notazione a cammello) nasce dalla pratica di scrivere parole composte o frasi unendo tutte le parole tra loro, ma lasciando le loro iniziali maiuscole. Il nome deriva dai “salti” all’interno di una parola, che fanno venire in mente le gobbe di un cammello. Alcuni esempi famosi di questa convenzione sono “FedEx”, “iPhone” e “eBay”. Questa convenzione viene ad esempio adottata da Java, che utilizza la forma con le iniziali maiuscole per specificare le classi e la forma con le iniziali minuscole per specificare gli oggetti.
Pascal case
Può essere considerato una sottocategoria del camel case dove le parole devono rigorosamente iniziare con una lettera maiuscola. Ad esempio, “FedEx” è in pascal case, ma “iPhone” non lo è. Questa convenzione viene adottata, ad esempio, dal linguaggio Pascal, da cui deriva anche il nome del pascal case.
Snake case
Lo snake case consiste nello scrivere gli identificatori separando le parole che lo compongono con un trattino basso, solitamente lasciando minuscole le iniziali delle parole e la prima lettera dell’intero identificatore minuscola o maiuscola (ad esempio “foo_bar” e “Hello_world”). Viene ampiamente utilizzato in programmazione e studi dimostrano che è sia più leggibile rispetto il camel case. Viene utilizzato da diversi linguaggi, come C, C++ e Python.
Kebab case
Molto simile allo snake case, consiste nello scrivere gli identificatori separando le parole che lo compongono con dei trattini (ad esempio “kebab-case”). Ovviamente questa convenzione può essere usata solo in quei linguaggi che ammettono il trattino come carattere valido in un identificatore (ad esempio non è ammesso in C ed i suoi derivati). Viene comunemente utilizzato da linguaggi come ad esempio Forth, Cobol , Lisp e CSS.
Screaming case
Questa convenzione ha essenzialmente due varianti, molto simili: la prima consiste nello scrivere le parole tutte in maiuscolo e senza spazi (ad esempio “TAXRATE”); la seconda invece prevede la separazione delle diverse parole che compongo l’identificatore tramite un trattino basso, lasciando sempre le parole tutte in maiuscolo (ad esempio “TAX_RATE”), motivo per il quale viene chiamato anche screaming snake case. Il nome (letteralmente caso urlato) deriva dal fatto che, convenzionalmente, su internet la scrittura di tutta una parola in maiuscolo equivale ad urlare.
Hungarian notation
La hungarian notation (in italiano notazione ungara o notazione ungherese) è una convenzione in cui il nome dell’oggetto indica il suo tipo e il suo scopo d’uso. È stata progettata in maniera tale da essere indipendente dal linguaggio. Nella hungarian notation, un nome di variabile inizia con un prefisso costituito da una o più lettere minuscole in modo da formare un codice mnemonico per il tipo o lo scopo di questa variabile. Il prefisso è seguito dal nome scelto dal programmatore. Il primo carattere del nome assegnato è in maiuscolo come nel camel case.
Alcuni esempi dell’hungarian notation sono i seguenti:
Come abbiamo già visto per la media, il calcolo delle statistiche di un campione può portare diversi problemi, sia perché, utilizzando le formule canoniche, è spesso necessario sapere in partenza il numero di elementi che si andrà a considerare, sia per le approssimazioni dovute alla rappresentazione con cifre finite dei numeri reali, che possono portare problemi quali la perdita di significatività e la cancellazione catastrofica.
Se prendiamo in considerazione la varianza, la formula canonica per il calcolo della varianza campionaria è la seguente:
Questa formula però richiede la conoscenza a priori del numero di elementi del campione, cosa che non sempre è possibile. Sono stati quindi sviluppati diversi algoritmi che permetto di superare questa limitazione ed anche quella relativa alla precisione del calcolo. In particolare, l’algoritmo di Knuth permette il calcolo online della varianza
Algoritmo di Knuth
Questo algoritmo permette appunto il calcolo della varianza in un passo singolo, elaborando ogni valore una sola volta. Per prima cosa occorre definire l’aggiornamento della media campionaria, che avviene con la seguente formula (descritta meglio nell’articolo relativo all’algoritmo di Knuth):
Vediamo innanzitutto come può essere decomposto lo scarto semplice dell’ultimo elemento osservato dalla media campionaria, in modo da poterlo legare al passo (n-1)esimo:
A questo punto sfruttiamo una delle proprietà della media campionaria. Essa infatti minimizza la somma delle differenze al quadrato , ovvero:
Inoltre è vera l’equazione:
Considerando ora la devianza delle n osservazioni, e chiamandola per semplicità, è vera la seguente relazione:
Sostituendo ad la media aggiornata utilizzando la prima formula, e ad il primo termine è possibile riscrivere la formula della devianza con una struttura iterativa che utilizza, per il calcolo della devianza all’elemento nesimo, la devianza all’elemento (n-1)esimo. Per ricavare la varianza non servirà altro che dividere il risultato per n. La formula diventa quindi la seguente:
Infine, utilizzando la formula che lega lo scarto semplice dell’ultimo elemento osservato dalla media campionari al passo (n-1)esimo, possiamo scrivere:
Per poter gestire più oggetti dello stesso tipo, abbiamo visto che è possibile utilizzare strutture come gli array. Tuttavia, essi hanno un limite che può complicare notevolmente il loro utilizzo. Infatti, bisogna dichiarare in precedenza il numero di elementi che verranno trattati, compito che a volte risulta impossibile, soprattutto quando si vanno a trattare dati di grande dimensione ed è impossibile stabilire la quantità massima di elementi che verranno salvati. Con il tempo sono state sviluppate diverse alternative che permetto di superare questi ed altri limite: liste e dizionari.
Liste
Una lista è una struttura dati dinamica che denota una collezione omogenea di dati. Contrariamente agli array, la memoria utilizzata non è necessariamente contigua. L’accesso ad un elemento avviene attraverso l’utilizzo di un indice. A seconda del linguaggio utilizzato, le liste possono essere indicizzate a partire da 0 (come in VB.net) o a partire da 1 (come in C#). Tuttavia, solitamente l’accesso agli elementi di una lista avviene in maniera diretta solo per il primo elemento della sequenza ; per accedere a un qualunque elemento, occorre scandire sequenzialmente tutti gli elementi che lo precedono. La particolarità di questa struttura è che, contrariamente agli array tradizionali, non è necessario specificare la dimensione in dichiarazione, ma varierà a seconda del numero di elementi inseriti. In VB.net e in C# sono dichiarate con le seguenti sintassi:
VB.net
Dim NameList As New List(Of DataType)
C#
List<dataType> nameList = new List<dataType>();
Dizionari
I dizionari sono strutture dati che denotano una collezione di dati. Come le liste, la loro dimensione non deve essere specificata in fase di dichiarazione, ma sarà stabilita dinamicamente in base al numero di elementi al suo interno. Un’altra peculiarità di questa struttura è la possibilità di accedere agli elementi attraverso una chiave stabilita direttamente dal programmatore. Infatti, questa struttura è caratterizzata dall’inserimento dei valori attraverso la coppia chiave-valore, dove ogni chiave può comparire al più una sola volta. Le operazioni ammesse su un dizionario sono:
l’inserimento di una nuova coppia
la rimozione di una coppia dalla collezione
la modifica di una coppia esistente
la ricerca di un particolare valore associato ad una determinata chiave
In VB.net e in C# viene dichiarata con la seguente sintassi:
VB.net
Dim NameDictionary As New Dictionary(Of TypeKey, TypeValue)
C#
Dictionary<typeKey, typeValue> nameDictionary =
new Dictionary<typeKey, typeValue>();
La finitezza nella rappresentazione dei numeri reali all’interno di un computer può portare a diversi tipi di errori. Da una parte, la limitazione nella dimensione dei numeri può comportare errori quali overflow e underflow, ovvero quando il numero eccede il limite massimo o il limite minimo di rappresentazione della variabile in cui viene salvato (la dimensione delle diverse variabili numeriche è descritta meglio nell’articolo sulla rappresentazione dei tipi Float e Integer).
Altri possibili errori sono legati alla precisione finita dei tipi Float, che può generare errori quali: roundoff error; loss of significance (perdita di significatività) e catastrophic cancellation (cancellazione catastrofica).
Il roundoff error è dovuto alla rappresentazione di un numero reale usando un numero finito di cifre. Naturalmente più un numero è preciso e minore sarà questo errore. Questo errore è presente anche quando si cerca di esprimere numeri in base 10, poiché il computer utilizza la codifica in base 2. Questo problema può diventare particolarmente rilevante nell’ambito finanziario, in quanto, nonostante l’errore di approssimazione di questo tipo sia pressoché irrilevante se considerato singolarmente, la mole enorme di transazioni che vengono registrate può portare ad un accumulo di questi errori e stravolgendo il risultato. Per questo motivo è stato introdotto il tipo decimal, che permette la codifica dei numeri in base 10 e, quindi, una scrittura esatta dei valori delle transazioni.
La loss of significance, invece, è un errore che abbiamo quando occorre sommare (o sottrarre) due numeri molto differenti tra loro. Ad esempio, potrebbe essere necessario sommare un numero molto grande, che quindi sacrifica la precisione per aumentare la dimensione del numero, ed uno molto piccolo ma con un’alta precisione. La somma di questi numeri dovrebbe produrre un numero con sia un valore molto grande, che un’alta precisione. Tuttavia, la memoria finita comporta che il computer dovrà dedicare la maggior parte della memoria alle cifre del numero più grande, sacrificando quindi la precisione dovuta al numero più piccolo.
Infine, la catastrophic cancellation avviene quando un’operazione su due numeri comporta un aumento dell’errore relativo notevolmente più di quanto aumenti l’errore assoluto. Ad esempio, quando si sottraggono due numeri praticamente identici (ovvero che differiscono per le ultime cifre decimali), può comportare una diminuzione inaccettabile delle cifre significative. Vediamo un esempio nel dettaglio.
Consideriamo il numero:
x = 0.1234567891234567890
Se vogliamo rappresentarlo nel computer con un float con 10 cifre dopo la virgola, avremmo:
xFloat = 0.1234567891
L’errore relativo in questa approssimazione è tutto sommato irrilevante, quindi possiamo considerare questa come una buona approssimazione.
Tuttavia, se eseguiamo l’operazione:
y = 0.1234567890000000000
x-y = 0.1234567891234567890 - 0.1234567890000000000
Otteniamo come risultato:
0.0000000001234567890
Se invece operassimo questa operazione nel computer, utilizzando l’approssimazione a 10 cifre decimale proposta prima, otterremmo come risultato:
0.1234567891 − 0.1234567890 = 0.0000000001
L’errore relativo in questo caso è decisamente elevato e la perdita di cifre significative diventa molto più importante e dannosa.
Ogni dato, indipendentemente dal suo tipo, viene memorizzato in un computer con una stringa binaria. Le differenze poi sono stabilite in fase di lettura, ovvero il modo in cui una sequenza viene letta determina il valore (ed il tipo) del dato stesso. In particolare, è possibile memorizzare due tipologie diverse di dati numerici: Integer e Float.
I dati Integer rappresentano i numeri interi e, a seconda del linguaggio di programmazione, è possibile definire tipi di diverse dimensioni. I tipi interi possono ammettere segno negativo oppure essere unsigned. Esistono tre modi differenti per rappresentare i numeri negativi in un sistema binario. Il più comune è il “complemento a due”, che permette di rappresentare i numeri da -2(n-1) a 2(n-1)-1. Col complemento a due, il primo bit del numero ha peso negativo o positivo; da questo deriva che tutti i numeri che cominciano con un “1” sono numeri binari negativi, mentre tutti i numeri che cominciano con uno “0” sono numeri binari positivi.
La quantità di numeri che un Integer può rappresentare, dipende dal numero di bits da cui è composto. Un Integer con n bits può rappresentare 2n numeri. I numeri interi vengono codificati direttamente in binario.
Per i numeri Float, o a virgola mobile, la codifica è più complessa. Infatti, un numero in virgola mobile è costituito nella sua forma più semplice da due parti:
un campo significando o mantissaM;
un campo esponente e.
Un generico numero reale a può così essere rappresentato come:
Un numero è caratterizzato dal valore b, che costituisce la base della notazione in cui è scritto il numero, e la quantità p di cifre presenti nella mantissa, detta precisione.
Bisogna tuttavia sottolineare come il tipo decimal, pur essendo un Float, sia leggermente diverso dagli altri. Infatti, contrariamente a tutti gli altri tipi numerici, è codificato in base 10 (invece che nella canonica base 2). La motivazione è che questo permette di scrivere i numeri in base 10 in maniera esatta, ovvero non ricorrendo ad approssimazioni. Questo è molto utile sopratutto in ambito finanziario, in quanto le transazioni posso essere registrate con l’importo esatto, evitando così problemi legati all’approssimazione.
La tipologia di Integer, come anche di Float, definibili, dipende dal linguaggio utilizzato. Di seguito sono riportati le tipologie di numeri Integer e Float in C# e in VB.net, con il range di valori che possono assumere. Per i tipi Float viene anche riportata la precisione massima.
Quando si parla di Array (o Vettori) nell’informatica, ci si riferisce ad una struttura di dati contenenti più valori. Si può immaginare un array come una sorta di contenitore, le cui caselle sono dette celle (o elementi) dell’array stesso. Ciascuna delle celle si comporta come una variabile tradizionale; tutte le celle sono variabili di uno stesso tipo preesistente, detto tipo base dell’array. Sono molto utilizzati, in quanto semplificano enormemente la collezione di più variabili dello stesso tipo. Ciascuna delle celle dell’array è identificata da un valore di indice. È possibile accedere singolarmente ad una sua generica posizione.
A differenza delle variabili tradizionali, quando si copia un array in un secondo, non si copia il valore contenuto nelle celle dell’array, ma le coordinate che permetto di risalire a quelle celle, ovvero sono dei reference type. Le operazioni quindi fatte su una copia dell’array, verranno fatte in verità sugli elementi dell’array originale.
Sia in C# che in VB.net quando viene inizializzato un array, bisogna indicarne il tipo di variabili che verranno salvate nelle sue celle, oltre alla lunghezza dell’array stesso. La necessità di indicare preventivamente il numero (perlomeno massimo) di elementi che si intende, o prevede, salvare all’interno dell’array, crea un notevole limite, che però viene superato grazie alla classe di elementi ArryList, che in sostanza sono degli array a lunghezza variabile.
Di seguito sono riportati i codici per inizializzare un array sia in C#, sia in VB.net.
VB.net
Dim NomeArray(num) As TipoArray
C#
tipoArray[] nomeArray = new tipoArray[num];
Una fondamentale differenza nelle due sintassi riguarda il significato di num. Infatti, in VB.net, il valore di num indica il valore dell’indice dell’ultima cella, che vengono indicizzate a partire da 0. Di conseguenza, il numero di celle dell’array sarà pari a num + 1. Invece in C#, il valore di num indica la lunghezza effettiva del vettore. Inoltre gli array sono indicizzati a partire dal valore 1.
Il controllo e l’utilizzo degli array avviene spesso attraverso il ciclo for e il ciclo foreach. Entrambi sono delle strutture di controllo per specificare iterazioni.
Un ciclo for viene usato solitamente quando il modo più naturale per esprimere la condizione di permanenza in un ciclo consiste nello specificare quante volte debbano essere ripetuti l’istruzione o il blocco controllati dal ciclo. Risulta, quindi, spesso indicato per operazioni in cui è necessario scorrere tutto un array (ad esempio per copiarne i valori delle celle in un secondo array).
Il ciclo for è composto da due parti: una intestazione che specifica le condizioni delle iterazioni ed un corpo che viene eseguito se sono rispettate le condizioni. Spesso le condizioni di iterazione si basano su di un indice che viene inizializzato con valore zero e viene incrementato ad ogni iterazione (solitamente di 1) finché non raggiunge un fissato valore massimo ed a quel punto si interrompe il ciclo. Ogni operazione fatta con il ciclo for può essere riscritta con un ciclo while e viceversa.
Il ciclo foreach viene invece utilizzato quando bisogna compiere operazioni per cui non è necessario tenere un indice numerico delle iterazioni. In sostanza equivale alla frase “esegui questa operazione per ogni elemento di questo insieme”, mentre invece il ciclo for può essere parafrasato come “esegui questa operazionenvolte”. Questa differenza lo rende particolarmente adatto alle operazioni sui vettori, più del ciclo for.
Di seguito è riportata la sintassi per l’utilizzo di questi due cicli in C# e VB.net
Ciclo For
VB.net
For counter [ As datatype ] = start To end [ Step ]
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next
Applicazione per il calcolo della media di tutti i numeri compresi tra due interi
Questa applicazione, sviluppata sia in C# che in VB.net, prevede l’inserimento in input di due interi, uno massimo ed uno minimo, e il calcolo della media di tutti gli interi compresi tra questi due, estremi inclusi. Vengono inoltre visualizzati separati gli interi pari e gli interi dispari generati. Il calcolo della media avviene attraverso l’algoritmo di Knuth.
Soluzione in C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CalcolaMediaC
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int PrimInt;
int UltInt;
int conta;
double media;
private void Calcola_Click(object sender, EventArgs e)
{
media = 0;
conta = 0;
PrimInt = int.Parse(this.NumPri.Text);
UltInt = int.Parse(this.NumUlt.Text);
if (PrimInt > UltInt)
{
MessageBox.Show("Inserimento non valido", "Riprova");
}
else
{
String testoP = "";
String testoD = "";
while (PrimInt <= UltInt)
{
conta += 1;
media = ((conta - 1) * media + PrimInt) / conta;
if (PrimInt % 2 == 0)
{
testoP = String.Concat(testoP, PrimInt.ToString(), " ");
}
else
{
testoD = String.Concat(testoD, PrimInt.ToString(), " ");
}
if (conta % 8 == 0)
{
testoP = testoP + "\n";
testoD = testoD + "\n";
}
PrimInt += 1;
}
LabNP.Text = testoP;
LabND.Text = testoD;
LabMedia.Text = media.ToString();
}
}
}
}
Public Class Form1
Dim PrimInt As Integer
Dim UltInt As Integer
Dim Conta As Integer
Dim Media As Double
Private Sub Inserimento(sender As Object, e As EventArgs) Handles Calcola.Click
Media = 0
Conta = 0
PrimInt = Integer.Parse(Me.NumPri.Text)
UltInt = Integer.Parse(Me.NumUlt.Text)
If PrimInt > UltInt Then
MessageBox.Show("Inserimento non valido", "Riprova")
Else
Dim testoP As String = ""
Dim testoD As String = ""
While PrimInt <= UltInt
Conta += 1
Media = ((Conta - 1) * Media + PrimInt) / Conta
If PrimInt Mod 2 = 0 Then
testoP = testoP & String.Format("{0, -12}", PrimInt.ToString)
Else
testoD = testoD & String.Format("{0, -12}", PrimInt.ToString)
End If
If Conta Mod 8 = 0 Then
testoP = testoP & vbCrLf
testoD = testoD & vbCrLf
End If
PrimInt += 1
End While
LabNP.Text = testoP
LabND.Text = testoD
LabMedia.Text = Media.ToString
End If
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
Select Case keyData
Case Keys.Enter
Calcola.PerformClick()
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class
Public Class Form1
Dim PrimInt As Integer
Dim UltInt As Integer
Dim Conta As Integer
Dim Media As Double
Dim MediaPred As Double
Dim Varianza As Double
Dim Filler As Integer
Private Sub Inserimento(sender As Object, e As EventArgs) Handles Calcola.Click
Media = 0
MediaPred = 0
Conta = 0
Varianza = 0
PrimInt = Integer.Parse(Me.NumPri.Text)
UltInt = Integer.Parse(Me.NumUlt.Text)
Dim Interi = New List(Of Integer)
If PrimInt > UltInt Then
MessageBox.Show("Inserimento non valido", "Riprova")
Else
For counter As Integer = PrimInt To UltInt
Interi.Add(counter)
Next
Dim testoP As String = ""
Dim testoD As String = ""
While Conta < Interi.Count()
Conta += 1
MediaPred = Media
Media = ((Conta - 1) * Media + Interi(Conta - 1)) / Conta
If Interi(Conta - 1) < 10 Then
Filler = 12
ElseIf Interi(Conta - 1) < 100 Then
Filler = 11
Else
Filler = 10
End If
If Interi(Conta - 1) Mod 2 = 0 Then
testoP = testoP & String.Format("{0, -" + Filler.ToString + "}", Interi(Conta - 1).ToString)
Else
testoD = testoD & String.Format("{0, -" + Filler.ToString + "}", Interi(Conta - 1).ToString)
End If
If Conta Mod 8 = 0 Then
testoP = testoP & vbCrLf
testoD = testoD & vbCrLf
End If
Varianza = Varianza + (Interi(Conta - 1) - Media) * (Interi(Conta - 1) - MediaPred)
End While
LabNP.Text = testoP
LabND.Text = testoD
LabMedia.Text = Media.ToString
LabVar.Text = (Math.Round(Varianza / Conta, 2)).ToString
End If
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
Select Case keyData
Case Keys.Enter
Calcola.PerformClick()
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class
Applicazione per il calcolo della media e della varianza rispettivamente di tutti i numeri pari e di tutti i dispari interi compresi tra due interi e della covarianza tra le due liste
Soluzione in C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace CalcolaListeC
{
public partial class Form1 : Form
{
int PrimInt;
int UltInt;
double MediaPar;
double MediaDis;
double VarianzaPar;
double VarianzaDis;
double Cov;
public Form1()
{
InitializeComponent();
}
private void Calcola_Click(object sender, EventArgs e)
{
MediaPar = 0;
MediaDis = 0;
VarianzaPar = 0;
VarianzaDis = 0;
PrimInt = int.Parse(this.NumPri.Text);
UltInt = int.Parse(this.NumUlt.Text);
var InteriPar = new List<int>();
var InteriDis = new List<int>();
if (PrimInt > UltInt)
MessageBox.Show("Inserimento non valido", "Riprova");
else
{
for (int counter = PrimInt; counter <= UltInt; counter++)
if (counter % 2 == 0)
InteriPar.Add(counter);
else
InteriDis.Add(counter);
string testoP = StringTesto(InteriPar);
string testoD = StringTesto(InteriDis);
MeidaPar = CalcolaMedia(InteriPar);
MeidaDis = CalcolaMedia(InteriDis);
VarianzaPar = CalcolaVarianzaC(InterPar);
VarianzaDis = CalcolaVarianzaC(InterDis);
if (InteriDis.Count == InteriPar.Count)
{
Cov = CalcolaCov(InteriPar, InteriDis);
LabCov.Text = (Math.Round(Cov/InteriPar.Count,2)).ToString
}
else
LabCov.Text = "Impossibile";
LabNP.Text = testoP;
LabND.Text = testoD;
LabMedia.Text = MediaPar.ToString();
LabMedia2.Text = MediaDis.ToString();
LabVar.Text = (Math.Round(VarianzaPar / (double)InteriPar.Count, 2)).ToString();
LabVar2.Text = (Math.Round(VarianzaDis / (double)InteriDis.Count, 2)).ToString();
}
}
public string StringTesto(List<int> Interi)
{
int Filler;
int Conta = 0;
string Testo = "";
while (Conta < Interi.Count())
{
if (Interi[Conta] < 10)
Filler = 12;
else if (Interi[Conta] < 100)
Filler = 11;
else
Filler = 10;
Testo = Testo + string.Format("{0, -" + Filler.ToString() + "}", Interi[Conta].ToString());
if ((Conta + 1) % 4 == 0)
Testo = Testo + Environment.NewLine;
Conta += 1;
}
return Testo;
}
public double CalcolaMedia(List<int> Interi)
{
int Conta = 0;
double Media = 0;
double MediaPred = 0;
while (Conta < Interi.Count())
{
MediaPred = Media;
Media = ((Conta) * Media + Interi[Conta]) / (Conta + 1);
Conta += 1;
}
return Media;
}
public double CalcolaVar(List<int> Interi)
{
double Var = 0;
int Conta = 0;
double Media = 0;
double MediaPred = 0;
while (Conta < Interi.Count())
{
MediaPred = Media;
Media = ((Conta) * Media + Interi[Conta]) / (Conta + 1);
Var = Var + (Interi[Conta] - Media) * (Interi[Conta] - MediaPred);
Conta += 1;
}
return Var;
}
public double CalcolaCov(List<int> Int1, List<int> Int2)
{
double Cov = 0;
int Conta = 0;
double Media1 = 0;
double Media2 = 0;
double MediaPred1 = 0;
double MediaPred2 = 0;
while (Conta < Int1.Count())
{
MediaPred1 = Media1;
Media1 = ((Conta) * Media1 + Int1[Conta]) / (Conta + 1);
MediaPred2 = Media2;
Media2 = ((Conta) * Media2 + Int2[Conta]) / (Conta + 1);
Cov = Cov + ((Int1[Conta] - Media1) * (Int2[Conta] - MediaPred2));
Conta += 1;
}
return Cov;
}
private void label6_Click(object sender, EventArgs e)
{
}
private void label9_Click(object sender, EventArgs e)
{
}
}
Public Class Form1
Dim PrimInt As Integer
Dim UltInt As Integer
Dim MediaPar As Double
Dim MediaDis As Double
Dim VarianzaPar As Double
Dim VarianzaDis As Double
Dim Cov As Double
Private Sub Inserimento(sender As Object, e As EventArgs) Handles Calcola.Click
MediaPar = 0
MediaDis = 0
VarianzaPar = 0
VarianzaDis = 0
PrimInt = Integer.Parse(Me.NumPri.Text)
UltInt = Integer.Parse(Me.NumUlt.Text)
Dim InteriPar = New List(Of Integer)
Dim InteriDis = New List(Of Integer)
If PrimInt > UltInt Or PrimInt < 0 Then
MessageBox.Show("Inserimento non valido", "Riprova")
Else
For counter As Integer = PrimInt To UltInt
If counter Mod 2 = 0 Then
InteriPar.Add(counter)
Else
InteriDis.Add(counter)
End If
Next
Dim testoP As String = StringTesto(InteriPar)
Dim testoD As String = StringTesto(InteriDis)
MediaPar = CalcolaMedia(InteriPar)
MediaDis = CalcolaMedia(InteriDis)
VarianzaPar = CalcolaVar(InteriPar)
VarianzaDis = CalcolaVar(InteriDis)
If InteriDis.Count = InteriPar.Count Then
Cov = CalcolaCov(InteriPar, InteriDis)
LabCov.Text = (Math.Round(Cov / InteriPar.Count, 2)).ToString
Else
LabCov.Text = "Impossibile"
End If
LabNP.Text = testoP
LabND.Text = testoD
LabMediaPari.Text = MediaPar.ToString
LabMediaDis.Text = MediaDis.ToString
LabVarPari.Text = (Math.Round(VarianzaPar / InteriPar.Count, 2)).ToString
LabVarDis.Text = (Math.Round(VarianzaDis / InteriDis.Count, 2)).ToString
End If
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
Select Case keyData
Case Keys.Enter
Calcola.PerformClick()
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Public Function StringTesto(ByVal Interi As List(Of Integer)) As String
Dim Filler As Integer
Dim Conta As Integer = 0
Dim Testo As String = ""
While Conta < Interi.Count()
If Interi(Conta) < 10 Then
Filler = 12
ElseIf Interi(Conta) < 100 Then
Filler = 11
Else
Filler = 10
End If
Testo = Testo & String.Format("{0, -" + Filler.ToString + "}", Interi(Conta).ToString)
If (Conta + 1) Mod 4 = 0 Then
Testo = Testo & vbCrLf
End If
Conta += 1
End While
Return Testo
End Function
Public Function CalcolaMedia(ByVal Interi As List(Of Integer)) As Double
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Conta += 1
End While
Return Media
End Function
Public Function CalcolaVar(ByVal Interi As List(Of Integer)) As Double
Dim Var As Double = 0
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Var = Var + (Interi(Conta) - Media) * (Interi(Conta) - MediaPred)
Conta += 1
End While
Return Var
End Function
Public Function CalcolaCov(ByVal Int1 As List(Of Integer), ByVal Int2 As List(Of Integer)) As Double
Dim Cov As Double = 0
Dim Conta As Integer = 0
Dim Media1 As Double = 0
Dim Media2 As Double = 0
Dim MediaPred1 As Double = 0
Dim MediaPred2 As Double = 0
While Conta < Int1.Count()
MediaPred1 = Media1
Media1 = ((Conta) * Media1 + Int1(Conta)) / (Conta + 1)
MediaPred2 = Media2
Media2 = ((Conta) * Media2 + Int2(Conta)) / (Conta + 1)
Cov = Cov + ((Int1(Conta) - Media1) * (Int2(Conta) - MediaPred2))
Conta += 1
End While
Return Cov
End Function
End Class
Lettura dei dati da un file .csv e calcolo delle frequenze
Soluzione in VB.net
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.RichTextBox1.Clear()
Dim separator As String = Me.RichTextBox2.Text.ToString
Dim dimensioni As Integer
Try
dimensioni = Integer.Parse(Me.RichTextBox3.Text)
Catch ex As Exception
Me.RichTextBox1.Text = "Il numero di dimensioni deve essere un intero tra 1 e 2!"
Exit Sub
End Try
If dimensioni < 1 Or dimensioni > 2 Then
Me.RichTextBox1.Text = "Il numero di dimensioni deve essere un intero tra 1 e 2!"
Exit Sub
End If
Dim ofd As New OpenFileDialog
ofd.ShowDialog()
Me.RichTextBox1.Text = "Nome scelto " & ofd.FileName
If dimensioni = 2 Then
Dim sr As New StreamReader(ofd.FileName)
Dim Y As New List(Of Double)
Dim X As New List(Of Double)
Me.RichTextBox1.AppendText(vbCrLf & "Y X ")
While Not sr.EndOfStream
Dim RigaDati As String = sr.ReadLine()
Dim Dati() As String = RigaDati.Split(separator.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
Y.Add(Convert.ToDouble(Dati(1)))
X.Add(Convert.ToDouble(Dati(0)))
Me.RichTextBox1.AppendText(vbCrLf & Convert.ToDouble(Dati(1)).ToString & Convert.ToDouble(Dati(0)).ToString)
End While
Dim beta As Double
Dim alfa As Double
beta = CalcolaCov(X, Y) / CalcolaVar(X)
alfa = CalcolaMedia(Y) - beta * CalcolaMedia(X)
Dim Y_hat As New List(Of Double)
Dim Epsilon As New List(Of Double)
For conta As Integer = 0 To (Y.Count - 1)
Dim th = alfa + beta * X(conta)
Y_hat.Add(th)
Epsilon.Add(Y(conta) - th)
Next
Dim R2 As Double
Dim Ess As Double
Dim Rss As Double
Ess = CalcolaVar(Epsilon)
Rss = CalcolaVar(Y_hat)
R2 = Rss / CalcolaVar(Y)
Me.RichTextBox1.AppendText(vbCrLf & "I valori della regressione sono:" & vbCrLf & "Intercetta: " & alfa.ToString & vbCrLf &
"Coefficiente angolare: " & beta.ToString & vbCrLf & "R2: " & R2.ToString & vbCrLf & "Ess: " & Ess.ToString & vbCrLf &
"Rss: " & Rss.ToString)
DisegnaGrafico(X, Y)
Y.Sort()
X.Sort()
Dim DistY As New ContaFreq
DistY.Fill(Y, Y(0), ((Y(Y.Count - 1) - Y(0)) / 10))
Dim DistX As New ContaFreq
DistX.Fill(X, X(0), ((X(X.Count - 1) - X(0)) / 10))
Me.RichTextBox1.AppendText(vbCrLf & "Distribuzione X")
Me.RichTextBox1.AppendText(DistX.Stampa())
Me.RichTextBox1.AppendText(vbCrLf & "Distribuzione Y")
Me.RichTextBox1.AppendText(DistY.Stampa())
End If
End Sub
Public Function CalcolaMedia(ByVal Interi As List(Of Double)) As Double
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Conta += 1
End While
Return Media
End Function
Public Function CalcolaVar(ByVal Interi As List(Of Double)) As Double
Dim Var As Double = 0
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Var = Var + (Interi(Conta) - Media) * (Interi(Conta) - MediaPred)
Conta += 1
End While
Return Var
End Function
Public Function CalcolaCov(ByVal Int1 As List(Of Double), ByVal Int2 As List(Of Double)) As Double
Dim Cov As Double = 0
Dim Conta As Integer = 0
Dim Media1 As Double = 0
Dim Media2 As Double = 0
Dim MediaPred1 As Double = 0
Dim MediaPred2 As Double = 0
While Conta < Int1.Count()
MediaPred1 = Media1
Media1 = ((Conta) * Media1 + Int1(Conta)) / (Conta + 1)
MediaPred2 = Media2
Media2 = ((Conta) * Media2 + Int2(Conta)) / (Conta + 1)
Cov = Cov + ((Int1(Conta) - Media1) * (Int2(Conta) - MediaPred2))
Conta += 1
End While
Return Cov
End Function
Private Sub DisegnaGrafico(X As List(Of Double), Y As List(Of Double))
'Creazione Grafico
Dim b As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height)
Dim g As Graphics = Graphics.FromImage(b)
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
g.InterpolationMode = Drawing2D.InterpolationMode.High
Dim FinestraVirtuale As New Rectangle(10, 10, Me.PictureBox1.Width - 20, Me.PictureBox1.Height - 20)
g.Clear(Color.White)
g.DrawRectangle(Pens.Blue, FinestraVirtuale)
Dim MinX As Double = 0
Dim MinY As Double = 0
Dim MaxX As Double = 3.607
Dim MaxY As Double = 4.737
For h As Integer = 0 To X.Count - 1
Dim X_graf As Integer = xVirtuale(X(h), MinX, MaxX, FinestraVirtuale)
Dim Y_graf As Integer = yVirtuale(Y(h), MinY, MaxY, FinestraVirtuale)
g.FillEllipse(Brushes.OrangeRed, New Rectangle(X_graf, Y_graf, 5, 5))
Next
Me.PictureBox1.Image = b
End Sub
Private Function xVirtuale(p1 As Double, MinX As Double, MaxX As Double, FinestraVirtuale As Rectangle) As Integer
Return CInt(FinestraVirtuale.Left + (FinestraVirtuale.Width * ((p1 - MinX) / (MaxX - MinX))))
End Function
Private Function yVirtuale(p1 As Double, MinY As Double, MaxY As Double, FinestraVirtuale As Rectangle) As Integer
Return CInt(FinestraVirtuale.Top + (FinestraVirtuale.Height * (1 - ((p1 - MinY) / (MaxY - MinY)))))
End Function
End Class
Prima applicazione semi interattiva
Soluzione in VB.net
Imports System.IO
Public Class Form1
Public Loc_MD As Point
Public Loc_Rett As Point
Dim FinestraVirtuale As New Rectangle(10, 10, 200, 100)
Dim b As New Bitmap(300, 200)
Dim g As Graphics = Graphics.FromImage(b)
Public drag As Boolean
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.RichTextBox1.Clear()
Dim separator As String = Me.RichTextBox2.Text.ToString
Dim dimensioni As Integer
Try
dimensioni = Integer.Parse(Me.RichTextBox3.Text)
Catch ex As Exception
Me.RichTextBox1.Text = "Il numero di dimensioni deve essere un intero tra 1 e 2!"
Exit Sub
End Try
If dimensioni < 1 Or dimensioni > 2 Then
Me.RichTextBox1.Text = "Il numero di dimensioni deve essere un intero tra 1 e 2!"
Exit Sub
End If
Dim ofd As New OpenFileDialog
ofd.ShowDialog()
Me.RichTextBox1.Text = "Nome scelto " & ofd.FileName
If dimensioni = 2 Then
Dim sr As New StreamReader(ofd.FileName)
Dim Y As New List(Of Double)
Dim X As New List(Of Double)
Me.RichTextBox1.AppendText(vbCrLf & "Y X ")
While Not sr.EndOfStream
Dim RigaDati As String = sr.ReadLine()
Dim Dati() As String = RigaDati.Split(separator.ToCharArray, StringSplitOptions.RemoveEmptyEntries)
Y.Add(Convert.ToDouble(Dati(1)))
X.Add(Convert.ToDouble(Dati(0)))
Me.RichTextBox1.AppendText(vbCrLf & Convert.ToDouble(Dati(1)).ToString & Convert.ToDouble(Dati(0)).ToString)
End While
Dim beta As Double
Dim alfa As Double
beta = CalcolaCov(X, Y) / CalcolaVar(X)
alfa = CalcolaMedia(Y) - beta * CalcolaMedia(X)
Dim Y_hat As New List(Of Double)
Dim Epsilon As New List(Of Double)
For conta As Integer = 0 To (Y.Count - 1)
Dim th = alfa + beta * X(conta)
Y_hat.Add(th)
Epsilon.Add(Y(conta) - th)
Next
Dim R2 As Double
Dim Ess As Double
Dim Rss As Double
Ess = CalcolaVar(Epsilon)
Rss = CalcolaVar(Y_hat)
R2 = Rss / CalcolaVar(Y)
Me.RichTextBox1.AppendText(vbCrLf & "I valori della regressione sono:" & vbCrLf & "Intercetta: " & alfa.ToString & vbCrLf &
"Coefficiente angolare: " & beta.ToString & vbCrLf & "R2: " & R2.ToString & vbCrLf & "Ess: " & Ess.ToString & vbCrLf &
"Rss: " & Rss.ToString)
DisegnaGrafico(X, Y)
Y.Sort()
X.Sort()
Dim DistY As New ContaFreq
DistY.Fill(Y, Y(0), ((Y(Y.Count - 1) - Y(0)) / 10))
Dim DistX As New ContaFreq
DistX.Fill(X, X(0), ((X(X.Count - 1) - X(0)) / 10))
Me.RichTextBox1.AppendText(vbCrLf & "Distribuzione X")
Me.RichTextBox1.AppendText(DistX.Stampa())
Me.RichTextBox1.AppendText(vbCrLf & "Distribuzione Y")
Me.RichTextBox1.AppendText(DistY.Stampa())
End If
End Sub
Public Function CalcolaMedia(ByVal Interi As List(Of Double)) As Double
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Conta += 1
End While
Return Media
End Function
Public Function CalcolaVar(ByVal Interi As List(Of Double)) As Double
Dim Var As Double = 0
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Var = Var + (Interi(Conta) - Media) * (Interi(Conta) - MediaPred)
Conta += 1
End While
Return Var
End Function
Public Function CalcolaCov(ByVal Int1 As List(Of Double), ByVal Int2 As List(Of Double)) As Double
Dim Cov As Double = 0
Dim Conta As Integer = 0
Dim Media1 As Double = 0
Dim Media2 As Double = 0
Dim MediaPred1 As Double = 0
Dim MediaPred2 As Double = 0
While Conta < Int1.Count()
MediaPred1 = Media1
Media1 = ((Conta) * Media1 + Int1(Conta)) / (Conta + 1)
MediaPred2 = Media2
Media2 = ((Conta) * Media2 + Int2(Conta)) / (Conta + 1)
Cov = Cov + ((Int1(Conta) - Media1) * (Int2(Conta) - MediaPred2))
Conta += 1
End While
Return Cov
End Function
Private Sub DisegnaGrafico(X As List(Of Double), Y As List(Of Double))
'Creazione Grafico
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
g.InterpolationMode = Drawing2D.InterpolationMode.High
g.Clear(Color.White)
g.DrawRectangle(Pens.Blue, FinestraVirtuale)
Dim MinX As Double = 0
Dim MinY As Double = 0
Dim MaxX As Double = 3.607
Dim MaxY As Double = 4.737
For h As Integer = 0 To X.Count - 1
Dim X_graf As Integer = xVirtuale(X(h), MinX, MaxX, FinestraVirtuale)
Dim Y_graf As Integer = yVirtuale(Y(h), MinY, MaxY, FinestraVirtuale)
g.FillEllipse(Brushes.OrangeRed, New Rectangle(X_graf, Y_graf, 5, 5))
Next
Me.PictureBox1.Image = b
End Sub
Private Function xVirtuale(p1 As Double, MinX As Double, MaxX As Double, FinestraVirtuale As Rectangle) As Integer
Return CInt(FinestraVirtuale.Left + (FinestraVirtuale.Width * ((p1 - MinX) / (MaxX - MinX))))
End Function
Private Function yVirtuale(p1 As Double, MinY As Double, MaxY As Double, FinestraVirtuale As Rectangle) As Integer
Return CInt(FinestraVirtuale.Top + (FinestraVirtuale.Height * (1 - ((p1 - MinY) / (MaxY - MinY)))))
End Function
Private Sub PictureBox1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Me.Loc_MD = e.Location
Me.Loc_Rett = Me.FinestraVirtuale.Location
Me.drag = False
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If Not drag Then
Dim deltaX As Integer = e.X - Loc_MD.X
Dim deltaY As Integer = e.Y - Loc_MD.Y
Me.FinestraVirtuale.Location = New Point(Loc_Rett.X + deltaX, Loc_Rett.Y + deltaY)
g.Clear(Color.White)
g.DrawRectangle(Pens.RoyalBlue, FinestraVirtuale)
Me.PictureBox1.Image = b
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
Me.drag = True
End Sub
End Class
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.RichTextBox1.Clear()
Dim separator As String = Me.RichTextBox2.Text.ToString
Dim ofd As New OpenFileDialog
ofd.ShowDialog()
Me.RichTextBox1.Text = "Nome scelto " & ofd.FileName
Dim sr As New StreamReader(ofd.FileName)
Dim Y As New List(Of Double)
Dim X As New List(Of Double)
While Not sr.EndOfStream
Dim RigaDati As String = sr.ReadLine()
Dim Dati() As String = RigaDati.Split(separator)
Y.Add(Convert.ToDouble(Dati(0)))
X.Add(Convert.ToDouble(Dati(0)))
End While
Dim beta As Double
Dim alfa As Double
beta = CalcolaCov(X, Y) / CalcolaVar(X)
alfa = CalcolaMedia(Y) - beta * CalcolaMedia(X)
Dim Y_hat As New List(Of Double)
Dim Epsilon As New List(Of Double)
For conta As Integer = 0 To (Y.Count - 1)
Dim th = alfa + beta * X(conta)
Y_hat.Add(th)
Epsilon.Add(Y(conta) - th)
Next
Dim R2 As Double
Dim Ess As Double
Dim Rss As Double
Ess = CalcolaVar(Epsilon)
Rss = CalcolaVar(Y_hat)
R2 = Rss / CalcolaVar(Y)
Me.RichTextBox1.AppendText(vbCrLf & "I valori della regressione sono:" & vbCrLf & "Intercetta: " & alfa.ToString & vbCrLf &
"Coefficiente angolare: " & beta.ToString & vbCrLf & "R2: " & R2.ToString & vbCrLf & "Ess: " & Ess.ToString & vbCrLf &
"Rss: " & Rss.ToString)
End Sub
Public Function CalcolaMedia(ByVal Interi As List(Of Double)) As Double
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Conta += 1
End While
Return Media
End Function
Public Function CalcolaVar(ByVal Interi As List(Of Double)) As Double
Dim Var As Double = 0
Dim Conta As Integer = 0
Dim Media As Double = 0
Dim MediaPred As Double = 0
While Conta < Interi.Count()
MediaPred = Media
Media = ((Conta) * Media + Interi(Conta)) / (Conta + 1)
Var = Var + (Interi(Conta) - Media) * (Interi(Conta) - MediaPred)
Conta += 1
End While
Return Var
End Function
Public Function CalcolaCov(ByVal Int1 As List(Of Double), ByVal Int2 As List(Of Double)) As Double
Dim Cov As Double = 0
Dim Conta As Integer = 0
Dim Media1 As Double = 0
Dim Media2 As Double = 0
Dim MediaPred1 As Double = 0
Dim MediaPred2 As Double = 0
While Conta < Int1.Count()
MediaPred1 = Media1
Media1 = ((Conta) * Media1 + Int1(Conta)) / (Conta + 1)
MediaPred2 = Media2
Media2 = ((Conta) * Media2 + Int2(Conta)) / (Conta + 1)
Cov = Cov + ((Int1(Conta) - Media1) * (Int2(Conta) - MediaPred2))
Conta += 1
End While
Return Cov
End Function
End Class
Loc_MD = e.Location
Me.Loc_Rett = Me.FinestraVirtuale.Location
Me.drag = False
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If Not drag Then
Dim deltaX As Integer = e.X - Loc_MD.X
Dim deltaY As Integer = e.Y - Loc_MD.Y
Me.FinestraVirtuale.Location = New Point(Loc_Rett.X + deltaX, Loc_Rett.Y + deltaY)
g.Clear(Color.White)
g.DrawRectangle(Pens.RoyalBlue, FinestraVirtuale)
Me.PictureBox1.Image = b
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
Me.drag = True
End Sub
End Class
La seconda applicazione sviluppata consiste in una breve avventura grafica, dove l’utente si muove all’interno di un dungeon e deve sconfiggere un boss finale. Per la flessibilità della gestione dei comandi input, questa applicazione è stata sviluppata solo in VB.net. Il codice è portato qui di seguito:
Public Class Form1
Private vita As Integer
Private atk As Integer
Private mana As Integer
Private posH As Integer
Private posV As Integer
Private key1 As Boolean
Private key2 As Boolean
Private spada As Boolean
Private poz As Boolean
Private boss As Boolean
Private vitaBoss As Integer
Private atkBoss As Integer
Private randomizer As New Random
Private Sub startButton_Click() Handles startButton.Click
For Each c As Control In Me.Controls
If TypeOf c Is Panel Then
For Each lbl As Label In c.Controls.OfType(Of Label)()
lbl.BackColor = Color.Black
Next
End If
Next
startButton.Enabled = False
Timer1.Start()
Room1.BackColor = Color.White
p1a2.BackColor = Color.White
Me.Room1.Text = "+"
vita = 100
atk = 20
mana = 50
posH = 1
posV = 1
key1 = False
key2 = False
spada = False
poz = True
boss = False
vitaBoss = 250
atkBoss = 30
MoveUp.Enabled = True
MoveDown.Enabled = True
MoveLeft.Enabled = True
MoveRight.Enabled = True
ButtonA.Enabled = True
ButtonB.Enabled = True
End Sub
Private Sub Posizione()
If (posH = 1) Then
If (posV = 1) Then
Me.Room1.BackColor = Color.White
Me.Room1.Text = "+"
Me.LabInt.Text = "Sei nella stanza numero 1" & vbCrLf & "Questa stanza è vuota "
Me.Room2.Text = ""
ElseIf (posV = 2) Then
Me.p2a3.BackColor = Color.White
Me.p2a4.BackColor = Color.White
Me.Room2.BackColor = Color.White
Me.Room1.Text = ""
Me.Room3.Text = ""
Me.Room4.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 2" & vbCrLf & "Questa stanza è vuota "
Me.Room2.Text = "+"
ElseIf (posV = 3) Then
Me.p3a5.BackColor = Color.White
Me.Room3.BackColor = Color.White
Me.Room2.Text = ""
Me.Room5.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 3" & vbCrLf & "Questa stanza è vuota "
Me.Room3.Text = "+"
End If
ElseIf (posH = 2) Then
If (posV = 2) Then
Me.p4a7.BackColor = Color.White
Me.Room4.BackColor = Color.White
Me.Room2.Text = ""
Me.Room7.Text = ""
If (key1) Then
Me.LabInt.Text = "Sei nella stanza numero 4" & vbCrLf & "Questa stanza è vuota "
Else
Me.LabInt.Text = "Sei nella stanza numero 4" & vbCrLf & "Questa stanza è vuota " & vbCrLf & "Ti serve una chiave!"
End If
Me.Room4.Text = "+"
ElseIf (posV = 3) Then
Me.Room5.BackColor = Color.White
Me.Room3.Text = ""
If (Not key1) Then
Me.LabInt.Text = "Sei nella stanza numero 5" & vbCrLf & "Hai trovato una chiave!" & vbCrLf & "A: Raccogli"
Else
Me.LabInt.Text = "Sei nella stanza numero 5" & vbCrLf & "Questa stanza è vuota"
End If
Me.Room5.Text = "+"
End If
ElseIf (posH = 3) Then
If (posV = 2) Then
Me.p6a7.BackColor = Color.White
Me.p7a9.BackColor = Color.White
Me.Room7.BackColor = Color.White
Me.Room4.Text = ""
Me.Room6.Text = ""
Me.Room9.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 7" & vbCrLf & "Questa stanza è vuota "
Me.Room7.Text = "+"
ElseIf (posV = 1) Then
Me.Room6.BackColor = Color.White
Me.Room7.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 6" & vbCrLf & "Questa stanza è vuota "
Me.Room6.Text = "+"
End If
ElseIf (posH = 4) Then
If (posV = 2) Then
Me.p8a9.BackColor = Color.White
Me.p9a10.BackColor = Color.White
Me.p9a11.BackColor = Color.White
Me.Room9.BackColor = Color.White
Me.Room7.Text = ""
Me.Room8.Text = ""
Me.Room10.Text = ""
Me.Room11.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 9" & vbCrLf & "Questa stanza è vuota "
Me.Room9.Text = "+"
ElseIf (posV = 1) Then
Me.Room8.BackColor = Color.White
Me.Room9.Text = ""
If (spada) Then
Me.LabInt.Text = "Sei nella stanza numero 8" & vbCrLf & "Questa stanza è vuota "
Else
Me.LabInt.Text = "Sei nella stanza numero 8" & vbCrLf & "Hai trovato una spada!" & vbCrLf & "A: Raccogli"
End If
Me.Room8.Text = "+"
ElseIf (posV = 3) Then
Me.p10a12.BackColor = Color.White
Me.Room10.BackColor = Color.White
Me.Room9.Text = ""
Me.Room12.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 10" & vbCrLf & "Questa stanza è vuota "
Me.Room10.Text = "+"
End If
ElseIf (posH = 5) Then
If (posV = 2) Then
Me.p11a12.BackColor = Color.White
Me.p11a14.BackColor = Color.White
Me.Room11.BackColor = Color.White
Me.Room9.Text = ""
Me.Room12.Text = ""
Me.Room14.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 11" & vbCrLf & "Questa stanza è vuota "
Me.Room11.Text = "+"
ElseIf (posV = 3) Then
Me.p11a12.BackColor = Color.White
Me.p10a12.BackColor = Color.White
Me.Room12.BackColor = Color.White
Me.Room10.Text = ""
Me.Room11.Text = ""
If (Not key2) Then
Me.LabInt.Text = "Sei nella stanza numero 12" & vbCrLf & "Hai trovato una chiave!" & vbCrLf & "A: Raccogli"
Else
Me.LabInt.Text = "Sei nella stanza numero 12" & vbCrLf & "Questa stanza è vuota "
End If
Me.Room12.Text = "+"
End If
ElseIf (posH = 6) Then
If (posV = 2) Then
Me.p14a16.BackColor = Color.White
Me.p13a14.BackColor = Color.White
Me.Room14.BackColor = Color.White
Me.Room11.Text = ""
Me.Room13.Text = ""
Me.Room16.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 14" & vbCrLf & "Questa stanza è vuota "
Me.Room14.Text = "+"
ElseIf (posV = 1) Then
Me.Room13.BackColor = Color.White
Me.Room14.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 13" & vbCrLf & "Questa stanza è vuota "
Me.Room13.Text = "+"
End If
ElseIf (posH = 7) Then
If (posV = 2) Then
Me.p15a16.BackColor = Color.White
Me.p16a17.BackColor = Color.White
Me.p16a18.BackColor = Color.White
Me.Room16.BackColor = Color.White
Me.Room14.Text = ""
Me.Room15.Text = ""
Me.Room17.Text = ""
Me.Room18.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 16" & vbCrLf & "Questa stanza è vuota "
Me.Room16.Text = "+"
ElseIf (posV = 1) Then
Me.Room15.BackColor = Color.White
Me.Room16.Text = ""
Me.LabInt.Text = "Sei nella stanza numero 15" & vbCrLf & "Questa stanza è vuota "
Me.Room15.Text = "+"
ElseIf (posV = 3) Then
Me.pFinal.BackColor = Color.LightCoral
Me.Room17.BackColor = Color.White
Me.Room16.Text = ""
If (key2) Then
Me.LabInt.Text = "Sei nella stanza numero 17" & vbCrLf & "Questa stanza è vuota "
Else
Me.LabInt.Text = "Sei nella stanza numero 17" & vbCrLf & "Questa stanza è vuota " & vbCrLf & "Ti serve una chiave!"
End If
Me.Room17.Text = "+"
ElseIf (posV = 4) Then
Me.RoomFinal.BackColor = Color.LightCoral
Me.Room17.Text = ""
Me.LabInt.Text = "Stanza del boss!"
Me.RoomFinal.Text = "+"
FunBoss()
End If
ElseIf (posH = 8) Then
If (posV = 2) Then
Me.Room18.BackColor = Color.White
Me.Room16.Text = ""
If (Not poz) Then
Me.LabInt.Text = "Sei nella stanza numero 18" & vbCrLf & "Questa stanza è vuota "
Else
Me.LabInt.Text = "Sei nella stanza numero 18" & vbCrLf & "Hai trovato una pozione!" & vbCrLf & "Può darti un bonus o un malus casuale!" & vbCrLf & "A: Bevi"
End If
Me.Room18.Text = "+"
End If
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim testo As String = "Vita: " & vita & vbCrLf & "Attacco : " & atk & vbCrLf & "Mana: " & mana & vbCrLf & vbCrLf & "Inventario:"
If (key1) Then
testo = testo & vbCrLf & "Chiave 1"
End If
If (key2) Then
testo = testo & vbCrLf & "Chiave 2"
End If
If (spada) Then
testo = testo & vbCrLf & "Spada"
End If
Me.LabStats.Text = testo
If (Me.vita <= 0) Then
Morto()
End If
If vitaBoss <= 0 Then
Vinto()
End If
End Sub
Private Sub Morto()
Timer1.Stop()
Me.LabInt.Text = "GAME OVER"
MessageBox.Show("Sei morto", "Vuoi riprovare?")
startButton.Enabled = True
MoveUp.Enabled = False
MoveDown.Enabled = False
MoveLeft.Enabled = False
MoveRight.Enabled = False
ButtonA.Enabled = False
ButtonB.Enabled = False
End Sub
Private Sub Vinto()
Timer1.Stop()
Me.LabInt.Text = "YOU WIN!"
MessageBox.Show("Complimenti, hai vinto!", "Vuoi giocare di nuovo?")
startButton.Enabled = True
MoveUp.Enabled = False
MoveDown.Enabled = False
MoveLeft.Enabled = False
MoveRight.Enabled = False
ButtonA.Enabled = False
ButtonB.Enabled = False
End Sub
Private Sub Move_Click(sender As Object, e As EventArgs) Handles MoveUp.Click, MoveDown.Click, MoveLeft.Click, MoveRight.Click
If (posV = 1 And (posH = 1 Or posH = 3 Or posH = 4 Or posH = 6 Or posH = 7)) Then
If (sender Is MoveUp) Then
posV += 1
End If
ElseIf ((posV = 3 And posH = 2) Or (posV = 2 And posH = 8)) Then
If (sender Is MoveRight) Then
posH -= 1
End If
ElseIf (posV = 2 And posH = 1) Then
If (sender Is MoveUp) Then
posV += 1
ElseIf (sender Is MoveDown) Then
posV -= 1
ElseIf (sender Is MoveLeft) Then
posH += 1
End If
ElseIf (posV = 3 And (posH = 1 Or posH = 4)) Then
If (sender Is MoveDown) Then
posV -= 1
ElseIf (sender Is MoveLeft) Then
posH += 1
End If
ElseIf (posV = 2 And posH = 2) Then
If (sender Is MoveRight) Then
posH -= 1
ElseIf (sender Is MoveLeft And key1) Then
posH += 1
End If
ElseIf (posV = 2 And (posH = 3 Or posH = 6)) Then
If (sender Is MoveRight) Then
posH -= 1
ElseIf (sender Is MoveLeft) Then
posH += 1
ElseIf (sender Is MoveDown) Then
posV -= 1
End If
ElseIf (posV = 2 And (posH = 7 Or posH = 4)) Then
If (sender Is MoveDown) Then
posV -= 1
ElseIf (sender Is MoveUp) Then
posV += 1
ElseIf (sender Is MoveRight) Then
posH -= 1
ElseIf (sender Is MoveLeft) Then
posH += 1
End If
ElseIf (posH = 5 And posV = 2) Then
If (sender Is MoveUp) Then
posV += 1
ElseIf (sender Is MoveRight) Then
posH -= 1
ElseIf (sender Is MoveLeft) Then
posH += 1
End If
ElseIf (posV = 3 And posH = 5) Then
If (sender Is MoveDown) Then
posV -= 1
ElseIf (sender Is MoveRight) Then
posH -= 1
End If
ElseIf (posV = 3 And posH = 7) Then
If (sender Is MoveDown) Then
posV -= 1
ElseIf (sender Is MoveUp And key1 And key2) Then
posV += 1
End If
End If
Posizione()
End Sub
Public Sub Interazione(sender As Object, e As EventArgs) Handles ButtonA.Click, ButtonB.Click
If (posV = 3 And posH = 2) Then
If (sender Is ButtonA) Then
key1 = True
End If
ElseIf (posV = 3 And posH = 5) Then
If (sender Is ButtonA) Then
key2 = True
End If
ElseIf (posV = 1 And posH = 4 And Not spada) Then
If (sender Is ButtonA) Then
spada = True
atk += 30
End If
ElseIf (posV = 2 And posH = 8 And poz) Then
If (sender Is ButtonA) Then
Dim cat As Integer
Dim eff As Integer
cat = randomizer.Next(1, 3)
If (cat = 1) Then
eff = randomizer.Next(-20, 50)
vita += eff
Else
eff = randomizer.Next(-5, 20)
atk += eff
End If
poz = False
End If
End If
If (boss) Then
If (sender Is ButtonA) Then
vitaBoss -= randomizer.Next(atk - 20, atk)
vita -= randomizer.Next(atkBoss - 15, atkBoss)
LabInt.Text = "Vita Boss: " & vitaBoss & vbCrLf & "A: Attacca" & " B: Curati"
End If
If ((sender Is ButtonB) And (mana > 0)) Then
mana -= 10
vita += 25
vita -= randomizer.Next(atkBoss - 30, atkBoss)
LabInt.Text = "Vita Boss: " & vitaBoss & vbCrLf & "A: Attacca" & " B: Curati"
ElseIf((sender Is ButtonB) And (mana <= 0)) Then
LabInt.Text = "Vita Boss: " & vitaBoss & vbCrLf & "Non puoi più curarti, non hai mana" & vbCrLf & " A: Attacca" & " B: Curati"
End If
End If
Posizione()
End Sub
Public Sub FunBoss()
MoveUp.Enabled = False
MoveDown.Enabled = False
MoveLeft.Enabled = False
MoveRight.Enabled = False
boss = True
LabInt.Text = "Vita Boss: " & vitaBoss & vbCrLf & "A: Attacca" & " B: Curati"
End Sub
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
Select Case keyData
Case Keys.Up
MoveUp.PerformClick()
Case Keys.Down
MoveDown.PerformClick()
Case Keys.Right
MoveRight.PerformClick()
Case Keys.Left
MoveLeft.PerformClick()
Case Keys.A
ButtonA.PerformClick()
Case Keys.B
ButtonB.PerformClick()
Case Keys.Enter
startButton.PerformClick()
End Select
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class