Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Media aritmetica, geometrica si hiperbolica a trei valori reale

Sa se afiseze media aritmetica, geometrica si hiperbolica a trei valori reale.

Analiza Programului

Media aritmetica a unui set de variabile este suma acestora impartita la numarul lor.
Media geometrica se aplica numerelor reale pozitive. Se calculeaza produsul numerelor (numarul numerelor este n), apoi se extrage radicalul de ordin n.
Media hiperbolica sau media armonica se aplica numerelor reale diferite de zero.

    class Program
    {
        static void Main(string[] args)
        {
            double a, b, c;
            Console.WriteLine("Introduceti primul numar");
            
            if(!Double.TryParse(Console.ReadLine(), out a))
                throw new FormatException("Format incorect");
            
            Console.WriteLine("Introduceti al doilea numar");
            if (!Double.TryParse(Console.ReadLine(), out b))
                throw new FormatException("Format incorect");

            Console.WriteLine("Introduceti al treilea numar");
            if (!Double.TryParse(Console.ReadLine(), out c))
                throw new FormatException("Format incorect");

            Console.WriteLine("Media aritmetica a celor trei numere este: {0}", (a+b+c)/3);

            double prod = a * b * c;
            if(prod < 0)
                Console.WriteLine("Media geometrica se aplica doar pentru numere pozitive");
            else
                Console.WriteLine("Media geometrica a celor 3 numere este {0}",  Math.Pow(prod, (1.0/3)));

            if (a == 0 || b == 0 || c == 0)
                Console.WriteLine("Nu se poate calcula media hiperbolica");
            else
                Console.WriteLine("Media hiperbolica a celor 3 numere este {0}", 3/(1.0/a+1.0/b+1.0/c));
            
            Console.ReadLine();
        }
    }

Extract Method

De multe ori, ca sa intelegi un cod pe care il “mostenesti” sau il preiei dintr-o aplicatie, ajungi sa faci ceea ce se cheama refactoring. Ca o scurta definitie, refactoring-ul reprezinta o restructurare ce nu va schimba comportamentul software-ului, in mod vizibil. El inseamna o “curatare” a codului intr-o maniera eficienta si organizata, o serie de schimbari care va ajuta la o mai buna intelegere a codului si la identificarea unor bug-uri nedescoperite.

Continue reading

Deep copy in C#

Copierea datelor este una dintre cele mai comune actiuni in programare. O metoda de copiere a fost prezentata in articolul Shallow copy.
O alta metoda de copiere o reprezinta deep copy. Deep copy reprezinta o modalitate de a clona un obiect. Deep copy va creea o copie a unui obiect in acelasi mod in care o face si shallow copy, cu deosebirea ca deep copy va face o copie separata pentru fiecare camp de tip referinta, din obiectul original. Implementarea acestei metode, in C#, poate fi scrisa astfel:

using System;

namespace DeepCopy
{
    class Program
    {
        /// <summary>
        /// Clasa Student
        /// </summary>
        class Student
        {
            public string Name { get; set; }

            public Info Info { get; set; }

            public Student DeepCopy()
            {
                //obtine o copie a membrilor obiectului
                var other = (Student)this.MemberwiseClone();
                //pentru tipul referinta, copiaza obiectul referintiat
                other.Info = new Info(other.Info.Id);

                return other;
            }
        }

        /// <summary>
        /// Clasa Info
        /// </summary>
        class Info
        {
            public int Id { get; set; }

            public Info(int id)
            {
                Id = id;
            }
        }

        static void Main(string[] args)
        {
            //creeaza un obiect
            var s = new Student();
            s.Name = "Marius";
            s.Info = new Info(10);

            //creeaza o copie 
            var s2 = s.DeepCopy();

            //va afisa Marius
            Console.WriteLine(s2.Name);
            //va afisa 10
            Console.WriteLine(s2.Info.Id);

            //modific valoarea obiectului
            s.Name = "Bogdan";
            s.Info.Id = 100;

            //va afisa Marius
            Console.WriteLine(s2.Name);
            //va afisa 10
            Console.WriteLine(s2.Info.Id);

            Console.ReadLine();
        }
    }
}

Deep copy mai poate fi implementata prin serializare sau cu ajutorul interfetei ICloneable.

Shallow copy in C#

Una din metodele pentru copierea unui obiect o reprezinta shallow copy. Ea consta in crearea unui nou obiect si copierea membrilor, care nu sunt statici, ale obiectului curent catre un nou obiect.
Clasa Object contine o metoda de tip protected numita MemberwiseClone.
In cazul in care campurile sunt de tip valoare, copierea are loc bit cu bit, acesta fiind cel mai fericit caz. In cazul in care campurile sunt de tip referinta, referinta este copiata, dar obiectul referentiat, nu. Exemplu:

using System;

namespace MemberWiseExample
{
    /// <summary>
    /// Clasa Student
    /// </summary>
    class Student
    {
        public string Name { get; set; }

        public Info Info { get; set; }

