viernes, 29 de noviembre de 2019

227. Unir pdfs

En algunas ocasiones necesitamos manipular pdfs como desarrolladores en este caso una de las herramientas que mas nos ayuda es itextsharp, y es la que emplearemos en este caso.

El caso que presento yo tengo pdf, y estos se deben unir en un solo pdf mayor, para ello vamos ha hacer lo siguiente, primero, vamos a agregar la referencia a nuestro proyecto.




Ahora lo que vamos ha hacer es lo siguiente:

1. Vamos a crear un nuevo pdf
2. Vamos a abrir los pdf y a copiar su contenido el nuevo pdf
3. Cerramos el pdf

Así de sencillo.

Les dejo el código para hacer esto

using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UnirPdf
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> pdf = new List<string>();
            pdf.Add(@"C:\f\A.pdf");
            pdf.Add(@"C:\f\B.pdf");
            UnirPdf(pdf, @"C:\f\C.pdf");
        }

        public static void UnirPdf(List<string> archivos, string salida)
        {
            Document document = new Document();
            using (FileStream newFileStream = new FileStream(salida, FileMode.Create))
            {
                PdfCopy writer = new PdfCopy(document, newFileStream);
                if (writer == null)
                {
                    return;
                }
                document.Open();

                foreach (string archivo in archivos)
                {
                    PdfReader reader = new PdfReader(archivo);
                    reader.ConsolidateNamedDestinations();
                    for (int i = 1; i <= reader.NumberOfPages; i++)
                    {
                        PdfImportedPage page = writer.GetImportedPage(reader, i);
                        writer.AddPage(page);
                    }

                    PRAcroForm form = reader.AcroForm;
                    if (form != null)
                    {
                        writer.CopyDocumentFields(reader);
                    }

                    reader.Close();
                }
                writer.Close();
                document.Close();
            }
        }

    }
}


Felices lineas

miércoles, 27 de noviembre de 2019

226. Running Totals SQL Server

Existen casos en los que se requiere obtener la información de SQL pero en que la información del renglón actual depende del anterior, por ejemplo el caso de las entradas y salidas de un inventario, en el que no tengo el registro de existencia de manera permanente.

Veamos un ejemplo, tengo la siguiente tabla



Como se puede ver no tengo un total de existencia, para poder obtener este total vamos a usar un concepto que se llama running totals, para ello es muy importante que tengamos un campo que le de un orden a nuestra informacion, en este caso es el id, pero puede ser también una fecha.

El query que emplearemos es el siguiente:

  SELECT Entrada, Salida,
  SUM(Entrada - Salida) OVER(ORDER BY Id
     ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
          AS RunningTotal
  FROM suma

¿Qué es lo que hace? Ejecuta la suma pero tomando en cuenta el valor del renglón precedente.

si ejecutamos el query obtenemos



En donde se ve que el nuevo valor nos muestra el total de nuestro inventario


Felices lineas

miércoles, 13 de noviembre de 2019

225. Xamarin Toolbar (II)


Continuemos con la construcción de nuestra barra de acciones, esta vez es momento de agregar botones (para eso queremos el menu) y acciones a estos.

El proceso es realmente sencillo:

1. Agreguemos un nuevo recurso, de tipo xml en la carpeta llamada menu


2. Ahora establezcamos que es lo que contendrá el menu, en mi caso yo coloque lo siguiente:


<?xml version="1.0" encoding="UTF-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

<item
android:id="@+id/Informacion"
android:icon="@drawable/ic_launcher"
app:showAsAction="ifRoom"
android:title="Info"/>

<item
android:id="@+id/menuof1"
app:showAsAction="never"
android:title="Menu 1"/>

<item
android:id="@+id/menuof2"
app:showAsAction="never"
android:title="Menu 2"/>

    <item
android:id="@+id/menuof3"
app:showAsAction="never"
android:title="Menu 3"/>

</menu>

¿Que hace?

<item
android:id="@+id/Informacion"
android:icon="@drawable/ic_launcher"
app:showAsAction="ifRoom"
android:title="Info"/>

Establece un icono, de acceso a una acción, aquí es muy importante el indicar la propiedad que se encuentra en negrita, eso nos permite que siempre se muestre en la barra.

<item
android:id="@+id/menuof1"
app:showAsAction="never"
android:title="Menu 1"/>

<item
android:id="@+id/menuof2"
app:showAsAction="never"
android:title="Menu 2"/>

    <item
android:id="@+id/menuof3"
app:showAsAction="never"
android:title="Menu 3"/>

Crea un conjunto de menus, dentro del menu con los tres puntos.

3. Ahora es necesario que este menu se muestre dentro del layout, para ello vamos a agregar a nuestro activity el siguiente código:

        public override bool OnCreateOptionsMenu(IMenu menu)
        {
            MenuInflater.Inflate(Resource.Menu.menutool, menu);
            return base.OnCreateOptionsMenu(menu);
        }

4. Por ultimo tenemos que asignar una acción a cada uno de los botones

        public override bool OnOptionsItemSelected(IMenuItem item)
        {
            string textToShow;

            if(item.ItemId == Resource.Id.Informacion)
            {
                textToShow = "Informacion";
            }
            else
            {
                textToShow = "Menu XX";
            }

            Android.Widget.Toast.MakeText(this, item.TitleFormatted + ":" + textToShow,
                Android.Widget.ToastLength.Long).Show();

            return base.OnOptionsItemSelected(item);
        }
   
Al probar en el emulador





Felices lineas

El Alien de México

224. Xamarin ToolBar (I)

Haremos un breve tutorial de Xamarin para Android, la mision poner una barra de actividades en la parte superior, otra en la parte inferior, y que estas puedan activar el menu.

Para hacer eso, debemos hacer lo siguiente:

Primero vamos a sustituir la barra de actividades, por una que tenga mucho mayor funcionalidad para esto es necesario que instalemos el siguiente paquete de nuget.



Vamos a agregar un nuevo estilo


Abrimos el archivo, y agregamos lo siguiente:

    <style name="AppBarra" parent="Theme.AppCompat">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="colorPrimary">#F6F6AA</item>
    </style>

Con esto vamos a quitar el Action Bar predeterminado, y podremos colocar el nuestro,

Ahora vamos a crear nuestro layout


Y agregaremos lo siguiente


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/actionBarSize"
    android:background="?android:attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</LinearLayout>

Con esto estamos agregando el nuevo toolbar

Ahora creemos el Activity que le dará vida a nuestro toolbar

Agregemos el siguiente código:


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

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;

namespace MenuTool
{
    [Activity(Label = "Menuly", MainLauncher = true, Theme = "@style/AppBarra")]
    public class Menuly : AppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            SetContentView(Resource.Layout.Menuly);

            var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            SetSupportActionBar(toolbar);
            SupportActionBar.Title = "Titulo!!!";

            // Create your application here
        }
    }
}

El código, aplica un tema, y busca la nueva toolbar, para poder comenzar a manipularla, si ejecutamos nuestro código tendremos lo siguiente:






El Alien de México



lunes, 21 de octubre de 2019

223. RMySQL (Mac)

En el post anterior vimos como poder instalar RMySQL en R para windows, sin embargo para el caso de MAC las cosas cambian un poco, esto debido a que el autor de RMySQL no incluye el compilado para MAC, por lo que es necesario compilarlo dentro de R.

¿Cuál es el inconveniente?, necesitamos tener instalado MySQL de manera local, ya que tendremos que usar algunas librerías del mismo.

para ello haremos lo siguiente, desde una consola, ejecutamos:


ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


con esto intalamos homebrew que nos ayudara a instalar mysql


brew install mysql


Con esto instalamos mySQL

Ahora desde RStudio damos de alta 2 rutas de bibliotecas

y posteriormente, instalar el paquete, observemos que este se instala como source, por que se compilara


a partir de este punto, se emplea igual que en el post anterior


Felices lineas

222. RMySQL (Windows)

R es una herramienta muy usada para el analisis de datos, en muchas ocaciones estos datos no los tenemos en otras bases como es el caso de MySQL, para poder usar una base de MySQL desde R, es necesario hacer lo siguiente:

1. Instalar el paquete RMySQL


2. Cargar la libreria RMySQL


3. Utilizarla

Para conectarnos a la base de datos se emplea la siguiente instrucción:

mydb = dbConnect(MySQL(),user='[ususario]',password='[password]',dbname='[Base]',host='[Ip]')

¿que podemos hacer?

dbListTables(mydb)

Nos lista las tablas de la base de datos

dbListFields(mydb,"[tabla]")

Obtenemos los campos de la base de datos

> rs = dbSendQuery(mydb,"select * from [Tabla]")
> data = fetch(rs,n=-1)

Cargamos la información para poder emplearla


Felices lineas




domingo, 13 de octubre de 2019

221. Importar csv a mysql

Si bien existen herramientas que permiten importar datos, la forma mas sencilla de hacer esta carga es hacerla desde el mismo servidor con la siguiente intrucción:



 LOAD DATA LOW_PRIORITY LOCAL INFILE '[ruta].csv' REPLACE INTO TABLE [tabla] CHARACTER SET latin1 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' IGNORE 1 LINES;

Es importante tener en cuenta que la tabla debe existir previo a la inserción de datos.

Es importante que el archivo csv se encuentre en la misma ruta del servidor para que esta carga sea lo mas rápido posible


Felices lineas

220. 7zip en Linux

7zip ha probado ser una de las mejores herramientas para compresión de archivos, ¿Cómo descomprimo un archivo de 7zip en linux?

El proceso es sencillo, primero necesitamos instalar 7 zip en linux para esto seguimos la siguiente instrucción:

sudo apt-get install p7zip-full p7zip-rar

¿Como comprimimos?

 7z a [archivo_salida] [Ruta_archivos]

¿Como descomprimimos?

7z e [Ruta_archivo_comprimido]


Felices lineas

domingo, 6 de octubre de 2019

219. 2019-10-06T23:17:14.967072Z mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists.

El error


2019-10-06T23:17:14.967072Z mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists.

Al iniciar MySQL en modo seguro

sudo mysqld_safe --skip-grant-tables &


se soluciona creando la ruta que solicita el sistema de forma manual

sudo mkdir -p /var/run/mysqld

sudo chown mysql:mysql /var/run/mysqld

218. World-writable config file '/etc/mysql/docker-default.d/my.cnf' is ignored

Este error ocurre al estar trabajando con mySQL en Linux, al iniciar mySQL, se obtiene este error

World-writable config file '/etc/mysql/docker-default.d/my.cnf' is ignored

el error se debe a que el archivo no cuenta con los permisos adecuados, por lo que en la ruta

/etc/mysql

se debe ejecutar:

chmod 0444 my.cnf


Felices lineas