domingo, 10 de julio de 2016

Dibujando Figuras Geométricas en PL/SQL

Que mejor diversión que programar un poco en tu tiempo libre no?
      Definitivamente trae mucha felicidad...

_____________________________________________________________________________________
Yo sin nada que hacer decidí hacer algo de arte. Vamo allá:

--- SCRIPT1:
SET SERVEROUTPUT ON /*para que se muestre en pantalla el resultado de la función "PUT_LINE" del paquete "DBMS_OUTPUT"*/
--STAGE ONE
DECLARE -- declaro las variables que usare
 V_CANTIDAD 
NUMBER(2);
 V_PRINT_LINE 
VARCHAR2(100);
BEGIN
 V_CANTIDAD := 10;  -- inicializo mis variables
 FOR 
I IN 1..V_CANTIDAD LOOP -- mi bucle que genera las líneas
  V_PRINT_LINE := 
RPAD(' ',I,'@');  /*RPAD rellena a la derecha(agregamos la --cantidad de "I" veces el caracteres "@" a la derecha de "' '")*/
  DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE);
 /* muestro la variable: "V_PRINT_LINE" llenada con la instrucción anterior*/
 END LOOP;

 FOR E IN REVERSE 1..
V_CANTIDAD-1 LOOP /*bucle en reversa para generar las líneas hacia abajo*/
  V_PRINT_LINE := RPAD(' ',E,'@');

  DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE);
 END LOOP;
END;
---OUTPUT:













_____________________________________________________________________________________
--- SCRIPT2:
--STAGE TWO -- figura anterior pero al revés
DECLARE
 V_CANTIDAD NUMBER(2);
 V_PRINT_LINE VARCHAR2(100);
 V_COUNT NUMBER(2); -- entiendo que esta variable me facilita las cosas, por eso la declare
BEGIN
 V_CANTIDAD := 10;
 V_COUNT := 0;
 FOR E IN REVERSE 1..V_CANTIDAD LOOP /*otro bucle en reversa para generar las líneas*/
  V_COUNT := V_COUNT+1; -- esta variable aumenta, contrario a "I" que disminuye
  V_PRINT_LINE := LPAD('@',E,'_')||RPAD('@',V_COUNT-1,'@');
  /*en el paso anterior relleno la variable "V_PRINT_LINE": LPAD('@',e,'_') agrega el carácter: "_" la cantidad de "E" veces a
 la izquierda del carácter "@"; y ||RPAD('@',v_count-1,'@') agrega la cantidad de "v_count-1" veces el carácter "@" a la derecha del carácter "@"*/
  DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE); -- muestra: "V_PRINT_LINE"
 END LOOP;
 ---------------------
 FOR E IN 1..V_CANTIDAD-1 LOOP -- bucle que genera las líneas hacia abajo
  V_PRINT_LINE := LPAD('@',E+1,'_')||RPAD('@',(V_COUNT-E)-1,'@');
  /*en paso anterior asigno el valor de la variable "V_PRINT_LINE": LPAD('@',E+1,'_') agrego "E+1" veces el carácter "_" a la izquierda del carácter "@"
 y ||RPAD('@',(V_COUNT-E)-1,'@'); agrega "(V_COUNT-E)-1" veces el carácter "@" a la derecha del carácter "@"*/
  DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE);
 END LOOP;
END;
---OUTPUT:



















_____________________________________________________________________________________
---SCRIPT3:
--STAGE THREE -- PIRAMIDE/CONO
DECLARE
 V_CANTIDAD NUMBER(2);
 V_PRINT_LINE VARCHAR2(100);
 V_PRINT_LINE2 VARCHAR2(100); -- otra variable, también para facilitar el asunto
 V_COUNT NUMBER(2);
BEGIN
 V_CANTIDAD := 10;
 V_COUNT := 0;
 FOR E IN REVERSE 1..V_CANTIDAD LOOP -- otro LOOP en reversa
  V_COUNT := V_COUNT+1;
  V_PRINT_LINE := LPAD('@',E,'_')||RPAD('@',V_COUNT-1,'@'); /* explicado anteriormente...*/
  V_PRINT_LINE2 := RPAD('@',V_COUNT-1,'@'); /*pude haberme ahorrado esta asignación, pero dividido en dos pasos es más intuitivo*/
  DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE||V_PRINT_LINE2); -- concateno con "||" las variables "V_PRINT_LINE" y "V_PRINT_LINE2"
 END LOOP;
END;
---OUTPUT:












_____________________________________________________________________________________
--STAGE FOUR --BARQUILLA/CONO
DECLARE
V_CANTIDAD NUMBER(2);
V_PRINT_LINE VARCHAR2(100);
V_PRINT_LINE2 VARCHAR2(100);
BEGIN
V_CANTIDAD := 10;
FOR E IN 1..V_CANTIDAD LOOP
V_PRINT_LINE := LPAD('@',E,'_')||RPAD('@',V_CANTIDAD-E,'@');
/*asigno a "V_PRINT_LINE" lo siguiente: LPAD('@',E,'_'): "_" es agregado "E" veces a la izquierda de "@" y lo concateno a: 
RPAD('@',V_CANTIDAD-E,'@'): "@" es agregado "V_CANTIDAD-E" veces a la derecha de "@"*/
V_PRINT_LINE2 := RPAD('@',V_CANTIDAD-E,'@'); -- explicado en paso anterior
DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE||V_PRINT_LINE2);
END LOOP;
END;
---OUTPUT:












_____________________________________________________________________________________
--STAGE FIVE -- PIRAMIDE/CONO|--|BARQUILLA/CONO
DECLARE /* en este bloque tengo más de lo mismo con cierta diferencia en la lógica, por lo cual me ahorrare la explicación...*/
V_CANTIDAD NUMBER(2);
V_PRINT_LINE VARCHAR2(100);
V_PRINT_LINE2 VARCHAR2(100);
V_COUNT NUMBER(2);
BEGIN
V_CANTIDAD := 10;
V_COUNT := 0;
----------PIRAMIDE/CONO
FOR E IN REVERSE 1..V_CANTIDAD LOOP
V_COUNT := V_COUNT+1;
V_PRINT_LINE := LPAD('@',E,'_')||RPAD('#',V_COUNT-1,'0'); /*cambio los caracteres para así apreciar bien el proceso*/
V_PRINT_LINE2 := RPAD('8',V_COUNT-1,'+');
DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE||V_PRINT_LINE2);
END LOOP;
----------BARQUILLA/CONO
FOR E IN 1..V_CANTIDAD-1 LOOP
V_PRINT_LINE := LPAD('+',E+1,'_')||RPAD('@',(V_CANTIDAD-1)-E,'='); /* igual aquí, cambio los caracteres para así apreciar bien el proceso*/
V_PRINT_LINE2 := RPAD('9',V_CANTIDAD-(E+1),'#');
DBMS_OUTPUT.PUT_LINE(V_PRINT_LINE||V_PRINT_LINE2);
END LOOP;

END;
---OUTPUT:


















_____________________________________________________________________________________
---E AQUÍ UN PLUS:
SET SERVEROUTPUT ON
SET VERIFY OFF /*omito el código que generan las variables de sustitución*/
DECLARE
    V_DATE VARCHAR2(150);
    V_CANTIDAD INTEGER(2);
    V_MESSAGE VARCHAR2(100);   
    E_WRONG_N EXCEPTION; /*exception definida por el usuario*/
    PRAGMA EXCEPTION_INIT(E_WRONG_N, -06502); /*asocio mi exception con un error de ORACLE*/
BEGIN
    V_DATE := TO_CHAR(SYSDATE,'fmDAY DD" de "MONTH" del Año" YYYY, "Hora:" HH12:MI:SS PM', 'nls_date_language = Spanish');
    /*en el paso anterior le asigno la fecha actual a la variable: "V_DATE" con un formato bonito:))*/
    V_CANTIDAD := '&CANTIDAD'; /*e aquí una Variable de Sustitución(le pide al usuario que la introduzca)*/
    IF V_CANTIDAD NOT BETWEEN 1 AND 15 THEN /*limito al usuario a introducir valore entre 1 y 15*/
        RAISE E_WRONG_N; /*levanto mi exception si me introducen un valor fuera del rango*/
    END IF;   
    V_MESSAGE := 'LIFE IS THE MOST PRECIOUS GIFT YOU WILL EVER HAVE!!!'; /*un lindo mensaje*/
    DBMS_OUTPUT.PUT_LINE('
   
'||V_MESSAGE);/*esas líneas son intencionales, por cuestiones de formato*/
    FOR A IN 1..V_CANTIDAD LOOP       
        DBMS_OUTPUT.PUT_LINE(LPAD(RPAD('%',A,'%'),V_CANTIDAD,'_')||RPAD('@',A,'@')); /*más de lo ya explicado pero sin variables*/     
        IF V_CANTIDAD = A THEN       
            DBMS_OUTPUT.PUT_LINE('<<<<<SQUEEZE*IT>>>>>');
            FOR I IN REVERSE 1..A LOOP               
                                     DBMS_OUTPUT.PUT_LINE(LPAD(RPAD('@',I,'@'),V_CANTIDAD,'_')||LPAD('%',I,'%'));             
            END LOOP;           
        END IF;       
    END LOOP;   
    DBMS_OUTPUT.PUT_LINE('FECHA Y HORA ACTUAL: '||V_DATE); /*muestro la fecha*/
    EXCEPTION
    WHEN E_WRONG_N THEN /*mi exception*/
        DBMS_OUTPUT.PUT_LINE('LA CANTIDAD DEBE SER NUMÉRICA Y EN UN RANGO DE 1 A 15');
END;
---OUTPUT:














_____________________________________________________________________________________
/*
De seguro todos estos procesos se pudieran hacer mucho más optimizados, pero el objetivo es solo mostrar lo potente y práctico que resulta PL/SQL.
*/