Archives par mot-clé : c#

USING THE LAMBDA EXPRESSION IN TRANSACTIONS VECTORS IN C#

 

USING THE LAMBDA EXPRESSION IN TRANSACTIONS VECTORS IN C SHARP

By Mohamed Ali Ettougourti

 

Operations on vectors or arrays  occupy the largest share of time spent on the execution of computer programs.

In sharp c # and other languages the term « lambda » is used to « standardize » some vector operations.

We give in these article basic examples:

We start by creating a vector or an array of double values

double [] x = new double [100];

To create random values we initiated a generator of random values « t » that we will use to fill the array « x » of random values.

System.Random t = new Random ();

To do this we will use the lambda expression illustrated by « => »

x = x.Select(b => b = t.NextDouble()).ToArray();

This simple line of code allows us to avoid for next loop, or do while loop or any other loops.

former code example:

for (int i = 0; i <x.length; i ++)

{

x [i] = t.NextDouble ();

}

The lambda expression also can perform some basic operations on the vector.

Thus we are able to calculate the sum of the values contained in the vector:

double sum = x.Sum();

Or to calculate the arithmetic mean:

double average = x.Average();

The same lambda expression allows us to find the maximum value in the vector:

double max = x.Max();

Or the minimum value of vector:

double min = x.Min();

we may even turning the vector on « List » to search and find the position in the vector  of the both values « min » and « max » ;

int position = x.ToList () .IndexOf (min.);

position = x.ToList () .IndexOf (max.);

The term « lambda » also helps manage elegantly and mass conversion of the values contained in the vector from one type to another.

We can easily convert double values in the vector « x »  to values of type « float » or « int » or « short » ..

We can calculate the sum of the values contained in the vector as if they were of type int32 , operating conversion and performing the addition with the lambda expression

int  int_sum = x.Select (b => System.Convert.ToInt32 (b)) Sum ();

A line of code using the command « Cast » will not work generating aerror  of type « system invalid cast exception. »

int  int_sum = x.Cast () Sum ();

with the lambda expression more advanced arithmetic  operations can be done on the values of the vector.

One can for example raise the values of the vector to the second power, determining the amount, and then divide the number by  the vector length.

All these operations take place in a single line of code

double y= x.Select(b => b * b).Sum() / x.Length;

Other uses of the lambda expression make use of words such as « next » and « index ».

This is the case if one wants to operate an accumulation on a sequence of values in the vector by using the « aggregate » function.

double yy1 = x.Where(b=> b> 0.5).Aggregate((b, next) => next + b);

When you start the program you would notice that the variable « yy » is equal to the variable « sum » and we have done nothing more than to calculate the sum of values in a different way.

But the aggregate function can regain its usefulness when using it with another statement such as « where » for example.

It will be possible soon when we calculate the sum of certain values chosen according to a specific criterion.

Code Sample:

double yy1 = x.Where(b=> b> 0.5).Aggregate((b, next) => next + b);

Checking result you would notice that only values greater than 0.5 were taken into consideration in calculating the sum.

The word « next » is not a keyword. It can be replaced in the previous line of code with the word « index » without   any results changing.

double yy2 = x.Where(b => b > 0.5).Aggregate((b, index) => index + b);

Truly the word « next » or « index » can be just as easily replaced by any other word such as « suivant » or even « cat » 🙂  without any kind of compiler protestation .

And  here is the source code of the examples given

private void sample ()

{
double []x = new double [100];

System.Random t = new Random();
x = x.Select(b => b = t.NextDouble()).ToArray();
double sum = x.Sum();
double average = x.Average();
double max = x.Max();
double min = x.Min();
int position = x.ToList().IndexOf(min);
position = x.ToList().IndexOf(max);

//generating error invalid cast exception
//int int_sum= x.Cast<int>().Sum();

double y= x.Select(b => b * b).Sum() / x.Length;

double yy1 = x.Where(b=> b> 0.5).Aggregate((b, next) => next + b);
double yy2 = x.Where(b => b > 0.5).Aggregate((b, suivant ) => suivant + b);

double yy2 = x.Where(b => b > 0.5).Aggregate((b, cat) => cat + b);
}

(31)

Sudoku: determiner les chiffres candidats en c#

 

sudoku : determiner les chiffres candidats en C# -2

par Ettougourti Mohamed Ali

Deux fonctions ont été nécessaires pour remplir une case sudoku de candidats possibles.

Nous listons ci-dessous la fonction controlvalid2 et la fonction getregion. (voir article précédent du même auteur)

