25 abr 2011

Convertir Número a Letras en C#

Cuando se realizan trabajos donde se necesita mostrar al cliente un determinado monto de dinero, tipo factura, recibo, cheque, etc, el cliente desea ver el monto en numeral asi como en literal.

Por ejemplo:

877866,50 = ochocientos setenta y siete mil ochocientos sesenta y seis 50/100 Bolivianos
Pues bien, la siguiente clase a la que llame NumLetra.cs realiza justamente esa operacion, esta extracomentada y trate de hacerla lo mas entendible posible. El proyecto en C#, lo llame con_NumLetraC

La logica que se utliza es la siguiente:

La clase recibe un numero ej. 123456789,50
valida este numero, si el numero no es valido devuelve NULL
Si el numero es valido segun sea este unidad, decena, centena, mil o millon,  va clasificando el numero y llama a sus procedimientos correspondientes, estas funciones, son utilizadas en cascada, osea:
nuestro numero de ejemplo es 123456789,50, entonces separa en 123456789 y 50, siendo 50 nuestra parte decimal.

El  numero entero, 123456789 es clasificado = es millon, entonces llama a la funcion getMillones, esta funcion a la vez divide el numero en miles y millones
123456789 = 123 456789 donde 123 corresponde a millones y 456789 a miles
entonces la misma funcion llama a las funciones getMiles, getCentenas, getUnidades, segun corresponda, al igual que la funcion getMiles, hace uso de getCentenas, getDecenas getUnidades, lo mismo getCentenas, hace uso de getDececas, getUnidades.

Espero se entienda :)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace con_NumLetraC
{
    class NumLetra
    {
        private String[] UNIDADES = { "", "un ", "dos ", "tres ", "cuatro ", "cinco ", "seis ", "siete ", "ocho ", "nueve " };
        private String[] DECENAS = {"diez ", "once ", "doce ", "trece ", "catorce ", "quince ", "dieciseis ",
        "diecisiete ", "dieciocho ", "diecinueve", "veinte ", "treinta ", "cuarenta ",
        "cincuenta ", "sesenta ", "setenta ", "ochenta ", "noventa "};
        private String[] CENTENAS = {"", "ciento ", "doscientos ", "trecientos ", "cuatrocientos ", "quinientos ", "seiscientos ",
        "setecientos ", "ochocientos ", "novecientos "};

        private Regex r;
    
        public String Convertir(String numero, bool mayusculas) {
            
        String literal = "";
        String parte_decimal;    
        //si el numero utiliza (.) en lugar de (,) -> se reemplaza
        numero = numero.Replace(".", ",");
            
        //si el numero no tiene parte decimal, se le agrega ,00
        if(numero.IndexOf(",")==-1){            
            numero = numero + ",00";
        } 
        //se valida formato de entrada -> 0,00 y 999 999 999,00
        r = new Regex(@"\d{1,9},\d{1,2}");            
        MatchCollection mc = r.Matches(numero);
        if (mc.Count > 0) {
            //se divide el numero 0000000,00 -> entero y decimal
            String[] Num = numero.Split(',');                    
            
            //de da formato al numero decimal
            parte_decimal = Num[1] + "/100 Bolivianos.";
            //se convierte el numero a literal
            if (int.Parse(Num[0]) == 0) {//si el valor es cero                
                literal = "cero ";
            }
            else if (int.Parse(Num[0]) > 999999)
            {//si es millon
                literal = getMillones(Num[0]);
            }
            else if (int.Parse(Num[0]) > 999)
            {//si es miles
                literal = getMiles(Num[0]);
            }
            else if (int.Parse(Num[0]) > 99)
            {//si es centena
                literal = getCentenas(Num[0]);
            }
            else if (int.Parse(Num[0]) > 9)
            {//si es decena
                literal = getDecenas(Num[0]);
            } else {//sino unidades -> 9
                literal = getUnidades(Num[0]);
            }
            //devuelve el resultado en mayusculas o minusculas
            if (mayusculas) {                
                return (literal + parte_decimal).ToUpper();
            } else {
                return (literal + parte_decimal);
            }
        } else {//error, no se puede convertir
            return literal = null;
        }
    }
    
        /* funciones para convertir los numeros a literales */

        private String getUnidades(String numero)
        {   // 1 - 9            
            //si tuviera algun 0 antes se lo quita -> 09 = 9 o 009=9
            String num = numero.Substring(numero.Length - 1);            
            return UNIDADES[int.Parse(num)];
        }

        private String getDecenas(String num)
        {// 99                        
            int n = int.Parse(num);
            if (n < 10)
            {//para casos como -> 01 - 09
                return getUnidades(num);
            }
            else if (n > 19)
            {//para 20...99
                String u = getUnidades(num);
                if (u.Equals(""))
                { //para 20,30,40,50,60,70,80,90
                    return DECENAS[int.Parse(num.Substring(0, 1)) + 8];
                }
                else
                {
                    return DECENAS[int.Parse(num.Substring(0, 1)) + 8] + "y " + u;
                }
            }
            else
            {//numeros entre 11 y 19
                return DECENAS[n - 10];
            }
        }

        private String getCentenas(String num)
        {// 999 o 099
            if (int.Parse(num) > 99)
            {//es centena
                if (int.Parse(num) == 100)
                {//caso especial
                    return " cien ";
                }
                else
                {
                    return CENTENAS[int.Parse(num.Substring(0, 1))] + getDecenas(num.Substring(1));
                }
            }
            else
            {//por Ej. 099 
                //se quita el 0 antes de convertir a decenas
                return getDecenas(int.Parse(num) + "");
            }
        }

        private String getMiles(String numero)
        {// 999 999
            //obtiene las centenas
            String c = numero.Substring(numero.Length - 3);
            //obtiene los miles
            String m = numero.Substring(0, numero.Length - 3);
            String n = "";
            //se comprueba que miles tenga valor entero
            if (int.Parse(m) > 0)
            {
                n = getCentenas(m);
                return n + "mil " + getCentenas(c);
            }
            else
            {
                return "" + getCentenas(c);
            }

        }

        private String getMillones(String numero) 
        { //000 000 000        
            //se obtiene los miles
            String miles = numero.Substring(numero.Length - 6); 
            //se obtiene los millones
            String millon = numero.Substring(0, numero.Length - 6);
            String n = "";
            if (millon.Length > 1) 
            {
                n = getCentenas(millon) + "millones ";
            }
            else
            {
                n = getUnidades(millon) + "millon ";
            }
            return n + getMiles(miles);
        }

    }

}

 Esta clase, recibe  un numero de 0,00 a 999999999.00 en formato String, el separador decimal puede ser un punto (.) o una coma (,), ademas tiene un parametro booleano "mayusculas" el cual sea verdadero (true) o falso (false), retorna el resultado en mayusculas o minusculas, esta clase no acepta numeros negativos ni tampoco numero mayores o iguales a mil millones, aunque claro trate de escribir esta clase para que sea facilmente comprensible y asi pueda ser ampliado o modificado segun sus necesidades.

