Autorías Escriturales Posthumanas

2.5 Guía para programar código para un Raspvelarde Pi


 

Como se mencionó en la Introducción, consideramos que una parte fundamental para poder estudiar tanto la materialidad como la agencia de lo no-humano, con el acento que estamos imprimiendo en la técnica digital, y su participación dentro de la autoría escritural es a partir de nuestro involucramiento en estas prácticas. Desde nuestra concepción de mediación técnica, las formas y particularidades que toma la escritura, lectura y autoría en cuanto digitales tienen una influencia sobre nuestras propias prácticas y percepciones. Explicitar esta escritura digital tiene la pretensión de servirnos, más adelante, en una descajanegrización de su operabilidad, así como un punto de partida para estudiar la materialidad de lo digital y su agenciamiento. En este sentido, creemos que se vuelve indispensable que el código, como forma de escritura, sea parte integral de nuestra investigación, lo que nos podrá ayudar a examinar los modos en los que intraccionan escrituras de heterogéneo orden en la conformación de autorías también de heterogéneo orden.
          Raspvelarde Pi es un proyecto que busca a través de la escritura en código en soportes materiales de fácil acceso –en este caso se utilizó para la elaboración de la guía un Raspberry Pi 3b+– generar un dispositivo de desapropiación escritural con la intención de intervenir en la producción misma de dichos fenómenos para tratar de producir formas de autoría más allá de su visión individuada. Este tutorial permitirá crear una aplicación capaz de generar de forma aleatoria un conjunto de combinaciones escriturales partiendo de una lista de líneas disponibles proporcionadas por el usuario. Inspirado en proyectos como el de Manuel Guerrero Nava para el Centro de Cultura Digital, Cómo programar una caja de música con Raspberry Pi, en el que sostiene que “Raspberry Pi no funcionará exactamente como estamos acostumbrados con sistemas operativos comerciales como son MAC OSX y Windows. Raspberry tendrá sus propios sistemas operativos basados en Linux, una de las distribuciones de Sistema Operativo (SO) open source más importantes (2)". Por lo tanto, es necesario señalar los pormenores de un dispositivo como Raspberry Pi antes de dar paso al tutorial.
          Como apuntan Branko Balon y Milenko Simić, Raspberry Pi es una marca, y una serie de productos, de ordenadores monoplaca pequeños “originally designed as an educational tool for promoting teaching of basic computer science in schools (1)”. El modelo 3b+ tiene las siguientes especificaciones: un System-on-a-Chip (SoC), es decir, un solo chip integra todos los módulos necesarios para el funcionamiento de la computadora, que tiene una velocidad base de 1.4 GHz acompañada de 1 GB de RAM. La pequeña placa cuenta con puertos USB, HDMI, microSD y micro USB para interactuar con diferentes dispositivos. De fábrica, el ordenador –de ahora en adelante será llamado Raspvelarde Pi– no tiene integrado ningún tipo de SO instalado de fábrica en la medida en que su filosofía educativa solicitaba del usuario experimentar con implementaciones de software open source, el cual es un tipo de software cuya licencia es accesible y libre para todo aquel que lo desee, lo que permite legalmente a cualquier usuario visualizar, modificar y distribuir dicho software a discreción lo cual tiene como intención principal fomentar la colaboración y la no privatización de los entornos digitales y sus herramientas. 
        Isaac Valentín Aguirre Martínez et. al. sostienen al respecto que el SO Raspbian, al estar basado en Linux, es uno de los sistemas predilectos y de mayor adaptabilidad gracias a su interfaz gráfica similar a la de Windows (248). Raspbian es parte de la iniciativa open source entre cuyas características que la definen en su sitio web cabe subrayar las siguientes: 

  • Redistribución gratuita: la licencia no impide que nadie pueda vender o regalar el software como parte de una distribución de software añadida que tenga otros programas diferentes. No se exigen regalías ni otro tipo de derechos por ventas derivadas.
  • Código fuente: El software open source debe incluir el código fuente  y permitir su redistribución. Se invita a la creación de códigos fuentes de fácil legibilidad para los usuarios.
  • Obras derivadas: la licencia open source permite las modificaciones y la generación de trabajos derivados, así como su distribución. 
  • No discriminación contra personas o grupos: la licencia open source no puede discriminar ningún grupo, persona particular o actividades bajo ningún tipo de circunstancia. 
  • La licencia no debe ser específica de un producto: los derechos de la licencia open source no pueden depender de que el programa sea parte de una distribución se software particular. 
  • La licencia no debe restringir otro software: la licencia no debe imponer ningún tipo de restricciones a otro software que sea distribuido bajo licencia. Se menciona que la licencia no puede, por ejemplo, insistir en que los demás programas distribuidos de manera adjuntan también tenga que adscribirse al código abierto.