Vous remarquerez que dans l’écriture des trois fonctions (setcandidates, controlvalid2 et getregion) la programmation est restée très basique puisque nous avons abusé de « for » et « next » et autres boucles while alors que comme nous allons le découvrir le c sharp offre bien d’autres possibilités de programmation beaucoup plus puissantes et performantes.

private int Controlvalid2(int i, char c)

{

int j = i;

while (j % 9 != 0) j–;

int k = j + 9;

for (; j < k; j++)

if (cells[j].c == c) {   return -1; }

j = i;

while (j >= 0) j -= 9;

j += 9;

k = j + 73;

for (; j < k; j += 9)

{

if (cells[j].c == c) {   return -1; }

}

int r = getregion(i); // chercher le centre du  petit carré

for (j = 0; j < 9; j++)

{

if (cells[r – 10].c == c ||

cells[r – 9].c == c ||

cells[r – 8].c == c ||

cells[r – 1].c == c ||

cells[r – 0].c == c ||

cells[r + 1].c == c ||

 

cells[r + 8].c == c ||

cells[r + 9].c == c ||

cells[r + 10].c == c)

{

return -1; }

}

return 1;

}

Rappelons que controlvalid2 collecte les chiffres dans chaque ligne et dans chaque colonne ou se trouve la case à remplir de candidats potentiels, elle fait aussi appel à getregion pour collecter les chiffres du petit carré, une fois tous les chiffres rassemblés elle peut accepter ou rejeter le chiffre proposé passé en paramètre c.

En montant à un niveau plus difficile on peut reprendre la fonction controlvalid pour en faire une fonction plus performante et plus concise.

Il s’agit de faire appel aux fonctions lambda introduites dans c# qui facilitent énormément le maniement des tableaux.

Pour chercher toutes les cases comportant un chiffre introduit par le joueur ou posé comme contrainte se trouvant sur la même ligne et sur la même colonne que notre case à remplir on utilise une seule instruction.

L’array  ou le tableau cells de 81 élements (9*9) est utilisé comme une liste qu’on peut interroger à l’aide de l’instruction « where ». le resultat de la recherche est stocké dans une liste de caractères ch grâce à l’instruction select,  pour effacer les doublons on utilise l’instruction distinct à la fin de l’expression lambda.

List<char> ch = cells.Where((b, index) => (index / 9 == l || index % 9 == col)   &&  cells[index].c != (char)’X’).Select(b => b.c).Distinct().ToList();

À la structure cell nous ajoutons deux fonctions qui nous donnent la colonne et la ligne de la case i. une autre fonction nous retourne le centre du petit carré auquel appartient la case à remplir de chiffres candidats.

La nouvelle structure a désormais la forme suivante :

public struct cell

{

public Point p;

public int width;

public int height;

public int val;

 

public char c;

public bool iscontrainte;

public char[]candidates;

public int nbcandidates;

public int getline (int i)

{

return i / 9;

}

public int getcol(int i)

{

return i % 9;

}

 

public int getcenterregion (int i)

{

int col= i % 9;

int l= i / 9;

switch (col)

{

case 1:

case 4:

case 7:

if (l == 1 || l == 4 || l == 7) return i;

break;

 

}

if (col >= 6) col = 7;

else if (col >= 3) col = 4;

else col = 1;

if (l >= 6) l = 7;

else if (l >= 3) l = 4;

else l = 1;

return (l * 9) + col;

 

}

}

La nouvelle fonction controlvalid4 réécrite est listée ci-dessous

private char[] controlvalid4 (int i)

{

if (cells[i].iscontrainte == true || cells[i].c != ‘X’)

return null;

//definir les cases de la région par rapport au centre 

int[] v = new int [9] { -10, -9, -8, -1, 0,1,8,9,10 };

//definir les chiffres legaux

char[] cc = new char[9] { ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ };

     //trouver la ligne

int l = cells[i].getline(i);

//trouver la colonne

int col = cells[i].getcol(i);

  //trouver les chiffres enregistrés dans toutes les cases de la //même ligne et de la même colonne

            // qui ne sont pas libres ne comportant pas un ‘X’ en guise de //chiffre tout en évitant les doublures

            //le tout enregistré dans une nouvelle liste   ch

       List<char> ch = cells.Where((b, index) => (index / 9 == l || index % 9 == col)

&& cells[index].c != (char)’X’).Select(b => b.c).Distinct().ToList();

//retourner null si aucune occurrence n’a été trouvée

if (!ch.Any()) return null;

   //aprés avoir calculé le centre du petit carré j

            // nous ajoutons toutes les valeurs de la région

            // à la liste ch 

int j = cells[i].getcenterregion(i);

for (int k = 0; k < 9; k++)

{

if(cells[j+ v[k]].c != (char)’X’)

ch.Add(cells[j + v[k]].c);

}

// nous disposons désormais d’une liste (ch) de tous

            //les chiffres illégaux pour notre case

            // et d’une autre (cc) de tous les chiffres légaux

ch = ch.Distinct().ToList(); // éviter de reproduire les chiffres //plus qu’une fois

//soustraire les chiffres illégaux de la liste des chiffres légaux

cc = cc.Except(ch.ToList()).ToArray();

return cc;

}