La forma de llamara a esta clase es:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace con_NumLetraC
{
    class Program
    {
        static void Main(string[] args)
        {
            NumLetra nl = new NumLetra();

            String numero = "57.60";            
            Console.WriteLine(nl.Convertir(numero,true));

            numero = "34557.70";
            Console.WriteLine(nl.Convertir(numero, false));

            numero = "4357,60";
            Console.WriteLine(nl.Convertir(numero, true));

            numero = "969.90";
            Console.WriteLine(nl.Convertir(numero, false));

            Console.ReadKey();
            
        }
    }
    
}

Y al ejecutar el proyecto tenemos:

20 abr 2011

Esquema de un compilador

El proceso de traducción de un lenguaje a otro que realiza un compilador se conoce como compilación.

El entorno en que se desarrolle el compilador y el lenguaje en que se implante puede afectar la velocidad y fiabilidad de la implantación del compilador.

La traducción de un lenguaje fuente de alto nivel a un programa ejecutable en lenguaje maquina suele implicar más de un paso de traducción. El paso mismo de compilación puede compernder de un cierto numero de pasos que traducen progresivamente el lenguaje a varias formas intermedias antes de producir el programa objeto final.
 (Imagen 1: Esquema de un compilador)
 (Imagen 2: Fases de un compilador)
 Imagen 3: Analisis y Sintesis

9 abr 2011

Paso de parametros entre paginas en ASP.Net

Para poder pasar parametros en diferentes paginas web, se puede utilizar el metodo de VS PostBackURL, para este ejemplo partiremos del siguiente sitio web "wbSample1" el cual consta de 2 paginas "Default.aspx" y "Default2.aspx"
Lo que harermos sera pasar un parametro de "Default.aspx" hacia "Default.aspx" utilizando PostBackURL.

Default.aspx consta de un objeto TextBox = TextBox1 y de un Button = Button1
Seleccionando el Button1, en sus propiedades se busca la opcion PostBackURL y se desplegara la ventana para seleccionar la pagina destino, como nuestro proyecto solo consta de dos paginas, es facilmente idetificable, se selecciona la pagina "default2.aspx" y OK
Eso es todo para el archivo "default.aspx", ahora se debe trabajar en el codigo de la pagina default2.aspx, en este ejemplo estamos utilizando el lenguaje Visual Basic