En este sentido, Raspvelarde Pi se inscribe en una visión de código abierto en la medida en que consideramos que esta adherencia puede permitir una mayor remezcla y la no apropiación mercantilista de los fenómenos escriturales a ser producidos. 
 





 


Raspvelarde Pi ha sido pensado para ser utilizado en computadores de bajo costo y con posibilidad de utilizar exclusivamente código abierto. Sin embargo, este tutorial puede ser seguido desde cualquier SO compatible con Entorno de Desarrollo Integrado (IDE) Apache Netbeans –lo que incluye a SO como Windows, MacOs y, evidentemente, Linux–. Si pretende seguir el tutorial en cualquiera de estos sistemas operativos pase al punto 4 - Instalación de Netbeans
          Para la instalación del SO Raspbian, también llamado Raspberry Pi OS en las actualizaciones más recientes, la forma más simple es hacerlo a través del puerto microSD de la placa del Raspvelarde Pi a través de otro ordenador. Para ello hay que descargar e instalar del sitio oficial el programa Raspberry Pi Imager: 


Tras haber instalado Raspberry Pi Imager en el ordenador, habrá que insertar la tarjeta microSD –que funcionará como la unidad principal de almacenamiento de nuestro Raspvelarde Pi– y seleccionar las siguientes opciones en la ventana inicial del programa: 


En Dispositivo Raspberry Pi se tiene que seleccionar el modelo en el cual se utilizará dicha tarjeta de memoria –en este caso elegiremos la opción Raspberry Pi 3–, en Sistema Operativo elegiremos Raspberry Pi OS (Legacy, 32-bit) y, por último, en Almacenamiento elegiremos el directorio que la computadora haya otorgado a la tarjeta microSD y seleccionaremos el botón de Siguiente. En el próximo paso podremos editar los ajustes iniciales del SO Raspbian:


Tras personalizar opciones como el nombre del dispositivo, de usuario y contraseña, así como la configuración de red inalámbrica procederemos a escribir el SO en la tarjeta microSD seleccionando el botón Continuar y esperaremos a que termine el proceso. Si se ha ejecutado exitosamente, se desplegará la siguiente ventana:


Tras haber instalado correctamente el SO en la tarjeta microSD, tendremos que insertar la memoria en el puerto da la placa del Raspvelarde Pi. También habrá que conectar –a través de los puertos USB, microUSB y HDMI– el teclado, el ratón, el cable HDMI hacia el monitor, así como conectarlo a la fuente de alimentación para continuar con la instalación del IDE Apache Netbeans.
 