Vous remarquez que la nouvelle fonction prend désormais un seul paramètre i qui est l’index de la case.

 




(95)

ecrire un programme wavtomidi en c#

ecrire un programme wavtomidi en c#

Par Ettougourti Mohamed Ali

 si nous voulons écrire un programme simple en c# pour convertir 
un fichier wav en midi nous devons commencer par 
 1- identifier la source audio.
fichier audio préalablement crée et enregistré ou au contraire une conversion en temps réel au fur et à mesure de la progression du son.
2-identifier le procédé de transformation du son.
autocorrélation , fast fourrier transform ou fft , cepstrum,
etc..
3- écrire les résultats dans un fichier midi.

pour écrire notre programme nous avons fait les choix suivants:
-utiliser des fichiers wav enregistrés préalablement.
-utiliser l'autocorrélation pour convertir le son en fréquences.

nous aurons donc besoin de routines pouvant traiter les différentes parties composant notre programme.

-lire un fichier wave
-transformer les données audio en fréquences.
-convertir les fréquences en notes musicales.
1 étape : lire un fichier wav:
Nous commençons par définir sur un formulaire 5 labels pour recevoir respectivement le nom du fichier wav sélectionné,
  le taux d'echantillonnage , le nombre de bits par sample : 8,16,24, 32.
le nombre de canaux :1  pour mono , 2 pour stéréo.
un 4 label pour déterminer la durée du morceau.
sur ce même formulaire nous ajoutons un menu avec une premiére commande :ouvrir fichier wav.
nous définissons enfin une fonction privée void dont le nom est ouvrirFichierWavToolStripMenuItem, fonction générée automatiquement par le visual studio.

et dont voici le listing
private void ouvrirFichierWavToolStripMenuItem_Click(object sender, EventArgs e)
        {
System.IO.FileStream s; byte[] buf; int fs; int bit; int channel; int fsize; int fsize2; int fsize3; float duree;
            OpenFileDialog op;
/* créer et configurer la boite de dialogue ouvrir fichier */
           op = new OpenFileDialog();  
            op.DefaultExt = "wav"; 
            op.FileName = "*.wav";
            op.InitialDirectory = "c:\\wave\\";
/*remplacer le repertoire par votre repertoire wav */
//afficher la boite de dialoge ouvrir fichier
            op.ShowDialog();
/*instancier le buffer de réception de l’entête du fichier wav en buf */
            buf = new byte[44];
/* créer le flux fichier s en récupérant le nomdu fichier sélectionné */
             s = new System.IO.FileStream(op.FileName , 
System.IO.FileMode.Open);
*/ lire l’entête les 44 premiers bits */
            s.Read(buf, 0, 44);
/* taux d’échantillonnage */
            fs = BitConverter.ToInt16(buf, 24);
/*nombre de canaux */
            channel = buf[22];
/* nombre de bits par sample */
            bit = buf[34];
/* taille du fichier en utilisant la fonction Seek */
             fsize = (int) s.Seek(0, System.IO.SeekOrigin.End);
/* 2 methode pour obtenir la taille du fichier en lisant les 4 premiers bits */
             fsize2 = BitConverter.ToInt32(buf, 4);
/* 3 methode pour obtenir la taille du fichier en lisant les derniers 4 bits */
             fsize3 = BitConverter.ToInt32(buf, 40);
/* récupérer la durée du son audio en divisant la taille du fichier par le taux d’echantillonnage multiplé par le nombre de bits par sample et par le nombre de canaux */
            duree = fsize3 / (fs *bit/8*channel);
/* convertir la durée en minutes */
            duree /= 60;
/* fermer le flux */
            s.Close();
/* afficher les paramétres du fichier audio sur le formulaire */
/* afficher les résultats obtenus */
            label1.Text = op.FileName ;
            label2.Text = "frequency sampling  "+ fs.ToString();
            label3.Text ="bit  "+ bit.ToString ();
            label4.Text ="channel  "+ channel.ToString ();
            label5.Text ="duree  "+ duree .ToString ();
        }
        }
    }

(609)