        public Student ShallowCopy()
        {
            return (Student)this.MemberwiseClone();
        }
    }

    /// <summary>
    /// Clasa Info
    /// </summary>
    class Info
    {
        public int Id { get; set; }

        public Info(int id)
        {
            Id = id;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //se creeaza un obiect de tip Student
            Student s = new Student ();
            s.Name = "Marius";
            s.Info = new Info(1);
           
            //se creeaza un obiect de tip student prin copia primului obiect
            Student s2 = s.ShallowCopy();
           
            //Marius
            Console.WriteLine(s2.Name);
            //1
            Console.WriteLine(s2.Info.Id);

            s.Name = "Bogdan";

            //Bogdan
            Console.WriteLine(s.Name);
            //Marius
            Console.WriteLine(s2.Name);

            s.Info.Id = 34;
            
            //34
            Console.WriteLine(s.Info.Id);
            //34
            Console.WriteLine(s2.Info.Id);

            Console.ReadLine();
        }
    }
}

Shallow copy mai este denumita si memberwise copy. Se recomanda pentru cresterea performantei si in conditiile in care obiectul nu are membri care se modifice frecvent.

log4net

Log4net este o biblioteca open-source folosiat de programatorii in .Net pentru afisarea/inregistrarea informatiilor legate de aplicatia la care lucreaza. Este utila pentru identificarea problemelor prin crearea unor inregistrari la runtime. Log4net nu influenteaza performanta. Este suportat de mai multe framework-uri si are un mecanism simplu pentru inregistrarea informatiilor catre mai multe tipuri de surse: consola, fisier, buffer de memorie, etc. Exista 5 nivele sau 5 categorii de informatii: Debug, Information, Warnings, Error, Fatal.

Destinatia unde va ajunge informatia pe care o dorim inregistrata se numeste Appender. Configurarea acestuia se face intr-un fisier XML, ca in exemplul urmator:

<configuration>
  <startup>
    <supportedRuntime version="v2.0.50727"/>
    <log4net>
      <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
        <layout type="log4net.Layout.PatternLayout">
          <param name="Header" value="[Header]\r\n" />
          <param name="Footer" value="[Footer]\r\n" />
          <!-- data (%d), timp (%t), nivel (%p), nume logger (%c), mesaj (%m)-->
          <param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
        </layout>
      </appender>
      <!--Appender-ul radacina in care specificam nivelul de informatii si appender-ul folosit-->
      <root>
        <level value="INFO" />
        <appender-ref ref="ConsoleAppender" />
      </root>
    </log4net>
  </startup>
</configuration>

Un cod simplu pentru care functioneaza logger-ul este acesta:

using System;
using log4net;
using log4net.Config;

namespace LogTest
{
    class Program
    {
        //se declara si se creeaza logger-ul
        private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            //initializarea log4net
            BasicConfigurator.Configure();

            //exemplu
            Logger.Debug("Informatii despre depanare.");
            Logger.Error("Informatii despre erori.");

            Console.ReadLine();
        }
    }
}

Log4net se poate descarca de pe logging.apache.org.

DotNetZip

Exista pe codeplex o biblioteca ce poate fi descarcata si folosita in mod gratuit si care permite arhivarea/dezarhivarea fisierelor si directoarelor. DotNetZip poate crea, citi, extrage sau actualiza arhive .zip.

Un exemplu de cod pentru crearea unui arhive in cadrul unui scenariu de backup:

using System;
using Ionic.Zip;

namespace ZipFolder
{
    class Program
    {
        static void Main(string[] args)
        {
            string applicationFolderPath = @"C:\Marius";

            try
            {
                Console.WriteLine(String.Format("Se incearca crearea unui backup pentru fisierele din directorul- {0}", applicationFolderPath));
                using (var zip = new ZipFile())
                {
                    zip.AddDirectory(applicationFolderPath);
                    zip.Save(applicationFolderPath + "\\Backup.zip");
                    Console.WriteLine(String.Format("Backup efectuat cu succes. Arhiva: {0} ", zip.Name));
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Eroarea la arhivarea fisierelor de backup" + ex.Message);
            }

            Console.ReadLine();
        }
    }
}

O singura instanta a aplicatiei

Presupunem ca ne dorim ca aplicatia la care lucram sa ruleze intr-o singura instanta. Pentru a nu permite utilizatorilor sa creeze mai mult de o instanta pentru aplicatie, vom folosi clasa Mutex din namespace-ul System.Threading. Clasa Mutex permite accesul exclusiv la o resursa partajata intre mai multe procese, pentru un singur thread. Acest lucru diferentiaza obiectele Mutex fata de obiectele Monitor.

using System;
using System.Threading;
using System.Windows.Forms;

namespace SingleInstance
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            bool createdNew = false;

            //numele unic al aplicatiei
            Mutex mutex = new Mutex(true, "SingleInstamce", out  createdNew);

            if (createdNew)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
            }
            else
            {
                MessageBox.Show("Aplicatia este deja pornita");
            }
        }
    }
}