Apache Netbeans es descrito en su manual de operación como “a free, open source, integrated development environment (IDE) that enables you to develop desktop, mobile and web applications. The IDE supports applications development in various languages, including Java, HTML5, PHP and CC++”. Una IDE es una herramienta de software que otorga al usuario un entorno de programación para desarrollo de software que permite la generación y edición de código fuente, la automatización de sus tareas y su compilación. Netbeans cuenta con la licencia open source Common Development and Distribution License (CDDL) que permite la combinación y redistribución libre donde sólo pide al usuario que los nuevos licenciamientos sigan amparados bajo la misma licencia. Chris Jensen y Walt Scachhi señalan que la comunidad de Netbeans, en 2004, era “one of the larger OSSD [...] communities, with 1100 active user, 500 contributors, 9500 source commits per month, 1.7 million downloads, and boast of nearly 100,000 unique mailing list subscribers (1)”. El desarrollo de código para las funcionalidades, el reporte de códigos, la documentación y la traducción a varios idiomas está a cargo de los colaboradores que, sin ánimo de lucro, dan servicio al IDE. Por este motivo se ha elegido a Netbeans como el entorno adecuado para las intenciones del proyecto. 
        Si se está siguiendo el tutorial a través de un SO diferente de Raspsbian, para la instalación del IDE Apache Netbeans simplemente tiene que acceder al sitio oficial para la descarga de la paquetería mientras que si está siguiendo el tutorial utilizando una Raspberry la instalación se hará desde la terminal. Si se ha instalado correctamente el SO Raspbian, el ícono de la terminal aparecerá en la barra de tareas superior:


La interfaz de la terminal debe mostrarse de la siguiente manera:


Al abrir la terminal aparecerá el nombre del dispositivo seguido del usuario, en nuestro caso RaspvelardePi@RaspvelardePi:, seguido del símbolo ~ que indica el directorio de inicio desde el que se parte, mientras que el símbolo $ indica que la terminal está preparada para recibir comandos por parte del usuario. Para la instalación de Netbeans deberemos ingresar líneas de comando empezando por: sudo apt update ,el comando sudo permite la ejecución de los demás comandos con los privilegios de administrador, el comando apt permite gestionar los paquetes instalados en el SO, el comando update indica que deben ser actualizados. Si se ejecutó correctamente el comando deberá desplegarse lo siguiente en la terminal:



La segunda línea de comandos que deberá ser escrita en la terminal es la siguiente: sudo apt install snapd la cual servirá para llamar a snapd el cual es un servicio que permite la gestión de paqueterías, entendidas como aplicaciones desarrolladas para el SO. Deberá desplegarse lo siguiente en la terminal:


Cuando la terminal nos pregunte ¿Desea continuar? [S/n] deberemos teclear la letra s para continuar con el proceso. Posteriormente, será necesario reiniciar el sistema por lo que ingresaremos la siguiente línea de comandos: sudo reboot. Después de que el sistema se haya reiniciado, volveremos a abrir la terminal para introducir la siguiente línea: sudo snap install core el cual servirá para instalar los componentes principales para el uso del servicio de la tienda snap. Deberá desplegarse lo siguiente en la terminal:


La última línea de comandos será: sudo snap install strictly-netbeans que servirá para instalar la versión más reciente del IDE Netbeans. Automáticamente comenzará el proceso de descarga y de instalación de la paquetería. Si el proceso ha sido exitoso deberá desplegarse lo siguiente en la terminal:


Tras haber instalado el IDE Netbeans, será necesario instalar la versión más reciente de Java Development Kit (JDK), el cual es un conjunto de herramientas que permite la creación de programas y aplicaciones en Java. El 99% de las líneas de código fuente de Netbeans está escrita en el lenguaje de programación de Java y por ello es necesario instalar su JDK. Si se sigue este tutorial desde otro SO, puede descargarlo desde el sitio oficial de Oracle. Si se sigue desde Raspbian, volveremos a abrir la terminal y ejecutaremos las siguientes líneas de comandossudo apt update


Después ingresaremos la línea de comandos sudo apt install default-jdk. Para verificar que la instalación se ha realizado correctamente, ingresaremos la línea java -version y la terminal deberá mostrar lo siguiente:


Con el IDE Netbeans instalado, así como con la paquetería necesaria de Java, podemos pasar a la escritura de código para la generación de la aplicación.
 