Ingresa en el codigo de default2.aspx en el Page Load  se debe escribir lo siguiente:

Partial Class Default2
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'si se carga esta pagina sin cargar previamente la primera sale "error"
        If Page.PreviousPage Is Nothing Then
            Label1.Text = "Error: Usted no debe estar aqui..."
        Else
            'Se toma el contenido del TextBox y se lo coloca en una variable
            Dim Nombre = CType((PreviousPage.FindControl("TextBox1")), TextBox).Text
            'si no existen datos muestra el primern mensaje
            If Nombre = "" Then
                Label1.Text = "Hola Anonimo bienvenido..."
            Else 'sino muestra el saludo con el nombre
                Label1.Text = "Hola " & Nombre & " bienvenido..."
            End If
        End If
    End Sub
End Class

Ahora solo ejecutamos el sitio web desde el servidor:

Vemos como se carga la pagina, pero esta primera vez no colocamos nada en el TextBox, y presionamos el Button, entonces se carga la segunda pagina, pero como el TextBox estaba vacio nos muestra este mensaje "Hola anonimo bienvenido...."
Para la segunda prueba, colocamos un nombre en el TextBox y presionamos el boton, esta vez si nos muestra el mensaje de bienvenida que queremos "Hola jc Mouse bienvenido..."

6 abr 2011

Problema "Sucesión de ULAM"

La siguiente se llama conjetura de ULAM en honor del matematico S.Ulam
  • Comience con cualquier entero positivo
  • Si es par, dividalo entre 2; si es impar, multipliquelo por 3 y agreguele 1.
  • Obtenga enteros sucesivamente repitiendo el proceso
Al final, obtendra el número 1, independientemente del entero inicial, Por ejemplo, cuando el entero inicial es 26, la secuencia será: 26,13,40,20,10,5,16,84,2,1.

Construya un diagrama de flujo y su codigo correspondiente que lea un numero entero positivo y obtenga e imprima la sucesion de ULAM (tambien conocido como Conjetura de Collatz)

Datos:
N, es una variable de tipo entero, que representa el número que ingresa.

Diagrama de Flujo


Codigo Fuente Visual Basic


Module problema_320

    Sub Main()
        Console.Write("Ingrese número : ")
        Dim N = Val(Console.ReadLine)
        If N > 0 Then
            Console.WriteLine(N)
            While N <> 1
                If (N Mod 2) = 0 Then
                    N = N \ 2
                Else
                    N = N * 3 + 1
                End If
                Console.WriteLine(N)
            End While
        Else
            Console.Write("N tiene que ser un entero positivo")
        End If
        Console.ReadLine()
    End Sub

End Module
Resultado

5 abr 2011

Problema "Rango de Calificaciones"

Se tiene las calificaciones de un grupo de alumnos que presentaron un examen de computación. Haga un diagrama de flujo y su respectivo programa que calcule e imprima cuantas calificaciones hay en cada uno de los rangos:
  • de 0 a 3.99
  • de 4 a 5.99
  • de 6 a 7.99
  • de 8 a 10

Datos: CAL1, CAL2, CAL3..... -1
donde CAL es una variable de tipo real, que representa la calificación del alumno, el fin de la introduccion de los datos esta dado por el valor -1

Diagrama de Flujo

donde RANGO1,RANGO2,RANGO3,RANGO4 son variables de tipo entero , son contadores, cuentan el numero de calificaciones que se encuentran entre los rangos dados respectivamente.

Codigo Consola Visual Basic


Module problema_320

    Sub Main()
        Dim RANGO1 As Integer = 0
        Dim RANGO2 As Integer = 0
        Dim RANGO3 As Integer = 0
        Dim RANGO4 As Integer = 0
        Dim CAL As Double

        Console.Write("Ingresa Calificacion [para terminar -1]: ")
        CAL = Val(Console.ReadLine)

        While CAL <> -1
            If CAL <= 3.99 Then
                RANGO1 = RANGO1 + 1
            Else
                If CAL <= 5.99 Then
                    RANGO2 = RANGO2 + 1
                Else
                    If CAL <= 7.99 Then
                        RANGO3 = RANGO3 + 1
                    Else
                        RANGO4 = RANGO4 + 1
                    End If
                End If
            End If
            Console.Write("Ingresa Calificacion [para terminar -1]: ")
            CAL = Val(Console.ReadLine)
        End While
        Console.WriteLine("0...3.99 = " & RANGO1)
        Console.WriteLine("4...5.99 = " & RANGO2)
        Console.WriteLine("6...7.99 = " & RANGO3)
        Console.WriteLine("8...10.0 = " & RANGO4)
        Console.ReadLine()
    End Sub

End Module



4 abr 2011

Problema "Aumento de Sueldos"

Construya un diagrama de flujo y codigo correspondiente tal que dado como dato el sueldo de un trabajador, calcule su aumento según el siguiente criterio:

  • SUELDO < 1000 BS   = AUMENTO DE 25%
  • SUELDO >= 1000 BS y <=1500 bs  = AUMENTO DE 21%
  • SUELDO > 1500 BS   = AUMENTO DE 18%

Imprima el nuevo sueldo del trabajador
Datos: SUELDO
donde Sueldo es una variable de tipo real, que expresa el sueldo del trabajador
DIAGRAMA DE FLUJO
Explicacion de variables
Sueldo: Variable de tipo real
nsueldo: variable de tipo real, Almacena el nuevo sueldo del trabajador con el aumento correspondiente

Codigo Consola Visual Basic

Module Module1

    Sub Main()
        Console.Write("Ingresa el sueldo: ")
        Dim sueldo = Val(Console.ReadLine)
        Dim nsueldo As Double
        If (sueldo < 1000) Then
            nsueldo = sueldo * 1.25
        Else
            If (sueldo <= 1500) Then
                nsueldo = sueldo * 1.21
            Else
                nsueldo = sueldo * 1.18
            End If
        End If
        Console.WriteLine("El nuevo sueldo es de: " & nsueldo)
        Console.ReadLine()
    End Sub

End Module
Resultado

2 abr 2011

Conexion ASP.NET y MySQL utilizando el archivo Web.config

Como se vio en un post anterior "Conexion ASP.NET y MySQL por codigo" donde se declaraba la cadena de conexion directamente en el codigo Visual Basic, tambien existe otra forma de declarar esta cadena de conexion en ASP.NET, y es utilizando o mejor dicho, editando el archivo Web.Config

¿Qué necesitamos?
  • Visual Estudio o Web Developer
  • Gestor de base de datos MySQL instalado
  • Conector MySQL y .NET (Connector/Net) instalado
  • Conocimientos de Visual Basic 
Antes de comenzar debemos tener una base de datos ya creada en MySQL,  para este tutorial se utiliza la base de datos dbSample o tambien puedes utilizar otra base de datos que se tenga en la PC.


base de datos: dbSample

create table PERSONA (
    p_id bigint(20) NOT NULL auto_increment primary key,    
    p_nombre Varchar(20) not null,
    p_paterno Varchar(20) not null,
    p_materno Varchar(20) null,
    p_direccion Varchar(100) null,
    p_telefono varchar(12) null    
);
Y se colocan algunos datos en la DataBase


insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Antonio','Bragueta','Suelta','Calle Imaginaria # 345','123-456-789');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Jesús','Están','Camino','Calle Imaginaria # 598','');
   
insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Margarita','Flores','del Campo','Calle Imaginaria # 989','878-998-565');
  
insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Rosa','Pechoabierto','Alinstante','Calle Imaginaria # 339','');
  
insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Emiliano','Salido','del Pozo','Av. Quete Importa s/n','888-298-565');
   
insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Dolores','Fuertes','De barriga','Av. Quete Importa #779','008-908-165');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Juan','Melo','Machuca','Calle Noseencuentra #721','098-334-212');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Pepe','Botella','Pepsi','Calle Hastaaqui # 344','634-334-212');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Aquiles','Meo','de la Torre','Calle Hastaaqui # 354','887-873-212');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Jose Luis','Lamata','Feliz','Calle Quelees # 354','887-334-212');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Jhonny','Melaslabo','Hoy','Calle Meperdi # 354','887-553-212');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Elsa','Bor','de Lencuentro','Calle Noesta # 454','044-123-202');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Tomas','Turbao','','Calle Hastaaqui # 9','817-334-112');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Lucho','Portuano','','Calle Hastaaqui # 443','002-334-443');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Benito','Camela','Suavecito','Av. Noesta # 143','343-334-443');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Paco','Mermela','','Av. Noesta # 143','343-334-443');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Ana','Liza','Melchoto','Av. Noesta # 143','343-334-443');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Cindy','Entes','','Av. MePerdi # 3','876-314-443');

insert into PERSONA( p_nombre , p_paterno , p_materno , p_direccion , p_telefono )
values('Monica','Galindo','','Av. Bolivia # 43','343-009-443');

Ya estamos listos para continuar:


1. Crea un nuevo proyecto del tipo ASP.NET Web Aplication
File -> New Project ->  ASP.NET Web Aplication
2. Añade la Referencia al Conector/NET de MySQL (Agregar/Quitar Referencia)
3. En Vista Diseño, busca y arrastra del ToolBox un Componente GridView a nuestra pagina default.aspx
3. Añade tambien un objeto Button, cambia su propiedad Text a "Cargar Datos de MySQL", puedes darle un formato a la tabla si quieres. Debes tener algo como esto:
Si ves el Source de los objetos podras advertir que los nombres (ID) del GridView es GridView1, y del Button s Button1, esto es importante para poder reconocer los objetos cuando se programe, se puede cambiar los nombres a ls objetos por cualquier otro, en esta ocasion se deja como esta.

Hasta aqui es practicamente lo mismo que se vio en el tutorial anterior, ahora continuemos con lo nuevo

4. Abre el archivo Web.config que esta en el Solution Explorer, doble clic sobre este o clic derecho Open
5. El archivo Web.config es un archivo XML donde se guarda toda la configuracion de una aplicación web. En la imagen de abajo puedes ver la parte correspondiente a la "Cadena de Conexion" encerrada en un recuadro

 Esta sentencia <connectionStrings&gt , debes reemplazar por :


 <connectionStrings>
    <add name="jcMouseConnectionString" 
         connectionString="server=SERVIDOR;user id=USUARIO;
                           password=CONTRASEÑA;persist security info=True;
                           database=BASE_DE_DATOS"
         providerName="MySql.Data.MySqlClient" />
  </connectionStrings>

Nuestro archivo Web.config quedaria entonces de la siguiente manera:

importante! Para identificar esta cadena de conexion desde codigo, se especifica su nombre con la etiqueta NAME

Hasta aqui terminamos con el archivo Web.config, continuemos ahora con codigo

6. Para ingresar al codigo, doble clic sobre el objeto Button en Vista Diseño, esto nos lleva a la pagina Default.aspx.vb


Se debe añadir el siguiente codigo



Imports MySql.Data.MySqlClient

Partial Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    End Sub

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        'se crea una conexion a la base de datos MySQL
        Dim connection As MySqlConnection
        connection = New MySqlConnection
        'se apunta a la cadena de conexion guardada en el archivo Web.config
        connection.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings("jcMouseConnectionString").ConnectionString
        'se abre la conexion
        connection.Open()
        'se ejecuta una consulta SQL
        Dim ComandoSQL As New MySqlCommand("Select * From persona", connection)
        Dim ds As New DataSet
        Dim da As New MySqlDataAdapter(ComandoSQL)
        da.Fill(ds)
        GridView1.DataSource = ds.Tables(0)
        GridView1.DataBind()
    End Sub
End Class

7. Como ultimo paso, guardamos todas las modificaciones y Clic derecho sobre vista diseño -> View in Browser.
Solo se ve el boton, esto es porque el GridView esta vacio, ahora presiona el boton
El fin?

1 abr 2011

Factorial en VB y C#

En un post anterior se vio el algoritmo para desarrollar una aplicacion para devolver el factorial de un numero, ahora se implementa ese algoritmo en VS en el lenguaje VB

El codigo para Consola en VB es:

Module Module1

    Sub Main()
        Console.Write("Ingresa N: ")
        Dim N = Val(Console.ReadLine)
        If (N >= 0) Then
            Dim Fact = 1
            If (N > 0) Then
                Do
                    Fact = Fact * N
                    N = N - 1
                Loop While N > 1
            End If
            Console.WriteLine("El Factorial es: " & Fact)
        Else
            Console.WriteLine("Error: no se puede continuar...")
        End If
        Console.ReadLine()
    End Sub

End Module


El Codigo para C#


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Factorial
{
    class Program
    {
        static void Main(string[] args)
        {            
            Console.Write("Ingrese N: ");
            int N =  int.Parse( Console.ReadLine() );            
            if( N>=0 ){
                int Fact = 1; 
                if( N > 0 ){
                    do{          
                        Fact = Fact * N;
                        N = N - 1;
                    }while(N>1);            
                }
            Console.WriteLine("El Factorial es: " + Fact);
            }else{
                Console.WriteLine("Error: No se puede calcular...");
            }
            Console.ReadKey();
        }
    }
}


Como se observa utilizamos dos lenguajes diferentes pero gracias al algoritmo unico y al diagrama de flujo y al pseudocodigo obtenido por este, puede escribirse en cualquiera de los lenguajes sin problemas, la logica es la misma, aunque entre uno y otro lenguaje existan algunas diferencias.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | cna certification