Antes de programar la aplicación que podrá generar combinaciones escriturales a través de una serie de líneas ingresadas por el usuario, se ofrecerán dos aplicaciones que permiten, dentro de la propia interfaz de Netbeans, cortar párrafos en diferentes líneas –que luego podrán ser integrados en la base de datos– con una extensión de palabras determinada por el usuario. La segunda aplicación permite al programa seleccionar de forma aleatoria un número determinado de líneas descartando un par de éstas. Se comenzará con el Cortador de párrafos. Primero, abriremos el IDE Netbeans y de desplegará su interfaz de inicio:


En la esquina superior izquierda seleccionaremos File > New Project. En la ventana emergente seleccionaremos la opción de Java with Maven >Java Application:


En la nueva ventana emergente, nombraremos al proyecto como Cortador (es indispensable respetar la mayúscula inicial) y daremos clic en Finish:


En la parte izquierda de la interfaz se generará un nuevo árbol de proyectos que incluirá el recién creado. Desplegaremos las siguientes ramas Cortador > Source Packages > com.mycompany.cortador y daremos doble clic en el archivo Cortador.java:


En la pestaña de la derecha se abrirá el código fuente, en la pestaña de Source de nuestro proyecto con las siguientes líneas:


Las primeras líneas muestran la licencia que tiene por defecto el proyecto, así como la posibilidad de modificarla si así se desea. De manera automática, Netbeans escribe el nombre del autor del proyecto el cual es tomado del nombre de usuario dado en el SO (En este caso RapsvelardePi). Las siguientes líneas son un código de prueba estándar para comprobar que el IDE funciona correctamente. Dejaremos las tres primeras líneas y borraremos todas las demás, en su lugar pondremos lo siguiente:

package com.mycompany.cortador; 

/**
*
* @author Raspvelarde Pi
*/ // Este es un comentario de documentación que indica el autor del código.


import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.text.Normalizer; 
import java.util.*;

public class Cortador {  
    public static void main(String[] args) {
        try (var scanner = new Scanner(System.in)) {
            String ruta = scanner.nextLine(); 
            String texto = scanner.nextLine(); 
            String[] palabras = texto.split("\\s+"); 
            Random rand = new Random(); 
            
            int i = 0; 
            int minPalabras = 6; // Mínimo número de palabras por línea.
            int maxPalabras = 9; // Máximo número de palabras por línea.
            File archivo = new File(ruta + "/texto_dividido.txt"); 
            if (!archivo.exists()) { 
                archivo.createNewFile(); 
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(archivo)); 
            while (i < palabras.length) { 
                int palabrasEnLinea = rand.nextInt(maxPalabras - minPalabras + 1) + minPalabras; 
                for (int j = 0; j < palabrasEnLinea; j++) { 
                    if (i < palabras.length) { 
                        String palabra = palabras[i]; 
                        palabra = Normalizer.normalize(palabra, Normalizer.Form.NFD); 
                        palabra = palabra.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); 
                        bw.write(palabra + " ");
                        i++; 
                    } else {
                        break;
                    }
                }
                bw.newLine();
            }
            bw.close(); 
        } catch (IOException e) { 
            System.out.println("Ocurrió un error: " + e.getMessage()); 
        }
    }
}


El cortador está programado para dividir en múltiples líneas el texto otorgado por el usuario diferenciado entre las palabras a través de los espacios. El número de palabras que selecciona para generar cada división se genera a través de seleccionar un número aleatorio entre 6 y 9:

int minPalabras = 6; // Mínimo número de palabras por línea.
int maxPalabras = 9; // Máximo número de palabras por línea.


Si se desea cambiar el rango de selección para el número de palabras posibles por línea, basta con cambiar los números en dichas líneas por los parámetros deseados. Para ejecutar el código, se hará clic en el ícono de Run Project:


En la parte inferior de la interfaz deberá abrirse automáticamente una nueva ventana llamada Output:


Primero la interfaz pedirá al usuario ingresar la ruta de acceso –es decir la carpeta de destino– en donde generará un nuevo archivo .txt con las líneas ya divididas. Después de escribir la ruta de acceso, se le pedirá al usuario ingresar el texto que será dividido en líneas y presionar Enter. Si ha funcionado correctamente la ventana mostrará la leyenda BUILD SUCCESS. Con el Cortador realizado, pasaremos a otra aplicación que hará una selección aleatoria de las líneas ya divididas. 
 


El seleccionador servirá para descartar, de forma completamente aleatoria, una parte de las líneas divididas hechas por el Cortador. Deberemos seguir exactamente las mismas indicaciones en Netbeans para generar otro nuevo proyecto con el nombre Seleccionador. Ahora agregaremos el siguiente código fuente a la nueva ventana de Source:

/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 */

package com.mycompany.seleccionador;

/**
 * @author Raspvelarde Pi
 */

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class Seleccionador {
    public static void main(String[] args) {
        Scanner scanner;
        scanner = new Scanner(System.in);
        System.out.println("Por favor, ingresa la ruta del archivo .txt:");
        // Leemos la ruta del archivo
        String ruta = scanner.nextLine();

        try {
            List<String> lineas = new ArrayList<>(Files.readAllLines(Paths.get(ruta)));
            // Obtenemos el número total de líneas
            int totalLineas = lineas.size();
            // Calculamos cuántas líneas se deben eliminar (un tercio del total)
            int lineasAEliminar = (int) (totalLineas * 0.33);
            // Creamos un objeto Random para generar números aleatorios
            Random rand = new Random();

            for (int i = 0; i < lineasAEliminar; i++) {
                // Generamos un índice aleatorio
                int indiceAleatorio = rand.nextInt(lineas.size());
                // Eliminamos la línea en el índice aleatorio
                lineas.remove(indiceAleatorio);
            }

            Files.write(Paths.get(ruta), lineas);

            System.out.println("Se han eliminado " + lineasAEliminar + " líneas del archivo original.");
        } catch (IOException e) {
            // Si ocurre un error al leer o escribir el archivo, imprimimos un mensaje de error
            System.out.println("Ha ocurrido un error al leer o escribir el archivo.");
        }
    }
}


El Seleccionador elegirá de forma completamente aleatoria una cantidad de líneas de un archivo .txt y las demás serán eliminadas. Para ello, al ejecutar Run Project el output nos pedirá escribir la ruta de acceso del documento .txt del archivo del cual deseamos generar una selección:


El Seleccionador indicará el número de líneas que fueron eliminadas aleatoriamente y el archivo original se sobrescribirá ya sin las líneas descartadas. El programa está configurado para eliminar una tercera parte del total de las líneas que hay en el documento, si se desea alterar el parámetro de descarte basta con modificar el parámetro en la línea: 

int lineasAEliminar = (int) (totalLineas * 0.33);

El decimal 0.33 equivale a la parte del total, teniendo al número 1 como la totalidad de las líneas, de las líneas que serán eliminadas. Es decir, si se quiere eliminar a la mitad bastaría con cambiar el parámetro por 0.50. Con el Cortador y el Seleccionador podremos generar listas indefinidas de líneas, tomados de cualquier tipo de escritura, para ser utilizados como versos en el Desapropiador, la última aplicación para el Raspvelarde Pi.
 


El Desapropiador es una aplicación que se encargará de generar, a través del ingreso de un documento .txt por parte del usuario, un número indeterminado de poemas a través de la selección aleatoria de las líneas pertenecientes al documento. Para ello tendremos que generar otro nuevo proyecto en Java with Maden y nombrarlo Generador. En la pestaña izquierda de la interfaz se deberá desplegar la siguiente arborización:


Abriremos el archivo Generador.java, borraremos las líneas por default del código fuente e ingresaremos las siguientes:

/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 */

package com.mycompany.generador;
public class Generador {
    static Gen v;
    public static void main(String[] args) {
        v = new Gen();
        v.setVisible(true);
        v.run();
    }
}


Después regresaremos a la arborización de la parte izquierda de la interfaz y daremos clic derecho sobre com.mycompany.generador y crearemos una nueva Java Class:


En la ventana emergente, nombraremos a la nueva clase como Gen y daremos clic en Finish:


El nuevo archivo Gen.java deberá aparecer en la misma ramificación del archivo Generador.java:


Daremos doble clic en el archivo Gen.java, borraremos todas las líneas de código por default e ingresaremos las siguientes:

/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 * Click nbfs://nbhost/SystemFileSystem/Templates/GUIForms/JFrame.java to edit this template
 */
package com.mycompany.generador;
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Raspvelarde Pi
 */
public class Gen extends javax.swing.JFrame implements Runnable{

    /**
     * Creates new form Gen
     */
    
    File archivo;
    FileReader fr;
    BufferedReader br;
    
    PrintWriter pw;
    
    Random random;
    boolean init,calc,poem;
    String dir,dirs;
    
    List<Integer> numbers;
    int M, N, V, Li, num;
    int valorEntero, randomIndex;
    
    public Gen() {
        initComponents();
        this.setTitle("Desapropiador");
        archivo = null;
        fr = null;
        br = null;
        M = 5;
        N = 30;
        V = 1564;
        Li = 0;
        init = false;
        calc = false;
        poem = false;
        num = 0;
        
         // Metemos en una lista los números del 1 al 40.
        numbers = new ArrayList<>(V);
        for (int i = 1 ; i < V + 1 ; i++){
            numbers.add(i);
        }
        
        // Instanciamos la clase Random
        random = new Random();
        
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane2 = new javax.swing.JScrollPane();
        jPanel1 = new javax.swing.JPanel();
        jSeparator2 = new javax.swing.JSeparator();
        jLabel1 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jTextField2 = new javax.swing.JTextField();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel3 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        jLabel1.setText("Direccion de archivo origen:");

        jTextField1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel2.setText("Direccion de los archivos destino:");

        jTextField2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel3.setText("<html>\nBienvenido, a continuación se explicará el uso del sistema. <br>\nEl botón de \"INICIO\" da comienzo a la secuencia del generador <br>\nEl botón de \"DETENER\" pausa el proceso del generador <br>\nAsegúrese de llenar los campos de las direcciones de los archivos antes de presionar el botón de \"INICIO\". <br>\nArchivo origen: La dirección debe terminar con el nombre del archivo (.txt) <br>\nArchivos destinos: La dirección de terminar con el nombre de una carpeta <br>\n</html>
        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jScrollPane1.setViewportView(jTextArea1);

        jButton1.setText("INICIAR");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("DETENER");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jSeparator2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSeparator1))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jTextField2)
                            .addComponent(jTextField1)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(237, 237, 237)
                        .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jLabel3)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGap(9, 9, 9)
                .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(5, 5, 5)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButton2)
                    .addComponent(jButton1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jScrollPane2.setViewportView(jPanel1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 770, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane2)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    public void Imprimir(String cad){
        this.jTextArea1.append(cad);
    }
    
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        dir = jTextField1.getText();
        dirs = jTextField2.getText();
        init = true;
        calc = true;
    }                                        

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        // TODO add your handling code here:
        init = false;
    }                                        
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JTextArea jTextArea1;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    // End of variables declaration                   

    @Override
    public void run() {
        while (true) {
            if (init){
                if (calc){
                    Imprimir("Iniciando... " + '\n');
                    num++;
                    //En general, para conseguir un número entero entre M y N con M menor que N y ambos incluídos, debemos usar esta fórmula.
                    valorEntero = (int) (Math.floor(Math.random()*(N-M+1)+M));
                    Imprimir("Extensión del poema: " + valorEntero + '\n');

                    calc = false;
                    poem = true;
                }
                if (poem){
                    for (int i = 1; i <= valorEntero; i++) {
                        randomIndex = random.nextInt(numbers.size());
                        // Damos la carta al jugador (sacamos el número por pantalla)
                        Imprimir("Linea " + numbers.get(randomIndex));

                        try {
                            // Apertura del fichero y creacion de BufferedReader para poder
                            // hacer una lectura comoda (disponer del metodo readLine()).
                            archivo = new File (dir);
                            fr = new FileReader (archivo);
                            br = new BufferedReader(fr);

                            // Lectura del fichero
                            String linea;
                            Li = 0;
                            while((linea=br.readLine())!=null){
                                if (Li == numbers.get(randomIndex)) {
                                    Imprimir('\t' + " Linea Fichero: " + linea + '\n');
                                    //Pasar al nuevo archivo
                                    try (FileWriter fichero = new FileWriter(dirs + "Poema_" + num + ".txt",true))
                                    {
                                        PrintWriter pw = new PrintWriter(fichero);
                                        pw.println(linea);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    //Detener
                                    break;
                                    
                                }
                                else
                                    Li++;
                            }
                        }
                        catch(IOException e){
                        }finally{
                            // En el finally cerramos el fichero, para asegurarnos
                            // que se cierra tanto si todo va bien como si salta
                            // una excepcion.
                            try{
                                if( null != fr ){
                                    fr.close();
                                }
                            }catch (IOException e2){
                            }
                        }

                        // Y eliminamos la carta del mazo (la borramos de la lista)
                        numbers.remove(randomIndex);   
                        try { Thread.sleep(5 * 60 * 1000); } catch (InterruptedException e) { }
                    }
                    Imprimir("  \n");
                    Imprimir("  \n");
                    calc = true;
                }
            }
            try { Thread.sleep(0x3e8); } catch (InterruptedException e) { }
        }
    }
}



Por último, daremos clic en la función de Run Project y deberá aparecer la siguiente ventana emergente:


Como se muestra en el video, habrá que ingresar, primero, la ruta de acceso del archivo de origen en la cual estarán todas las líneas que serán desapropiadas. Es importante destacar que, como han funcionado las aplicaciones anteriores, el archivo ingresado tiene que ser un documento en formato .txt (Se utilizan archivos en formato .txt porque son archivos de texto sin formato. Es decir, a diferencia de procesadores de texto programados pensados visualmente y para el trabajo ofimático, como lo podría ser Word de Microsoft Office, el texto de los archivos .txt no guarda ningún tipo de información como fuente, tamaño, alineamiento, interlineado, etc., que al momento de copiar y pegar podría generar problemas). En un segundo término, ingresamos la dirección –es decir la ruta de una carpeta dentro del dispositivo– en el cual se almacenarán cada uno de los poemas, un archivo por cada poema generado. El código está diseñado para generar poemas de una extensión entre 5 y 30 líneas cada uno para después pasar al siguiente hasta terminar con la lista de líneas disponibles sin repetir ninguna. En las primeras líneas de código pueden encontrarse nombradas las siguientes variables:

M = 5;
N = 30;
V = 1564;


Las variables M y N representan el parámetro de números naturales de los cuales la aplicación definirá un número de versos distinto para cada poema dentro del rango. Si se desea cambiar dichos parámetros basta con modificar los números 5 y 30 y determinar un nuevo rango. Por otra parte, la variable V representa el número total de líneas de las cuales podrá elegir aleatoriamente el desapropiador. Es importante modificar el valor de esta variable para que sea exactamente el mismo que el número total de líneas del archivo de raíz o, por el contrario, aparecerán líneas completamente en blanco. 
        La selección de cada línea, así como la generación de archivos para cada poema, no se genera de manera inmediata, sino que se ha codificado un descanso de 5 minutos entre la elección de una línea y la siguiente. En las últimas líneas finales del código fuente puede encontrarse lo siguiente:

try { Thread.sleep(5 * 60 * 1000); } catch (InterruptedException e) { }

La función Thread.sleep es la que permite dicho descanso entre línea y línea. La forma de indicar este tiempo está expresada en milisegundos:  ( 5 * 60 * 1000 ) , los asteriscos representan multiplicación lo que da como resultado un total de 30,000 milisegundos que equivalen a 5 minutos. Por ejemplo, si se deseará reducir al tiempo bastaría con modificar simplemente el número 5 por un 1 . Es decir, el primero número puede indicarnos el número de minutos que se descansará. El proceso puede pausarse y volverse a reanudar desde la misma interfaz si es necesario. Tras haber de terminado de seleccionar todas las líneas del archivo de origen, el Desapropiador habrá generado cierto número de poemas divididos en diferentes archivos. 


Para la edición, maquetación y presentación de los resultados obtenidos por el Desapropiador, se ha seguido el tutorial Publicación desde una sola fuente de Perro Tuerto. para un proceso automatizado a través del uso de Markdowns el cual es un lenguaje de marcado que permite la creación de plantillas de texto que con facilidad pueden ser exportadas a diversos formatos. La utilidad se los Markdowns reside en la posibilidad de administrar una sola fuente textual para su maquetación en diversos soportes, en nuestro caso para su edición en formato PDF. Sugerimos seguir las mismas instrucciones, aunque recomendamos unas pequeñas modificaciones para corregir la implementación automatizada de índices: en la sección Modificación de las opciones de exportación se sugiere hacer cambios en las preferencias de los gestores de recursos de exportación en el programa open source Zettrl. Perro Tuerto no indica que:

Las nuevas opciones de exportación están en la carpeta  static/defaults  de nuestro librito y son las siguientes:

  • default.html  para la exportación del HTML
  • default.epub  para la exportación del EPUB
  • default.sla  para la exportación del proyecto de Scribus
 
Para los tres archivos Default mencionados, uno para cada formato de exportación, existe una serie de instrucciones para determinar las características de los distintos documentos. Sugerimos agregar las siguientes líneas para la automatización del índice en los tres documentos al momento de modificarlos en el Gestor de Recursos de Zettlr:

standalone: true
toc-depth: 3
toc: true
dpi: 150


La automatización de la maquetación del proyecto es el último paso en la generación del experimento escritural que nos permitirá cuestionar las particularidades que puede tomar la autoría escritural en una situación de profunda tecnificación.

En el presente capítulo se buscó establecer la desapropiación como una técnica escritural que puede aproximarnos a articulaciones no individuadas de la autoría. Sin embargo, y como ya señala la misma Rivera Garza, la desapropiación está traspasada tanto por un entorno digital como por condiciones de extrema violencia. Bajo estos términos, se determinó desapropiar a Velarde y volver a situarlo en su ineludible relación con Jerez. Como ya hemos expuesto, el simple hecho de administrar escrituras previas no implica operar desde la desapropiación: se trata de volver a vincular, de mostrar la imposibilidad de la autonomía de la literatura, de generar presente y buscar alimentar nuevas relaciones. 
En tu casa desierta: Una desapropiación de Ramón López Velarde nos servirá para dilucidar en el próximo capítulo las implicaciones que tiene pensar la autoría escritural desde una postura posthumana. De igual forma, nos ayudará a buscar propuestas que nos alejen de una visión exclusivamente privativa de la escritura al tiempo que promuevan formas de sociabilidad que se adecuen a la descentralización de la voluntad humana como único rector de la construcción y dirección de la vida. 

 
En tu casa desierta: Una desapropiación de Ramón López Velarde

This page has paths:

This page references: