<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Posts - David Charte</title>
	<subtitle>My blog site.</subtitle>
	<link href="https://dch.lu/posts/feed.xml" rel="self" type="application/atom+xml"/>
    <link href="https://dch.lu/posts/"/>
	<updated>2024-05-05T00:00:00+00:00</updated>
	<id>https://dch.lu/posts/feed.xml</id>
	<entry xml:lang="en">
		<title>Finding a convenient mobile workflow for writing posts on a static blog</title>
		<published>2024-05-05T00:00:00+00:00</published>
		<updated>2024-05-05T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/blog-mobile-workflow/" type="text/html"/>
		<id>https://dch.lu/posts/blog-mobile-workflow/</id>
		<content type="html">&lt;p&gt;I wanted to have a more convenient way of adding posts to the blog that didn&#x27;t involve so much editing, dealing with git, jekyll and everything. Something so that I could just jot down some notes on my phone whenever and have them up in no time. This is what I&#x27;ve found at the moment, I may extend this in the future and feel free to send suggestions my way (talk to me at &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;c.im&#x2F;@dcl&quot;&gt;dci@c.im&lt;&#x2F;a&gt; on the fediverse).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jekyllex&quot;&gt;JekyllEx&lt;a class=&quot;zola-anchor&quot; href=&quot;#jekyllex&quot; aria-label=&quot;Anchor link for: jekyllex&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;An Android app that is supposed to manage Jekyll blogs. Installed it but couldn&#x27;t get it to launch, it just crashed :(&lt;&#x2F;p&gt;
&lt;h2 id=&quot;isomorphic-git&quot;&gt;isomorphic-git&lt;a class=&quot;zola-anchor&quot; href=&quot;#isomorphic-git&quot; aria-label=&quot;Anchor link for: isomorphic-git&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I didn&#x27;t find any other promising phone apps and didn&#x27;t want to deal with developing one myself so I started looking into what tools I would need to write a simple webapp to clone my blog, edit it and send updates. Managing a git repo from the browser seemed daunting but I found this amazing library, isomorphic-git, which makes it a breeze. It is very simple to use and leverages modern features of JS in the browser (the author even has an equivalent implementation of Node&#x27;s &lt;code&gt;fs&lt;&#x2F;code&gt; for the browser!), so huge shoutout for that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stackedit&quot;&gt;StackEdit&lt;a class=&quot;zola-anchor&quot; href=&quot;#stackedit&quot; aria-label=&quot;Anchor link for: stackedit&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;After seeing that the git part of the problem could be solved, I looked into Markdown editors, and I came across &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;stackedit.io&quot;&gt;StackEdit&lt;&#x2F;a&gt; which I had already used ages ago.&lt;&#x2F;p&gt;
&lt;p&gt;...and it turns out StackEdit has full support for GitHub&#x2F;Gitlab repos! I&#x27;m just writing this post on it right now and I can push it to the repo so that GitHub takes care of compiling and adding it to the blog.&lt;&#x2F;p&gt;
&lt;p&gt;StackEdit also offers PWA capabilities so you can pin it as an icon on your homescreen.&lt;&#x2F;p&gt;
&lt;p&gt;So this is looking great for writing quick and short stories more frequently :)&lt;&#x2F;p&gt;
&lt;!--stackedit_data:
eyJoaXN0b3J5IjpbMTg2NDIyMjM2MCwtMTk3MjI0MzEyXX0=
--&gt;</content>
	</entry>
	<entry xml:lang="en">
		<title>Machine Learning: ¿Qué es y para qué sirve el análisis exploratorio? (con un ejemplo para que lo veas claro)</title>
		<published>2022-05-24T00:00:00+00:00</published>
		<updated>2022-05-24T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/analisis-exploratorio/" type="text/html"/>
		<id>https://dch.lu/posts/analisis-exploratorio/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Reconocimiento y clasificación de imágenes con Deep Learning </title>
		<published>2022-04-06T00:00:00+00:00</published>
		<updated>2022-04-06T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/clasificacion-deep-learning/" type="text/html"/>
		<id>https://dch.lu/posts/clasificacion-deep-learning/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Aplicaciones de Inteligencia Artificial y Machine Learning en pequeños negocios</title>
		<published>2021-02-08T00:00:00+00:00</published>
		<updated>2021-02-08T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/aplicaciones-ia/" type="text/html"/>
		<id>https://dch.lu/posts/aplicaciones-ia/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>5 aplicaciones prácticas inesperadas de la Inteligencia Artificial</title>
		<published>2020-11-03T00:00:00+00:00</published>
		<updated>2020-11-03T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/aplicaciones-inesperadas-ia/" type="text/html"/>
		<id>https://dch.lu/posts/aplicaciones-inesperadas-ia/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Deploying HomelabOS on a Raspberry Pi 4</title>
		<published>2020-03-31T00:00:00+00:00</published>
		<updated>2020-03-31T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/homelabos/" type="text/html"/>
		<id>https://dch.lu/posts/homelabos/</id>
		<content type="html">&lt;p&gt;HomelabOS is a tool for deploying self-hosted services on a server. For this installation, you will need:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Raspberry Imager&lt;&#x2F;li&gt;
&lt;li&gt;Latest &lt;code&gt;ubuntu-preinstalled-server-arm64&lt;&#x2F;code&gt; from here: https:&#x2F;&#x2F;github.com&#x2F;TheRemote&#x2F;Ubuntu-Server-raspi4-unofficial&#x2F;releases&lt;&#x2F;li&gt;
&lt;li&gt;Docker on your PC (your user should be in the &lt;code&gt;docker&lt;&#x2F;code&gt; group, &lt;code&gt;sudo usermod -a -G docker username&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Latest HomelabOS zip from here: https:&#x2F;&#x2F;gitlab.com&#x2F;NickBusey&#x2F;HomelabOS&#x2F;-&#x2F;tags&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;installing-ubuntu&quot;&gt;Installing Ubuntu&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-ubuntu&quot; aria-label=&quot;Anchor link for: installing-ubuntu&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;We will need Ubuntu 18.04 on the Raspberry. Here&#x27;s how to install it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;fixing-firmware&quot;&gt;Fixing firmware&lt;a class=&quot;zola-anchor&quot; href=&quot;#fixing-firmware&quot; aria-label=&quot;Anchor link for: fixing-firmware&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;First, open up Raspberry Imager and flash Raspbian to your SD card. Boot up your RPi 4 and run these commands:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; apt-get update&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-and z-shell&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; apt-get dist-upgrade&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;y&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rpi-update&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; rpi-eeprom-update&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;actually-installing-ubuntu&quot;&gt;Actually installing Ubuntu&lt;a class=&quot;zola-anchor&quot; href=&quot;#actually-installing-ubuntu&quot; aria-label=&quot;Anchor link for: actually-installing-ubuntu&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Now, use Raspbian Imager to flash the IMG file for Ubuntu Server 18.04 to your SD card. Boot up your Raspberry and check for working SSH (default user and password are &lt;code&gt;ubuntu&lt;&#x2F;code&gt;, &lt;code&gt;ubuntu&lt;&#x2F;code&gt;). You will need to configure an SSH key if you don&#x27;t have one, so &lt;code&gt;ssh-keygen&lt;&#x2F;code&gt; and &lt;code&gt;ssh-copy-id&lt;&#x2F;code&gt; are your friends. A static IP would also be convenient, you can &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;linuxize.com&#x2F;post&#x2F;how-to-configure-static-ip-address-on-ubuntu-18-04&#x2F;&quot;&gt;use netplan to configure it&lt;&#x2F;a&gt;, it&#x27;s easy!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;installing-homelabos&quot;&gt;Installing HomelabOS&lt;a class=&quot;zola-anchor&quot; href=&quot;#installing-homelabos&quot; aria-label=&quot;Anchor link for: installing-homelabos&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Extract files from the downloaded ZIP &lt;strong&gt;on your PC&lt;&#x2F;strong&gt;. Now &lt;code&gt;cd&lt;&#x2F;code&gt; to the HomelabOS directory and run the following:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; logo&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; config &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; answer some questions&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; set enable_miniflux true &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; miniflux is a feed reader&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This should accomplish the following steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Build Docker images for HomelabOS&lt;&#x2F;li&gt;
&lt;li&gt;Set some configuration variables and create &lt;code&gt;settings&#x2F;config.yml&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Enable a service, it doesn&#x27;t have to be miniflux, I chose that for testing&lt;&#x2F;li&gt;
&lt;li&gt;Deploy the configured services to your Raspberry&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;For more info and troubleshooting, see the original posts.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sources&quot;&gt;Sources&lt;a class=&quot;zola-anchor&quot; href=&quot;#sources&quot; aria-label=&quot;Anchor link for: sources&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 18.04.4 unofficial image: https:&#x2F;&#x2F;jamesachambers.com&#x2F;raspberry-pi-4-ubuntu-server-desktop-18-04-3-image-unofficial&#x2F;&lt;&#x2F;li&gt;
&lt;li&gt;HomelabOS installation: https:&#x2F;&#x2F;nickbusey.gitlab.io&#x2F;HomelabOS&#x2F;setup&#x2F;installation&#x2F;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I&#x27;ll be updating this post with more info and tips as I continue optimizing my configuration.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Versatile workflow for autoencoders in Keras</title>
		<published>2020-02-11T00:00:00+00:00</published>
		<updated>2020-02-11T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/versatile-autoencoders/" type="text/html"/>
		<id>https://dch.lu/posts/versatile-autoencoders/</id>
		<content type="html">&lt;h2 id=&quot;architecture-definition&quot;&gt;Architecture definition&lt;a class=&quot;zola-anchor&quot; href=&quot;#architecture-definition&quot; aria-label=&quot;Anchor link for: architecture-definition&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;This code defines the simplest architecture: [input, encoding (2), output]&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;enc_dim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;2&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;encoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;tf.keras.Sequential([&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;keras&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;layers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Dense&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;enc_dim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;activation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;relu&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;input_shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;shape&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-arguments z-python&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-tuple z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-group z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-square z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-round z-python&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;decoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;tf.keras.Sequential([&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;keras&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;layers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Dense&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;data&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;shape&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-arguments z-python&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;activation&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;sigmoid&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;input_shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-sequence z-tuple z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;enc_dim&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-square z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-round z-python&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;definition-of-a-loss-function&quot;&gt;Definition of a loss function&lt;a class=&quot;zola-anchor&quot; href=&quot;#definition-of-a-loss-function&quot; aria-label=&quot;Anchor link for: definition-of-a-loss-function&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Defining the loss as a function allows us much more flexibility to compute penalties from the encodings, or even other inputs (supervised autoencoders).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;autoencoder_loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;layers&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;inp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;, &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;enc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;, &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;layers&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;rec_loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;K.binary_crossentropy(inp, out)&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-python&quot;&gt;#&lt;&#x2F;span&gt; compute other penalties
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;rec_loss # + other penalties&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-flow z-return z-python&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;definition-of-the-loss-layer-and-the-model&quot;&gt;Definition of the loss layer and the model&lt;a class=&quot;zola-anchor&quot; href=&quot;#definition-of-the-loss-layer-and-the-model&quot; aria-label=&quot;Anchor link for: definition-of-the-loss-layer-and-the-model&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;The loss function is wrapped as the last layer of the autoencoder model and connected to the necessary inputs&#x2F;outputs.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;loss_l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tf&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;keras&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;layers&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Lambda&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;autoencoder_loss&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;output_shape&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-sequence z-tuple z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;name&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;loss&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-sequence z-list z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-list z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;encoder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;encoder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;output&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;decoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;encoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;encoder&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-sequence z-list z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;autoencoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;tf.keras.Model([encoder.input, target_input], loss_l)&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;compilation-of-model-with-custom-loss&quot;&gt;Compilation of model with custom loss&lt;a class=&quot;zola-anchor&quot; href=&quot;#compilation-of-model-with-custom-loss&quot; aria-label=&quot;Anchor link for: compilation-of-model-with-custom-loss&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Since the last layer (&lt;code&gt;y_pred&lt;&#x2F;code&gt;) is actually the loss, our custom loss only needs to return that value.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;autoencoder&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;compile&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;loss&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;loss&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-inline z-python&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-inline z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-inline z-python&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-inline z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-inline z-parameters z-python&quot;&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;y_true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;y_pred&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-inline z-body z-python&quot;&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;y_pred&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-curly z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;optimizer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;=&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;adam&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-invalid z-illegal z-stray z-brace z-round z-python&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;fit-model-with-dummy-target&quot;&gt;Fit model with dummy target&lt;a class=&quot;zola-anchor&quot; href=&quot;#fit-model-with-dummy-target&quot; aria-label=&quot;Anchor link for: fit-model-with-dummy-target&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Keras will complain if no target is passed, so we just create some dummy targets which will not be used at all.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;hist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;autoencoder.fit(data, np.zeros(data.shape[0]), batch_size=8, epochs = 100)&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Crea tu propia página o blog gratis con Jekyll y Github: Parte 5 - Vídeo práctico</title>
		<published>2019-02-26T00:00:00+00:00</published>
		<updated>2019-02-26T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-5/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-5/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Crea tu propia página o blog gratis con Jekyll y Github: Parte 4 - Compilación en la nube y gestión de plugins</title>
		<published>2019-02-18T00:00:00+00:00</published>
		<updated>2019-02-18T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-4/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-4/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Crea tu propia página o blog gratis con Jekyll y Github: Parte 3 - Personalizando el sitio</title>
		<published>2019-02-11T00:00:00+00:00</published>
		<updated>2019-02-11T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-3/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-3/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Crea tu propia página o blog gratis con Jekyll y Github: Parte 2 - Publicando posts</title>
		<published>2019-02-04T00:00:00+00:00</published>
		<updated>2019-02-04T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-2/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-2/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Crea tu propia página o blog gratis con Jekyll y Github: Parte 1 - Primeros pasos</title>
		<published>2019-01-28T00:00:00+00:00</published>
		<updated>2019-01-28T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-1/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-1/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>TRUCO: Cómo resaltar la inicial de un texto con CSS</title>
		<published>2018-11-06T00:00:00+00:00</published>
		<updated>2018-11-06T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/resaltar-inicial/" type="text/html"/>
		<id>https://dch.lu/posts/resaltar-inicial/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Guía básica para la personalización de la shell de Linux y Mac</title>
		<published>2018-09-25T00:00:00+00:00</published>
		<updated>2018-09-25T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/personalizacion-shell/" type="text/html"/>
		<id>https://dch.lu/posts/personalizacion-shell/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>3 formas de inicializar colecciones Java a la hora de declararlas</title>
		<published>2018-08-20T00:00:00+00:00</published>
		<updated>2018-08-20T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/colecciones-java/" type="text/html"/>
		<id>https://dch.lu/posts/colecciones-java/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>3 trucos para automatizar tus tareas de desarrollo con git hooks</title>
		<published>2018-08-01T00:00:00+00:00</published>
		<updated>2018-08-01T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/git-hooks/" type="text/html"/>
		<id>https://dch.lu/posts/git-hooks/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Cómo maquetar HTML con el sistema grid de CSS</title>
		<published>2018-07-11T00:00:00+00:00</published>
		<updated>2018-07-11T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/maquetar-grid/" type="text/html"/>
		<id>https://dch.lu/posts/maquetar-grid/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Conceptos esenciales sobre compilación e interpretación</title>
		<published>2018-06-26T00:00:00+00:00</published>
		<updated>2018-06-26T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/compilacion/" type="text/html"/>
		<id>https://dch.lu/posts/compilacion/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Mezclando colores y creando efectos fotográficos en CSS mediante el uso de blend modes</title>
		<published>2018-06-12T00:00:00+00:00</published>
		<updated>2018-06-12T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/blendmodes/" type="text/html"/>
		<id>https://dch.lu/posts/blendmodes/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Programación funcional: Funciones de primera clase y de orden superior</title>
		<published>2018-05-30T00:00:00+00:00</published>
		<updated>2018-05-30T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/primera-clase/" type="text/html"/>
		<id>https://dch.lu/posts/primera-clase/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Programación funcional: Inmutabilidad y funciones puras</title>
		<published>2018-05-24T00:00:00+00:00</published>
		<updated>2018-05-24T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/inmutabilidad/" type="text/html"/>
		<id>https://dch.lu/posts/inmutabilidad/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Cómo centrar y distribuir elementos HTML con el módulo flexbox de CSS</title>
		<published>2018-05-09T00:00:00+00:00</published>
		<updated>2018-05-09T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/flexbox/" type="text/html"/>
		<id>https://dch.lu/posts/flexbox/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>A guide to Ruby in ten lines of code</title>
		<published>2018-03-17T00:00:00+00:00</published>
		<updated>2018-03-17T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/ruby-10/" type="text/html"/>
		<id>https://dch.lu/posts/ruby-10/</id>
		<content type="html">&lt;p&gt;This is a slightly unorthodox introduction guide to the Ruby language. Through this guide we will examine just ten one-line snippets of code, and discover a lot of features from each of them.&lt;&#x2F;p&gt;
&lt;p&gt;This is the post version of a talk I gave for &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;libreim.github.io&quot;&gt;LibreIM&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;syntax&quot;&gt;Syntax&lt;a class=&quot;zola-anchor&quot; href=&quot;#syntax&quot; aria-label=&quot;Anchor link for: syntax&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;puts&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Hello &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;gets&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;strip&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;!&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This snippet accepts a string from standard input, then cleans the leading and trailing spacing characters and embeds it in a greeting which is shown on standard output. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;puts&lt;&#x2F;code&gt; and &lt;code&gt;gets&lt;&#x2F;code&gt; are the standard functions for displaying messages and reading input, respectively.&lt;&#x2F;li&gt;
&lt;li&gt;You can omit parenthesis around parameters for better readability.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;#{...}&lt;&#x2F;code&gt; in strings interprets small pieces of code and transforms the output into a string.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;puts&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;boooored&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;upcase &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;unless&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Time&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;now&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;saturday?
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This example is so readable you probably don&#x27;t need a description. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Literals are Ruby objects and can receive methods.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;if&lt;&#x2F;code&gt;, &lt;code&gt;unless&lt;&#x2F;code&gt;, &lt;code&gt;while&lt;&#x2F;code&gt; and &lt;code&gt;until&lt;&#x2F;code&gt; can be used as one-line structures.&lt;&#x2F;li&gt;
&lt;li&gt;There is a convention to end methods which return booleans with &lt;code&gt;?&lt;&#x2F;code&gt; and methods which have non-explicit side effects with &lt;code&gt;!&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;real&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; imag &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;(1 + 3i).rectangular&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This snippet assigns the real part of 1 + 3i to &lt;code&gt;real&lt;&#x2F;code&gt; and the imaginary part to &lt;code&gt;imag&lt;&#x2F;code&gt;. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Ruby has built-in support for complex numbers, big numbers (as in symbolic, bigger than &lt;code&gt;long long&lt;&#x2F;code&gt; numbers) and symbolic rationals.&lt;&#x2F;li&gt;
&lt;li&gt;Assignment allows splatting arrays. The splat operator &lt;code&gt;*&lt;&#x2F;code&gt; allows for related operations. For example,&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;x, *xs = &quot;[1, 2, 3, 4]&quot;
```
performs some Haskell-ish pattern matching: &lt;code&gt;x&lt;&#x2F;code&gt; receives the first element and &lt;code&gt;xs&lt;&#x2F;code&gt; holds the rest of the array. There is also a similar double-splat &lt;code&gt;**&lt;&#x2F;code&gt; for hashes.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;object-oriented-programming&quot;&gt;Object oriented programming&lt;a class=&quot;zola-anchor&quot; href=&quot;#object-oriented-programming&quot; aria-label=&quot;Anchor link for: object-oriented-programming&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-class z-ruby&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-name z-class z-ruby&quot;&gt;DeadPlayerError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-inheritance z-ruby&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-other z-inherited-class z-ruby&quot;&gt;StandardError&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-ruby&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Defines a class useful to return errors (exceptions). Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Classes are defined with &lt;code&gt;class&lt;&#x2F;code&gt; (which is syntax sugar for &lt;code&gt;Class.new { ... }&lt;&#x2F;code&gt;).&lt;&#x2F;li&gt;
&lt;li&gt;There is simple inheritance with &lt;code&gt;&amp;lt;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;You can throw an error with &lt;code&gt;raise DeadPlayerError&lt;&#x2F;code&gt;. Ruby distinguishes errors, from which a program can recover, and other kinds of exceptions, which leave the program in an invalid state and therefore it must stop.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;{.ruby}&quot; class=&quot;language-{.ruby} z-code&quot;&gt;&lt;code class=&quot;language-{.ruby}&quot; data-lang=&quot;{.ruby}&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Point = &amp;quot;Struct.new :x, :y, :z&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creates a class with getters and setters for the given attributes. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Member attributes of a class are &lt;strong&gt;always&lt;&#x2F;strong&gt; private (or protected, as they are inherited). Thus, the &lt;em&gt;dot&lt;&#x2F;em&gt; only sends methods and doesn&#x27;t directly access attributes.&lt;&#x2F;li&gt;
&lt;li&gt;Methods can be defined in a &lt;code&gt;do ... end&lt;&#x2F;code&gt; block. You should consider defining a class if you want to add them.&lt;&#x2F;li&gt;
&lt;li&gt;New objects are created with &lt;code&gt;Point.new&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;iteration-and-data-structures&quot;&gt;Iteration and data structures&lt;a class=&quot;zola-anchor&quot; href=&quot;#iteration-and-data-structures&quot; aria-label=&quot;Anchor link for: iteration-and-data-structures&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;puts&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-other z-literal z-lower z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;%w[&lt;&#x2F;span&gt;such elegant wow&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;each_with_index&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;map &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-begin z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-end z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;i&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;. &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;w&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Walks through the array, obtains an array of strings &lt;em&gt;index. element&lt;&#x2F;em&gt; and prints it on stdout. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%w[]&lt;&#x2F;code&gt; splits a list of words by spaces and returns an array.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;each_with_index&lt;&#x2F;code&gt; iterates giving each element and its index in the collection.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;map&lt;&#x2F;code&gt; applies a function on each element of a collection and returns the result.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;{...}&lt;&#x2F;code&gt; o &lt;code&gt;do ... end&lt;&#x2F;code&gt; denote &lt;em&gt;blocks&lt;&#x2F;em&gt;, structures of code which are passed to methods in order to be ran from them. Blocks can receive parameters between bars &lt;code&gt;|a, b|&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;dot &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;-&amp;gt;(v1, v2) { v1.zip(v2).reduce(0) { |p, (n, m)| p + n * m } }&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Computes the dot product. Example usage: &lt;code&gt;dot.([1, 2, 3], [-1, 0, 2])&lt;&#x2F;code&gt;. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Lambda functions are defined with &lt;code&gt;-&amp;gt;&lt;&#x2F;code&gt;. As opposed to usual functions or methods, Lambdas are objects.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;zip&lt;&#x2F;code&gt; pairs the elements of two or more arrays.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;reduce&lt;&#x2F;code&gt; accumulates results of a binary function.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;fib &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Hash.new { |h, i| h[i] = h[i - 2] + h[i - 1] }.update(0 =&amp;gt; 0, 1 =&amp;gt; 1)&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Creates a Hash which contains, for each index, the corresponding term of the Fibonacci sequence. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Hash&lt;&#x2F;code&gt; may receive a &lt;em&gt;default&lt;&#x2F;em&gt; initialization (usually &lt;code&gt;nil&lt;&#x2F;code&gt;). This initialization takes place whenever the user attempts to access a value which has not been assigned previously.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Hash#update&lt;&#x2F;code&gt; assigns several values at a time.&lt;&#x2F;li&gt;
&lt;li&gt;This would be equivalent to a memoized recursive version.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;solution&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;neighborhood&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;detect &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-begin z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;attempt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;fitness&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-end z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; fitness &lt;span class=&quot;z-keyword z-operator z-comparison z-ruby&quot;&gt;&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-readwrite z-instance z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-ruby&quot;&gt;@&lt;&#x2F;span&gt;current_fitness&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Assuming the &lt;code&gt;.neighborhood&lt;&#x2F;code&gt; returns a collection of possible solutions and their performance (fitness), this finds the first one which improves the current solution. Actual use: &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;git.io&#x2F;vPxQ6&quot;&gt;https:&#x2F;&#x2F;git.io&#x2F;vPxQ6&lt;&#x2F;a&gt;. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;detect&lt;&#x2F;code&gt; receives a predicate and returns the first ellement of the collection which verifies it.&lt;&#x2F;li&gt;
&lt;li&gt;If you want to get the best solution in the neighborhood instead, you can use &lt;code&gt;max_by&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;There is a huge list of iteration methods available in any Ruby collection class:
&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;ruby-doc.org&#x2F;core-2.5.0&#x2F;Enumerable.html&quot;&gt;&lt;code&gt;Enumerable&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;i-o&quot;&gt;I&#x2F;O&lt;a class=&quot;zola-anchor&quot; href=&quot;#i-o&quot; aria-label=&quot;Anchor link for: i-o&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;open&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-ruby&quot;&gt;DATA&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;read&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;w&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;write &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;IO&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;read&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-global z-pre-defined z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-ruby&quot;&gt;$&lt;&#x2F;span&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;gsub&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-regexp z-ruby&quot;&gt;&lt;span class=&quot;z-string z-regexp z-classic z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;^#&amp;#39; &lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This snippet reads itself (as in, the own program running), uncomments lines marked with &lt;code&gt;#&#x27;&lt;&#x2F;code&gt; and passes the result as input to the program started by &lt;code&gt;Kernel#open&lt;&#x2F;code&gt;. Notice that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$0&lt;&#x2F;code&gt; is the name of the current program&#x2F;script.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;gsub&lt;&#x2F;code&gt; performs global sustitution&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Kernel#open&lt;&#x2F;code&gt; opens read&#x2F;write pipes with other processes when the &quot;filename&quot; looks like &lt;code&gt;&quot;|program_name&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;The catch&lt;&#x2F;em&gt;  The program is hidden in the data section of the &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fdavidcl&#x2F;ruby-ten-lines&#x2F;blob&#x2F;master&#x2F;slides.rb&quot;&gt;original script&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;__END__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;pandoc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; beamer&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;o&lt;&#x2F;span&gt; slides.pdf&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;pdf-engine&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-option z-shell&quot;&gt;=&lt;&#x2F;span&gt;xelatex&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Deploying Mastodon on a single DigitalOcean droplet</title>
		<published>2018-03-10T00:00:00+00:00</published>
		<updated>2018-03-10T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/mastodon-digitalocean/" type="text/html"/>
		<id>https://dch.lu/posts/mastodon-digitalocean/</id>
		<content type="html">&lt;h2 id=&quot;what-happened&quot;&gt;What happened&lt;a class=&quot;zola-anchor&quot; href=&quot;#what-happened&quot; aria-label=&quot;Anchor link for: what-happened&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;I bought a super cheap domain with a &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;quotient.space&quot;&gt;cool name&lt;&#x2F;a&gt;. I had to put something there, so why not Mastodon? I had a 10$ coupon from DigitalOcean so I could try it for free for a month or two.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;zola-anchor&quot; href=&quot;#prerequisites&quot; aria-label=&quot;Anchor link for: prerequisites&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;You&#x27;ll need a domain name for this. There are free domains available in certain TLDs, and also very cheap ones out there (quotient.space was just 0.55€ for the first year).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-do-the-thing&quot;&gt;How to do the thing&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-to-do-the-thing&quot; aria-label=&quot;Anchor link for: how-to-do-the-thing&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Most of this process is just following Mastodon&#x27;s own &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tootsuite&#x2F;documentation&#x2F;blob&#x2F;master&#x2F;Running-Mastodon&#x2F;Docker-Guide.md&quot;&gt;Docker guide&lt;&#x2F;a&gt;. I used version 2.3.0 for this, so the process may be different for other versions.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer&lt;&#x2F;strong&gt;:  This is my first time deploying Mastodon so trust your own common sense over these steps.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set up a single 5$ droplet in your DO account (if you are not yet an user you can use this link to get 10$ credit: &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;m.do.co&#x2F;c&#x2F;ca70d8a84d85&quot;&gt;https:&#x2F;&#x2F;m.do.co&#x2F;c&#x2F;ca70d8a84d85&lt;&#x2F;a&gt;). Throw your public SSH key in there and use its IP address to login: &lt;code&gt;ssh root@[ip-address]&lt;&#x2F;code&gt;. You can also set up your domain so that it points to DO&#x27;s nameservers and redirects to your droplet.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;apt install docker.io nginx letsencrypt&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You&#x27;ll need a new version of docker-compose so run this (&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;wdullaer&#x2F;f1af16bd7e970389bad3&quot;&gt;source&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;COMPOSE_VERSION&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; ls-remote https:&#x2F;&#x2F;github.com&#x2F;docker&#x2F;compose&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;grep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; refs&#x2F;tags&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;grep&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;oP&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;[0-9]+\.[0-9][0-9]+\.[0-9]+$&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;tail&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;n&lt;&#x2F;span&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; sh&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;c&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;curl -L https:&#x2F;&#x2F;github.com&#x2F;docker&#x2F;compose&#x2F;releases&#x2F;download&#x2F;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-begin z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;COMPOSE_VERSION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-end z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&#x2F;docker-compose-&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;uname&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;-&lt;span class=&quot;z-meta z-group z-expansion z-command z-backticks z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;uname&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-shell&quot;&gt;`&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &amp;gt; &#x2F;usr&#x2F;local&#x2F;bin&#x2F;docker-compose&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; chmod +x &#x2F;usr&#x2F;local&#x2F;bin&#x2F;docker-compose&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; sh&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;c&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;curl -L https:&#x2F;&#x2F;raw.githubusercontent.com&#x2F;docker&#x2F;compose&#x2F;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-begin z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;COMPOSE_VERSION&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-end z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&#x2F;contrib&#x2F;completion&#x2F;bash&#x2F;docker-compose &amp;gt; &#x2F;etc&#x2F;bash_completion.d&#x2F;docker-compose&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Also, create a swapfile:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;fallocate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;l&lt;&#x2F;span&gt; 1G &#x2F;swapfile&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 600 &#x2F;swapfile&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;mkswap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &#x2F;swapfile&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;swapon&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &#x2F;swapfile&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Follow the guide for Docker in Mastodon documentation to clone the repository. Now, &lt;code&gt;touch .env.production&lt;&#x2F;code&gt; since docker-compose will not work without it. Follow the guide to get the images.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Check that file permissions are correct. I came across a couple of &lt;code&gt;Permission denied&lt;&#x2F;code&gt; errors since some directories in the Docker container were owned by &lt;code&gt;root&lt;&#x2F;code&gt; instead of &lt;code&gt;mastodon&lt;&#x2F;code&gt;. To check this, login into the web container as root:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; run&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;rm&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;u&lt;&#x2F;span&gt; 0 web bash&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; in the container:&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;R&lt;&#x2F;span&gt; mastodon:mastodon &#x2F;mastodon&#x2F;public&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;blockquote&gt;
&lt;p&gt;Is this terrible? Shouldn&#x27;t I have changed it? Tell me&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Follow the guide to setup your instance. You don&#x27;t need a MailGun account if it&#x27;s a single-user instance, but put some fake user and password just in case. The compilation of assets may take several minutes, for convenience make sure you aren&#x27;t kicked out of the ssh session. Set up an admin account for yourself.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;docker-compose up -d&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Follow the nginx and Let&#x27;s Encrypt sections of the &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tootsuite&#x2F;documentation&#x2F;blob&#x2F;master&#x2F;Running-Mastodon&#x2F;Production-guide.md#nginx-configuration&quot;&gt;production guide&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If all went well you should be able to see your new Mastodon instance when you visit your domain.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;useful-stuff&quot;&gt;Useful stuff&lt;a class=&quot;zola-anchor&quot; href=&quot;#useful-stuff&quot; aria-label=&quot;Anchor link for: useful-stuff&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If assets compilation didn&#x27;t work, you can try again with&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; run&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;rm&lt;&#x2F;span&gt; web rake assets:precompile&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If creating the user didn&#x27;t work, try adding a new user, locating the password reset token in the logs (then navigating to &lt;code&gt;example.com&#x2F;auth&#x2F;password&#x2F;edit?reset_password_token=[your-token]&lt;&#x2F;code&gt; to create a password) and lastly confirming the email address:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; run&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;rm&lt;&#x2F;span&gt; web rake mastodon:add_user&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; logs mastodon_web_1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker-compose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; run&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;rm&lt;&#x2F;span&gt; web rake mastodon:confirm_email USER_EMAIL=&lt;span class=&quot;z-keyword z-control z-regexp z-set z-begin z-shell&quot;&gt;[&lt;&#x2F;span&gt;your&lt;span class=&quot;z-keyword z-operator z-word z-shell&quot;&gt;-&lt;&#x2F;span&gt;email&lt;span class=&quot;z-keyword z-control z-regexp z-set z-end z-shell&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Time tracking in Emacs with org-clock</title>
		<published>2017-11-30T00:00:00+00:00</published>
		<updated>2017-11-30T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/time-tracking-org/" type="text/html"/>
		<id>https://dch.lu/posts/time-tracking-org/</id>
		<content type="html">&lt;p&gt;This is yet another short post about a little feature in Emacs that turned out to be pretty useful. If you ever feel that you&#x27;d like to know how much time you are spending working on different projects (and are an Emacs user), this is the post for you.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;org-clock&quot;&gt;org-clock&lt;a class=&quot;zola-anchor&quot; href=&quot;#org-clock&quot; aria-label=&quot;Anchor link for: org-clock&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;After searching for a simple app to track my time for an hour or so, I ended up looking for that functionality in Emacs and, &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.xkcd.com&#x2F;378&#x2F;&quot;&gt;unsurprisingly enough&lt;&#x2F;a&gt;, it exists. It&#x27;s integrated inside &lt;em&gt;org-mode&lt;&#x2F;em&gt; so it works very well with any task list you may already have, or you could create a completely separate file exclusive for time tracking.&lt;&#x2F;p&gt;
&lt;p&gt;The following is the skeleton for my time log:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;org&quot; class=&quot;language-org z-code&quot;&gt;&lt;code class=&quot;language-org&quot; data-lang=&quot;org&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;#+title: Time log
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;=CHEATSHEET=
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- S-c         open this window (i3)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- C-c C-x C-i org-clock-in
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- C-c C-x C-o org-clock-out
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- C-c C-x C-j org-clock-goto
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- C-c C-x C-d org-clock-display
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;- C-c C-x C-r org-clock-report
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;* Work
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;* M.Sc.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;* Projects &#x2F; Fun
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Easy enough, the only actual content of the file is that last stack of headers (it could be a list with &lt;code&gt;-&lt;&#x2F;code&gt; instead of &lt;code&gt;*&lt;&#x2F;code&gt; as well). Now onto the good part: place the cursor over one of the tasks and type &lt;kbd&gt;Ctrl + c&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + x&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + i&lt;&#x2F;kbd&gt;. This will set a clock under that task with the starting time of the task. Let some time pass, and use &lt;kbd&gt;Ctrl + c&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + x&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + o&lt;&#x2F;kbd&gt; to stop the clock. Emacs will also remember when you have a clock running, and will warn you if you try to close the buffer or stop the clock if you start another one.&lt;&#x2F;p&gt;
&lt;p&gt;When you have tracked several time periods for the same task, you can compute the total time with &lt;kbd&gt;Ctrl + c&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + x&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + d&lt;&#x2F;kbd&gt;. &lt;em&gt;org-clock&lt;&#x2F;em&gt; also understands nested tasks (second-level headers, nested lists, etc.) and will sum the time of all the tasks inside a higher-level task to compute the overall spent time. You can generate a daily report with &lt;kbd&gt;Ctrl + c&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + x&lt;&#x2F;kbd&gt;,&lt;kbd&gt;Ctrl + r&lt;&#x2F;kbd&gt; and setting the &lt;code&gt;:block today&lt;&#x2F;code&gt; parameter. The following screenshot shows all these features at work:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;emacs-org-clock.png&quot; alt=&quot;Screenshot of my time log&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;convenient-stuff&quot;&gt;Convenient stuff&lt;a class=&quot;zola-anchor&quot; href=&quot;#convenient-stuff&quot; aria-label=&quot;Anchor link for: convenient-stuff&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;As a user of i3, it&#x27;s easy to set keybindings that will let me access my time log instantly:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; .config&#x2F;i3&#x2F;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;bindsym&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;mod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;+c exec &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;xdotool search --name &amp;#39;timelog.org&amp;#39; windowactivate &amp;amp;&amp;amp; i3-msg kill || emacsclient -c &#x2F;media&#x2F;datos&#x2F;Documents&#x2F;timelog.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;for_window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-keyword z-control z-regexp z-set z-begin z-shell&quot;&gt;[&lt;&#x2F;span&gt;class=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Emacs&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; title=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;timelog.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-regexp z-set z-end z-shell&quot;&gt;]&lt;&#x2F;span&gt; floating enable&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;for_window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-keyword z-control z-regexp z-set z-begin z-shell&quot;&gt;[&lt;&#x2F;span&gt;class=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Emacs&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; title=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;timelog.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-regexp z-set z-end z-shell&quot;&gt;]&lt;&#x2F;span&gt; resize set 1920 1280&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;for_window&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-keyword z-control z-regexp z-set z-begin z-shell&quot;&gt;[&lt;&#x2F;span&gt;class=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Emacs&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; title=&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;timelog.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-regexp z-set z-end z-shell&quot;&gt;]&lt;&#x2F;span&gt; move position center&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This enables a &lt;kbd&gt;Super + c&lt;&#x2F;kbd&gt; binding that will toggle an Emacs window with the time log file.&lt;&#x2F;p&gt;
&lt;p&gt;In order to save some keystrokes and prevent forgetting to save the time log, I have also added these hooks into my Emacs config:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; class=&quot;language-lisp z-code&quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;z-source z-lisp&quot;&gt;&lt;span class=&quot;z-meta z-group z-lisp&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-lisp&quot;&gt;(&lt;&#x2F;span&gt;add&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;hook &amp;#39;org&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;clock&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;in&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;hook &amp;#39;save&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;buffer&lt;span class=&quot;z-punctuation z-definition z-group z-end z-lisp&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-lisp&quot;&gt;&lt;span class=&quot;z-meta z-group z-lisp&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-lisp&quot;&gt;(&lt;&#x2F;span&gt;add&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;hook &amp;#39;org&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;clock&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;out&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;hook &amp;#39;save&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;buffer&lt;span class=&quot;z-punctuation z-definition z-group z-end z-lisp&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Finally, I let Emacs open the file in background at startup with the following line in the configuration, so the buffer isn&#x27;t actually closed when I close the window:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;lisp&quot; class=&quot;language-lisp z-code&quot;&gt;&lt;code class=&quot;language-lisp&quot; data-lang=&quot;lisp&quot;&gt;&lt;span class=&quot;z-source z-lisp&quot;&gt;&lt;span class=&quot;z-meta z-group z-lisp&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-lisp&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-lisp&quot;&gt;find&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;file&lt;span class=&quot;z-keyword z-operator z-arithmetic z-lisp&quot;&gt;-&lt;&#x2F;span&gt;noselect &lt;span class=&quot;z-string z-quoted z-double z-lisp&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-lisp&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;~&#x2F;Documentos&#x2F;timelog.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-lisp&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-lisp&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And that&#x27;s all there is to simple time tracking in Emacs. I hope you learned something useful and I didn&#x27;t waste your time.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Emacs for lazy people</title>
		<published>2017-05-05T00:00:00+00:00</published>
		<updated>2017-05-05T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/emacs-lazy/" type="text/html"/>
		<id>https://dch.lu/posts/emacs-lazy/</id>
		<content type="html">&lt;p&gt;Emacs is one of the most powerful, extensible editors out there.
However, learning to use it is not an easy task, and I&#x27;m just really
lazy. The following are some packages that I hope will make your life
way easier. And if you already use Emacs, I encourage you to try them
and see if they help you get a more comfortable development environment.&lt;&#x2F;p&gt;
&lt;p&gt;To add any of these packages to your Emacs configuration, find your
initialization file (usually &lt;code&gt;~&#x2F;.emacs&lt;&#x2F;code&gt; or &lt;code&gt;~&#x2F;.emacs.d&#x2F;init.el&lt;&#x2F;code&gt;) and
add the snippets there. You will also need to install and enable &lt;code&gt;use-package&lt;&#x2F;code&gt;
beforehand (&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;www.lunaryorn.com&#x2F;posts&#x2F;my-emacs-configuration-with-use-package.html&quot;&gt;why?&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;smex&quot;&gt;Smex&lt;a class=&quot;zola-anchor&quot; href=&quot;#smex&quot; aria-label=&quot;Anchor link for: smex&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;In Emacs we use M-x
(&lt;kbd&gt;Alt&lt;&#x2F;kbd&gt;+&lt;kbd&gt;X&lt;&#x2F;kbd&gt;) to enter any
command without the need for a dedicated keyboard shortcut or menu
entry. By default Emacs doesn&#x27;t help much while writing a command, and
it can be challenging to remember many of them, as well as tedious
writing the long ones (&lt;code&gt;package-list-packages&lt;&#x2F;code&gt; anyone?).
&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;nonsequitur&#x2F;smex&#x2F;&quot;&gt;Smex&lt;&#x2F;a&gt; is a M-x enhancement for
Emacs, built on top of Ido, which means it will try to predict and
autocomplete commands as you write them.&lt;&#x2F;p&gt;
&lt;p&gt;In order to install and enable Smex, add the following code to your
initialization file:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;common_lisp&quot; class=&quot;language-common_lisp z-code&quot;&gt;&lt;code class=&quot;language-common_lisp&quot; data-lang=&quot;common_lisp&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(use-package smex
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:config (smex-initialize))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;ergoemacs&quot;&gt;Ergoemacs&lt;a class=&quot;zola-anchor&quot; href=&quot;#ergoemacs&quot; aria-label=&quot;Anchor link for: ergoemacs&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;re just starting to use emacs, you may find it difficult to learn
all the new keybindings. If you&#x27;re a long-time user, you may have
experienced repetitive strain injury (RSI), also known as &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Emacs#Emacs_pinky&quot;&gt;Emacs
pinky&lt;&#x2F;a&gt;. Don&#x27;t worry,
I&#x27;ve got just the solution for you:
&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;ergoemacs.github.io&#x2F;index.html&quot;&gt;ergoemacs-mode&lt;&#x2F;a&gt; is a minor-mode
that sets ergonomic and well-known keybindings for common editing
functions, with the aim of reducing RSI as well as adding some
familiarity to the use of emacs.&lt;&#x2F;p&gt;
&lt;p&gt;Just as before, add the following code to your initialization file and
restart Emacs to use it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;common_lisp&quot; class=&quot;language-common_lisp z-code&quot;&gt;&lt;code class=&quot;language-common_lisp&quot; data-lang=&quot;common_lisp&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(use-package ergoemacs-mode
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:init
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  (setq ergoemacs-theme nil)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  (setq ergoemacs-keyboard-layout &amp;quot;es&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:config
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;  (ergoemacs-mode 1)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can check &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;ergoemacs.github.io&#x2F;key-setup.html&quot;&gt;your new keybinding
layout&lt;&#x2F;a&gt;. Remember that,
after enabling Ergoemacs, the keyboard shortcut that allows you to enter
a custom command becomes
&lt;kbd&gt;Alt&lt;&#x2F;kbd&gt;+&lt;kbd&gt;A&lt;&#x2F;kbd&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;which-key&quot;&gt;Which-key&lt;a class=&quot;zola-anchor&quot; href=&quot;#which-key&quot; aria-label=&quot;Anchor link for: which-key&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;emacs-which-key.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;justbur&#x2F;emacs-which-key&quot;&gt;Which-key&lt;&#x2F;a&gt; displays the key
bindings following your currently entered incomplete command. That way,
when you can&#x27;t remember which key to press, you&#x27;ll have a cheat sheet in
a couple of seconds.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;common_lisp&quot; class=&quot;language-common_lisp z-code&quot;&gt;&lt;code class=&quot;language-common_lisp&quot; data-lang=&quot;common_lisp&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(use-package which-key
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;:config (which-key-mode))
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;auto-reload-stuff&quot;&gt;Auto-reload stuff&lt;a class=&quot;zola-anchor&quot; href=&quot;#auto-reload-stuff&quot; aria-label=&quot;Anchor link for: auto-reload-stuff&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;When using version control, files generally change while having them
open in the editor. If this happens, I expect my editor to refresh the
files so that I don&#x27;t write on an old version. Emacs doesn&#x27;t enable this
behavior by default, rather letting the user decide if they want to
reload files. Instead, we can set it to automatically reload files from
disk when changed via these configuration lines (source: &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;pragmaticemacs.com&#x2F;emacs&#x2F;automatically-revert-buffers&#x2F;&quot;&gt;Pragmatic
Emacs&lt;&#x2F;a&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;common_lisp&quot; class=&quot;language-common_lisp z-code&quot;&gt;&lt;code class=&quot;language-common_lisp&quot; data-lang=&quot;common_lisp&quot;&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(global-auto-revert-mode 1)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(add-hook &amp;#39;dired-mode-hook &amp;#39;auto-revert-mode)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;{:.note}
The &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;magit.vc&#x2F;&quot;&gt;magit&lt;&#x2F;a&gt; plugin for version control with git does
refresh the files without the need for this configuration (thanks &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;ncordon.github.io&#x2F;&quot;&gt;Nacho&lt;&#x2F;a&gt;
for the remark!).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;still-want-more&quot;&gt;Still want more?&lt;a class=&quot;zola-anchor&quot; href=&quot;#still-want-more&quot; aria-label=&quot;Anchor link for: still-want-more&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;These are the main tools that have eased my way into Emacs. You can check out the rest of my configuration in &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fdavidcl&#x2F;dotfiles&#x2F;tree&#x2F;master&#x2F;emacs&quot;&gt;my dotfiles repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Sincronizando notas entre PC y móvil mediante Orgzly y Syncthing</title>
		<published>2017-03-05T00:00:00+00:00</published>
		<updated>2017-03-05T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/sincronizar-org/" type="text/html"/>
		<id>https://dch.lu/posts/sincronizar-org/</id>
		<content type="html">&lt;p&gt;Uno de los sistemas más versátiles que existen para organización personal y gestión de tareas es &lt;em&gt;org-mode&lt;&#x2F;em&gt; de Emacs, un modo de este editor que proporciona comodidades útiles tanto para tomar notas rápidas como incluso &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;m42.github.io&#x2F;blog&#x2F;2016&#x2F;09&#x2F;26&#x2F;matematicas-en-emacs&#x2F;&quot;&gt;escribir unos apuntes con fórmulas matemáticas&lt;&#x2F;a&gt;. Esencialmente, aunque cuesta trabajo empezar a usarlo, tiene más utilidades y plugins que la mayoría de &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Wenger-16999-Swiss-Knife-Giant&#x2F;product-reviews&#x2F;B001DZTJRQ&#x2F;ref=cm_cr_arp_d_viewopt_rvwer?pageNumber=1&amp;amp;filterByStar=positive&amp;amp;reviewerType=all_reviews&quot;&gt;navajas suizas&lt;&#x2F;a&gt;, por lo que no es muy difícil encontrar una forma cómoda de aprovechar unas cuantas para organizarse.&lt;&#x2F;p&gt;
&lt;p&gt;Para llevar un sistema basado en &lt;em&gt;org&lt;&#x2F;em&gt; en el móvil existe &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;www.orgzly.com&#x2F;&quot;&gt;Orgzly&lt;&#x2F;a&gt;, una aplicación de Android que da una interfaz intuitiva mediante botones y gestos, pero que internamente utiliza el formato de &lt;em&gt;org&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;{:.fig.medium}
&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;orgzly.png&quot; alt=&quot;&quot; &#x2F;&gt;
Orgzly en funcionamiento&lt;&#x2F;p&gt;
&lt;p&gt;La pregunta que nos vendría a la mente a todos sería si podemos tener el mismo archivo de &lt;em&gt;org&lt;&#x2F;em&gt; sincronizado entre nuestros dispositivos con Emacs y Orgzly. El problema al que llegamos es que el único sistema de sincronización que ofrece Orgzly es a través de Dropbox y, aparte de las preocupaciones por seguridad y privacidad que nos podrían surgir, en realidad es totalmente innecesario tener nuestro archivo almacenado en la nube.&lt;&#x2F;p&gt;
&lt;p&gt;La solución que he encontrado es usar &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;syncthing.net&#x2F;&quot;&gt;Syncthing, un sistema de sincronización P2P de código libre&lt;&#x2F;a&gt;. Para ello simplemente tendremos que instalar la app de Syncthing en los dispositivos Android y la versión del programa correspondiente a nuestro sistema operativo para el PC.&lt;&#x2F;p&gt;
&lt;p&gt;{:.note}
En Arch Linux basta ejecutar &lt;code&gt;pacman -S syncthing&lt;&#x2F;code&gt;. Además, conviene añadirlo al arranque del sistema con &lt;code&gt;systemctl --user enable syncthing&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;En la versión de PC, Syncthing generalmente inicializará una carpeta por defecto. Podemos mover ahí nuestro archivo &lt;em&gt;org&lt;&#x2F;em&gt;. Para hacer que se comuniquen los dispositivos entre sí, desde la interfaz web disponible en &lt;code&gt;localhost:8384&lt;&#x2F;code&gt; mostramos el ID desde &lt;em&gt;Options&lt;&#x2F;em&gt; → &lt;em&gt;Show ID&lt;&#x2F;em&gt; y escaneamos el código QR desde el móvil en la pantalla de &lt;em&gt;Nuevo dispositivo&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;{:.fig.medium}
&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;syncthing-add.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Una vez hecho esto, la app avisará de que el PC quiere comenzar a sincronizar la carpeta por defecto. Aceptamos la solicitud y asignamos una ruta dentro de los archivos del teléfono, para almacenar esa carpeta. Syncthing descargará en esa ubicación los archivos que hayamos copiado en el ordenador, y los volverá a enviar a este cuando realicemos cambios.&lt;&#x2F;p&gt;
&lt;p&gt;{:.fig.medium}
&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;syncthing-pc.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;El último paso es configurar a Orgzly para que lea y escriba de esa carpeta. Para esto entramos en la configuración de la aplicación, y bajo &lt;em&gt;Sync&lt;&#x2F;em&gt; seleccionamos &lt;em&gt;Repositories&lt;&#x2F;em&gt; → &lt;em&gt;Directory&lt;&#x2F;em&gt;. Escogemos la ruta que definimos antes para el almacenamiento de Syncthing. A partir de ahora, Orgzly guardará en ese directorio los archivos &lt;em&gt;org&lt;&#x2F;em&gt; que cree, y leerá los nuevos archivos que aparezcan.&lt;&#x2F;p&gt;
&lt;p&gt;{:.fig.medium}
&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;orgzly-repos.jpg&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Por último, Syncthing permite sincronizar datos entre muchos dispositivos y ser relativamente selectivo en cuanto a qué se sincroniza con cada uno. Así, nuestros archivos de &lt;em&gt;org&lt;&#x2F;em&gt; pueden estar siempre actualizados vayamos donde vayamos, y sin necesidad de almacenarlos permanentemente en servidores externos.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Métodos de aproximación en Ruby</title>
		<published>2017-01-28T00:00:00+00:00</published>
		<updated>2017-01-28T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/aproximadores-ruby/" type="text/html"/>
		<id>https://dch.lu/posts/aproximadores-ruby/</id>
		<content type="html">&lt;p&gt;Entre las tareas de una práctica para la asignatura de Mecánica
Celeste (todo
el
&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fdavidcl&#x2F;celeste&quot;&gt;código disponible en GitHub&lt;&#x2F;a&gt;),
he tenido que programar un par de métodos numéricos de aproximación
iterativos. Resultó ser una aplicación muy práctica de los
&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;tux.ugr.es&#x2F;libreim&#x2F;blog&#x2F;2015&#x2F;08&#x2F;24&#x2F;ruby-enumerators&#x2F;&quot;&gt;enumerables de Ruby&lt;&#x2F;a&gt; y
me parece un buen ejemplo del ahorro de código que puede suponer su uso.&lt;&#x2F;p&gt;
&lt;p&gt;Para abstraer distintos métodos iterativos de aproximación, definí una
clase abstracta &lt;code&gt;Approximator&lt;&#x2F;code&gt; de la que derivarían el resto. Permite
almacenar la aproximación actual y la tolerancia o error que se quiera
aceptar. Las clases derivadas implementan el método &lt;code&gt;next_one&lt;&#x2F;code&gt; que
calcula la siguiente aproximación a partir de la actual.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Clase base para métodos numéricos de aproximación de funciones
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-class z-ruby&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-name z-class z-ruby&quot;&gt;Approximator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Datos miembro
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - current:   valor de la aproximación actual
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - tolerance: valor de tolerancia
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;attr_accessor&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;current&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;tolerance&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;initialize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;tolerance&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt; &lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;DEFAULT_TOLERANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;current &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; initial
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;tolerance &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; tolerance
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Método a implementar en las clases hijas
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;next_one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;raise&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;NotImplementedError&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;El punto clave para aprovechar la potencia de los enumeradores es
implementar un método &lt;code&gt;each&lt;&#x2F;code&gt; que haga uso de la función &lt;code&gt;yield&lt;&#x2F;code&gt; para
proporcionar los resultados parciales. En este caso, proporciona la
aproximación encontrada en cada iteración. Lo interesante de &lt;code&gt;yield&lt;&#x2F;code&gt;
es que no devuelve el control al método hasta que se necesita un nuevo
resultado, de forma que sólo se realizan los cálculos necesarios. Por
ejemplo, podría haber implementado (y lo hice, al principio) el método
&lt;code&gt;each&lt;&#x2F;code&gt; como un &lt;code&gt;loop&lt;&#x2F;code&gt; infinito, sin condición de parada, y podría
iterar las veces necesarias para obtener una precisión arbitraria
(suponiendo convergencia del método). Sin embargo, para poder hacer un
uso práctico de las clases, añadí la condición de parada con la
tolerancia.&lt;&#x2F;p&gt;
&lt;p&gt;Una vez implementado &lt;code&gt;each&lt;&#x2F;code&gt;, basta con incluir el módulo &lt;code&gt;Enumerable&lt;&#x2F;code&gt;
que añade toda la funcionalidad de los enumeradores, como &lt;code&gt;to_a&lt;&#x2F;code&gt; que
acumula en un array todos los elementos devueltos por &lt;code&gt;each&lt;&#x2F;code&gt;. Así,
para calcular la mejor aproximación basta con devolver el último
elemento de ese array.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-class z-ruby&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-name z-class z-ruby&quot;&gt;Approximator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Método que calcula y proporciona aproximaciones
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;each&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    previous &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;Float&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-double-colon z-ruby&quot;&gt;::&lt;&#x2F;span&gt;INFINITY
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;until&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;current &lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt; previous&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;abs &lt;span class=&quot;z-keyword z-operator z-comparison z-ruby&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; tolerance
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;      &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Proporciona una aproximación y espera a que se
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;      &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; pida la siguiente
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;      &lt;span class=&quot;z-keyword z-control z-pseudo-method z-ruby&quot;&gt;yield&lt;&#x2F;span&gt; current
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;      previous &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; current
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;      &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;current &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; next_one
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Incluimos herramientas que permiten enumerar
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; las aproximaciones
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;include&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;Enumerable&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Método que devuelve la última aproximación
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; para la tolerancia dada
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;approximate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;to_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;last
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Además de consultar la mejor aproximación, podremos realizar otras
tareas como obtener una lista de &lt;em&gt;n&lt;&#x2F;em&gt; iteraciones con &lt;code&gt;take(n)&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Por último, basta implementar especializaciones de esta clase con
métodos de aproximación concretos. El siguiente es el método de
Newton-Raphson, que permite calcular raíces de funciones a partir de
sucesivas evaluaciones en la función y en su derivada.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-class z-ruby&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-name z-class z-ruby&quot;&gt;NewtonRaphson&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-inheritance z-ruby&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-other z-inherited-class z-ruby&quot;&gt;Approximator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Datos miembro
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - function:   almacena la función f
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - derivative: almacena la derivada de f
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;attr_accessor&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;derivative&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;initialize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;initial&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;tolerance&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt; &lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;DEFAULT_TOLERANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;derivative&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-pseudo-method z-ruby&quot;&gt;super&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;initial&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; tolerance&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;function &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; function
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;derivative &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; derivative
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;next_one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Método de Newton-Raphson para encontrar raíces:
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Calcula Φ(current) = current - f(current)&#x2F;f&amp;#39;(current)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    current &lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt; function&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;call&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;current&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;derivative&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;call&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;current&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Un ejemplo de uso de esta implementación sería el cálculo de la raíz
cuadrada de 5, como la raíz del polinomio correspondiente:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;example &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;NewtonRaphson&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-constant z-numeric z-float z-decimal z-ruby&quot;&gt;3&lt;span class=&quot;z-punctuation z-separator z-decimal z-ruby&quot;&gt;.&lt;&#x2F;span&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-comparison z-ruby&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;x&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; x&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;**&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;2&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;5&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-comparison z-ruby&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;x&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;*&lt;&#x2F;span&gt;x &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;example&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;approximate
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;=&amp;gt; 2.23606797749979
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Otra especialización es la aproximación de la suma de una serie
convergente, a partir de una función que evalúe el n-ésimo término:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-class z-ruby&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-name z-class z-ruby&quot;&gt;SeriesApproximator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-inheritance z-ruby&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-ruby&quot;&gt;&lt;span class=&quot;z-entity z-other z-inherited-class z-ruby&quot;&gt;Approximator&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Datos miembro
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - term: función que evalúa el término n-ésimo de la serie
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;  - n: índice del término actual se la serie
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;attr_accessor&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;term&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;n&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;initialize&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;tolerance&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-ruby&quot;&gt; &lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;DEFAULT_TOLERANCE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;term&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-pseudo-method z-ruby&quot;&gt;super&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; tolerance&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;term &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; term
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;n &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Calcula el siguiente término de la serie y lo suma a
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; la aproximación actual
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;next_one&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;n &lt;span class=&quot;z-keyword z-operator z-assignment z-augmented z-ruby&quot;&gt;+=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-variable z-language z-ruby&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;current &lt;span class=&quot;z-keyword z-operator z-assignment z-augmented z-ruby&quot;&gt;+=&lt;&#x2F;span&gt; term&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;call&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;n&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Podemos usarla para calcular la suma de Σ1&#x2F;2^n:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;series &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;SeriesApproximator&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-comparison z-ruby&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;n&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-float z-decimal z-ruby&quot;&gt;1&lt;span class=&quot;z-punctuation z-separator z-decimal z-ruby&quot;&gt;.&lt;&#x2F;span&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-ruby&quot;&gt;**&lt;&#x2F;span&gt;n &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;series&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;approximate
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt;=&amp;gt; 0.999999999998181
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;En particular, las sumas de series nos pueden permitir aproximar los
valores de algunas funciones en diversos puntos, utilizando
por ejemplo &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fourier_series&quot;&gt;desarrollos de Fourier&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Y si habéis leído hasta aquí, ¡gracias! Espero que os haya parecido útil
y os sirva para aprovechar los enumerables en otros proyectos.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Un sistema de contribuciones a blogs Jekyll para gente sin conocimientos de Jekyll, GitHub o Markdown</title>
		<published>2016-08-22T00:00:00+00:00</published>
		<updated>2016-08-22T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/jekyll-formularios/" type="text/html"/>
		<id>https://dch.lu/posts/jekyll-formularios/</id>
		<content type="html">&lt;p&gt;Durante un tiempo, los colaboradores del &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;tux.ugr.es&#x2F;dgiim&#x2F;blog&quot;&gt;blog de LibreIM&lt;&#x2F;a&gt; hemos tenido que componer los posts prácticamente a mano, haciendo uso de un editor de texto para escribirlos, Git para llevar el registro de cambios y una &lt;em&gt;pull request&lt;&#x2F;em&gt; en GitHub para enviar el post, revisarlo y corregirlo. Evidentemente, este puede ser un proceso ideal para desarrolladores acostumbrados al proceso, pero está lejos de ser perfecto cuando tratamos de mantener un blog colaborativo abierto a que cualquiera publique su conocimiento. Lo que buscamos es una forma de abstraer el proceso de edición y envío de posts para hacer el blog accesible a mucha más gente.&lt;&#x2F;p&gt;
&lt;p&gt;La solución que concebimos consta de dos partes: por un lado, un backend que utilizaría una cuenta &lt;em&gt;bot&lt;&#x2F;em&gt; de GitHub para la gestión automática de ramas y &lt;em&gt;pull requests&lt;&#x2F;em&gt;; por otro, una aplicación web con un formulario y un sencillo editor desde la que se enviarían los posts.&lt;&#x2F;p&gt;
&lt;p&gt;{:.fig}
&lt;img src=&quot;&#x2F;assets&#x2F;images&#x2F;jekyll-form.png&quot; alt=&quot;Formulario resultante&quot; &#x2F;&gt;
Un ejemplo del &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;tux.ugr.es&#x2F;dgiim&#x2F;new&#x2F;post&quot;&gt;formulario resultante&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;preparativos-previos&quot;&gt;Preparativos previos&lt;a class=&quot;zola-anchor&quot; href=&quot;#preparativos-previos&quot; aria-label=&quot;Anchor link for: preparativos-previos&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Para crear nuevos &lt;em&gt;commits&lt;&#x2F;em&gt; y &lt;em&gt;pull requests&lt;&#x2F;em&gt; necesitamos una cuenta de GitHub. Podemos usar la propia o crear una nueva. Otorgaremos a dicha cuenta permisos de escritura sobre el repositorio de blog en cuestión. Después, obtendremos un &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;settings&#x2F;tokens&quot;&gt;token de acceso personal&lt;&#x2F;a&gt; con permisos de modificación de repositorios. Dicho token lo almacenaremos en las variables de entorno de la shell donde vayamos a hospedar la aplicación, supongamos que bajo el nombre de &lt;code&gt;GITHUB_TOKEN&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;el-backend&quot;&gt;El backend&lt;a class=&quot;zola-anchor&quot; href=&quot;#el-backend&quot; aria-label=&quot;Anchor link for: el-backend&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Componer un guion que trabaje con Git automáticamente no es muy complicado. Se podría utilizar directamente un guion de Bash pero, en vistas a integrarlo en la aplicación web, usamos la &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;rubygems.org&#x2F;gems&#x2F;git&quot;&gt;gema git&lt;&#x2F;a&gt; para Ruby. Esta permite realizar todo tipo de operaciones sobre repositorios Git, a nosotros nos basta con clonar, abrir una nueva rama, incluir un nuevo archivo en un &lt;em&gt;commit&lt;&#x2F;em&gt; y enviarlo al repositorio remoto. El siguiente código Ruby define una función que realiza todo el proceso, notemos cómo se obtiene por parámetro un &lt;em&gt;block&lt;&#x2F;em&gt; (similar a una función anónima) que permite realizar las modificaciones pertinentes al repositorio:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; repo.rb
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;fileutils&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;git&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-def z-ruby&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-ruby&quot;&gt;modify_repo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-ruby&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;head&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;commit_msg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-ruby&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;block&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  dir &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;.repo&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Usamos el token de acceso para clonar el repositorio
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Git&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-environment-variable z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;ENV&lt;&#x2F;span&gt;[&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;GITHUB_TOKEN&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;@github.com&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;repo&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;.git&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; dir&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Configuramos el email y nombre de la cuenta bot
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;config&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;user.name&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;BOT&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;config&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;user.email&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;BOT_EMAIL@example.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Creamos una rama nueva
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;branch&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;head&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;checkout
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Realizamos modificaciones en el repo
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;chdir &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;{&lt;&#x2F;span&gt; block&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;call &lt;span class=&quot;z-punctuation z-section z-scope z-ruby&quot;&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Commit y push
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;add&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;all&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-ruby&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;commit&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;commit_msg&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  g&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;push&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;origin&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; head&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;FileUtils&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;rm_rf&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;dir&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ahora hemos de añadir la capacidad de crear &lt;em&gt;pull requests&lt;&#x2F;em&gt;, para ello usamos la &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;rubygems.org&#x2F;gems&#x2F;octokit&quot;&gt;gema octokit&lt;&#x2F;a&gt;, que acepta el token de acceso que obtuvimos antes:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; form.rb
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;octokit&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require_relative&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;repo&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;github &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Octokit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-double-colon z-ruby&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Client&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;access_token&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-key-value z-ruby&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-environment-variable z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;ENV&lt;&#x2F;span&gt;[&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;GITHUB_TOKEN&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;repo &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;BOT&#x2F;blog&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;base &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;gh-pages&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;head &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;new-post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;modify_repo repo&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; head&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Nuevo post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Creación del nuevo post
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;response &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; github&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;create_pull_request&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;repo&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; base&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; head&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Nuevo post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Únicamente nos queda obtener del usuario los datos necesarios para crear un nuevo post: un titulo, un autor, una categoría y el contenido.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;el-formulario&quot;&gt;El formulario&lt;a class=&quot;zola-anchor&quot; href=&quot;#el-formulario&quot; aria-label=&quot;Anchor link for: el-formulario&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;sinatra&quot;&gt;Sinatra&lt;a class=&quot;zola-anchor&quot; href=&quot;#sinatra&quot; aria-label=&quot;Anchor link for: sinatra&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;www.sinatrarb.com&#x2F;&quot;&gt;Sinatra&lt;&#x2F;a&gt; es un &lt;em&gt;domain specific language&lt;&#x2F;em&gt; (DSL) para Ruby que facilita la creación de aplicaciones web sencillas sin apenas esfuerzo. Basta con escribir las peticiones HTTP que se aceptan y cuál es la respuesta. Además, es muy útil utilizarlo junto a otras gemas de Ruby que ahorren trabajo a la hora de escribir las plantillas y el estilo. Nuestro archivo de dependencias &lt;code&gt;Gemfile&lt;&#x2F;code&gt; queda de la siguiente forma:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Gemfile
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;source &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;rubygems.org&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;sinatra&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;sinatra-contrib&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;thin&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;      &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Web server
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;haml&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;      &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; For layouts
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;sass&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;      &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; For stylesheets
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;kramdown&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; For the preview
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;rouge&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;     &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; For syntax highlighting
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;octokit&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;   &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; For pull requests
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;git&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;       &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Repo management
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;gem&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;recaptcha&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Some protection against bots
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para instalar y manejar las dependencias usamos &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;bundler.io&#x2F;&quot;&gt;Bundler&lt;&#x2F;a&gt;: basta así con ejecutar &lt;code&gt;gem install bundler&lt;&#x2F;code&gt; y tras esto &lt;code&gt;bundle install&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;respondiendo-a-peticiones&quot;&gt;Respondiendo a peticiones&lt;a class=&quot;zola-anchor&quot; href=&quot;#respondiendo-a-peticiones&quot; aria-label=&quot;Anchor link for: respondiendo-a-peticiones&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Vamos a ampliar el archivo &lt;code&gt;form.rb&lt;&#x2F;code&gt; creado anteriormente para aceptar y responder un par de peticiones HTTP. Responderemos a &lt;code&gt;GET &#x2F;&lt;&#x2F;code&gt; mostrando el formulario, que crearemos aparte en una vista en Haml. Por otro lado, al enviar dicho formulario se creará una petición &lt;code&gt;POST &#x2F;posts&lt;&#x2F;code&gt; con los datos que necesitamos para componer el nuevo post.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haml&quot; class=&quot;language-haml z-code&quot;&gt;&lt;code class=&quot;language-haml&quot; data-lang=&quot;haml&quot;&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-line z-ruby z-haml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-line z-ruby z-haml&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;# views&#x2F;form.haml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;h1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; Nuevo post
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;action&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;posts&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;method&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;type&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;text&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;name&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;title&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;placeholder&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Título&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;type&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;text&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;name&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;author&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;placeholder&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Autor 1, Autor 2, ...&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;type&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;text&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;name&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;category&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;placeholder&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Categoría&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;textarea&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;name&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;content&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;placeholder&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Contenido&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;input&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;type&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;submit&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;value&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Enviar&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; form.rb
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;rubygems&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;bundler&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Bundler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;default&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-require z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;require_relative&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;repo&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;get &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Mostramos el formulario
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  haml &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;form&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;post &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;posts&#x2F;?&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Obtenemos los datos
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  title &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;params[:title]&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  author &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;params[:author]&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  content &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;params[:content]&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  category &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; params&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;category&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;]&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-ruby&quot;&gt;||&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;unclassified&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Creamos el nombre del archivo
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  date &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;today&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;strftime &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-placeholder z-ruby&quot;&gt;%Y&lt;&#x2F;span&gt;-&lt;span class=&quot;z-constant z-other z-placeholder z-ruby&quot;&gt;%m&lt;&#x2F;span&gt;-&lt;span class=&quot;z-constant z-other z-placeholder z-ruby&quot;&gt;%d&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  filename &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; title&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;downcase&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;split&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-range z-ruby&quot;&gt;..&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-ruby&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;join&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;-&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  github &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Octokit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-double-colon z-ruby&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Client&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;access_token&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-key-value z-ruby&quot;&gt;=&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-environment-variable z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-ruby&quot;&gt;ENV&lt;&#x2F;span&gt;[&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;GITHUB_TOKEN&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  repo &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;BOT&#x2F;blog&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  base &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;gh-pages&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  head &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;new-post-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  modify_repo repo&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; head&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Nuevo post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; Creamos el archivo del post
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;File&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-builtin z-ruby&quot;&gt;open&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;_posts&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;date&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;filename&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;.md&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;w&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-begin z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-ruby&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-parameters z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameters z-end z-ruby&quot;&gt;|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;        f&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;write &lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;lt;&amp;lt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;+++
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;title = &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;title&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;authors = &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;author&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;split &lt;span class=&quot;z-meta z-string z-regexp z-ruby&quot;&gt;&lt;span class=&quot;z-string z-regexp z-classic z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;,&lt;span class=&quot;z-constant z-character z-escape z-ruby&quot;&gt;\s&lt;&#x2F;span&gt;*&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;category = &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;category&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;+++
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-begin z-ruby&quot;&gt;#{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-interpolation z-ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-ruby&quot;&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-interpolation z-end z-ruby&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-meta z-string z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-heredoc z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;EOF&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  response &lt;span class=&quot;z-keyword z-operator z-assignment z-ruby&quot;&gt;=&lt;&#x2F;span&gt; github&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;create_pull_request&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;repo&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; base&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; head&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Nuevo post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Para iniciar el servidor web con nuestra aplicación, debería bastar con ejecutar &lt;code&gt;ruby form.rb&lt;&#x2F;code&gt; en el terminal.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;anadiendo-un-editor-de-verdad&quot;&gt;Añadiendo un editor de verdad&lt;a class=&quot;zola-anchor&quot; href=&quot;#anadiendo-un-editor-de-verdad&quot; aria-label=&quot;Anchor link for: anadiendo-un-editor-de-verdad&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Todo esto ya está muy bien, y la aplicación ahorra un montón de esfuerzo para cada vez que se crea un nuevo post. Pero aún queda una barrera que evitaría que algunos usuarios estuvieran cómodos escribiendo: el marcado de formato con Markdown. Existen diversos editores Markdown que pueden incrustarse en una página web, algunos con amplias funcionalidades y otros más sencillos. Nosotros optamos por &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;simplemde.com&#x2F;&quot;&gt;SimpleMDE&lt;&#x2F;a&gt;, que facilita la escritura mediante algunas pistas visuales en el código y unos botones que dan acceso a la mayoría de opciones de formato de Markdown.&lt;&#x2F;p&gt;
&lt;p&gt;Este editor aporta además una opción de previsualización personalizable, lo que quiere decir que podemos modificar la forma en que se compila el código Markdown y se muestra dicha vista previa. Como los blogs Jekyll usan el intérprete &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;kramdown.gettalong.org&#x2F;&quot;&gt;Kramdown&lt;&#x2F;a&gt; por defecto, podemos añadir una ruta al servidor que compile un documento mediante esta herramienta. Además, utilizamos también la gema &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;rouge.jneen.net&#x2F;&quot;&gt;Rouge&lt;&#x2F;a&gt; para resaltado de código.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ruby&quot; class=&quot;language-ruby z-code&quot;&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; form.rb
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-ruby&quot;&gt;#&lt;&#x2F;span&gt; ...
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;post &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;preview&#x2F;?&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-start-block z-ruby&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;  &lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Kramdown&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-double-colon z-ruby&quot;&gt;::&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-class z-ruby&quot;&gt;Document&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-other z-special-method z-ruby&quot;&gt;new&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-begin z-ruby&quot;&gt;(&lt;&#x2F;span&gt;params&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;content&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-array z-ruby&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;syntax_highlighter&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;rouge&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-group z-end z-ruby&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-ruby&quot;&gt;.&lt;&#x2F;span&gt;to_html
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-ruby&quot;&gt;&lt;span class=&quot;z-keyword z-control z-ruby&quot;&gt;end&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Por otro lado, el editor habrá que inicializarlo mediante un código similar al siguiente:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;haml&quot; class=&quot;language-haml z-code&quot;&gt;&lt;code class=&quot;language-haml&quot; data-lang=&quot;haml&quot;&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;action&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;posts&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;method&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;post&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-line z-ruby z-haml&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-line z-ruby z-haml&quot;&gt;&lt;span class=&quot;z-source z-ruby z-embedded z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-ruby&quot;&gt;# ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  &lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;textarea&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-id z-haml&quot;&gt;#markdown_editor&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;name&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;content&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;placeholder&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Contenido&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;link&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;rel&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;stylesheet&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-ruby&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;href&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;cdn.jsdelivr.net&#x2F;simplemde&#x2F;latest&#x2F;simplemde.min.css&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-haml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-haml&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-haml&quot;&gt;script&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-section z-attributes z-haml&quot;&gt;{&lt;span class=&quot;z-constant z-other z-symbol z-ruby&quot;&gt;src&lt;span class=&quot;z-punctuation z-definition z-constant z-ruby&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-ruby&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-ruby&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;https:&#x2F;&#x2F;cdn.jsdelivr.net&#x2F;simplemde&#x2F;latest&#x2F;simplemde.min.js&lt;span class=&quot;z-punctuation z-definition z-string z-end z-ruby&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;:javascript
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-slash z-haml&quot;&gt;  &lt;span class=&quot;z-punctuation z-section z-comment z-haml&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&#x2F; La típica función para peticiones AJAX
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  function AjaxRequest(url, method, data, callback) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    var xmlhttp;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    if (window.XMLHttpRequest)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      xmlhttp = &amp;quot;new XMLHttpRequest();&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    else
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      xmlhttp = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    xmlhttp.onreadystatechange = &amp;quot;function() {&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      if (xmlhttp.readyState == 4 &amp;amp;&amp;amp; xmlhttp.status == 200) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        if (xmlhttp.responseXML) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;          callback(xmlhttp.responseXML);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        } else {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;          callback(xmlhttp.responseText);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    };
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    xmlhttp.open(method, url, true);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    if (method == &amp;quot;POST&amp;quot;)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      xmlhttp.setRequestHeader(&amp;quot;Content-type&amp;quot;, &amp;quot;application&#x2F;x-www-form-urlencoded&amp;quot;);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    xmlhttp.send(data);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-slash z-haml&quot;&gt;  &lt;span class=&quot;z-punctuation z-section z-comment z-haml&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&#x2F; Inicializa el editor Markdown con algunas opciones extra
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  var simplemde = &amp;quot;new SimpleMDE({&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    element: document.getElementById(&amp;quot;markdown_editor&amp;quot;),
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    blockStyles: {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      code: &amp;quot;~~~&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    },
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-slash z-haml&quot;&gt;    &lt;span class=&quot;z-punctuation z-section z-comment z-haml&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&#x2F; Usa el sistema propio para vista previa (kramdown + rouge)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    previewRender: function(plainText, preview) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-slash z-haml&quot;&gt;      &lt;span class=&quot;z-punctuation z-section z-comment z-haml&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&#x2F; Esperar un segundo sin cambios para hacer la petición
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      if (window.delay)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        clearTimeout(window.delay);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      window.delay = &amp;quot;setTimeout(function() {&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        AjaxRequest(&amp;quot;&#x2F;preview&amp;quot;, &amp;quot;POST&amp;quot;, &amp;quot;content=&amp;quot; + encodeURIComponent(plainText), function(response) {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;&lt;span class=&quot;z-comment z-line z-slash z-haml&quot;&gt;          &lt;span class=&quot;z-punctuation z-section z-comment z-haml&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&#x2F; `preview` es el nodo que contiene la vista previa
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;          preview.innerHTML = &amp;quot;response;&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;        });
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      }, 1000);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;      return preview.innerHTML;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-haml&quot;&gt;  });
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ahora sí, con todo esto tenemos un editor que facilita la tarea de escribir un post a cualquiera.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;los-extras&quot;&gt;Los extras&lt;a class=&quot;zola-anchor&quot; href=&quot;#los-extras&quot; aria-label=&quot;Anchor link for: los-extras&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Un par de funcionalidades adicionales que hemos utilizado en &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;tux.ugr.es&#x2F;dgiim&#x2F;new&#x2F;post&quot;&gt;el formulario para LibreIM&lt;&#x2F;a&gt; son la inclusión de &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;http:&#x2F;&#x2F;mathjax.org&#x2F;&quot;&gt;MathJax&lt;&#x2F;a&gt; para interpretar fórmulas en LaTeX, y de un CAPTCHA mediante la gema &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;rubygems.org&#x2F;gems&#x2F;recaptcha&#x2F;&quot;&gt;recaptcha&lt;&#x2F;a&gt;. No entro aquí en más detalle porque son fáciles de usar; además, todo nuestro código está &lt;a rel=&quot;nofollow noreferrer&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;libreim&#x2F;form-im&quot;&gt;publicado en GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;en-conclusion&quot;&gt;En conclusión...&lt;a class=&quot;zola-anchor&quot; href=&quot;#en-conclusion&quot; aria-label=&quot;Anchor link for: en-conclusion&quot; style=&quot;visibility: hidden;&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Mantener un blog en Jekyll tiene muchas ventajas: se puede hostear en cualquier servidor ya que es un generador de sitios estáticos, se puede realizar control de cambios por Git, etc. Y, con un poco de trabajo y una pequeña aplicación web, también se puede hacer accesible la colaboración a cualquier persona, incluso sin conocimientos de GitHub, Jekyll o Markdown. Ahora queda la parte complicada: convencer a más personas para que contribuyan al blog ;)&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Iterating in Ruby: Enumerable and Enumerators</title>
		<published>2015-08-24T00:00:00+00:00</published>
		<updated>2015-08-24T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/iterating-ruby/" type="text/html"/>
		<id>https://dch.lu/posts/iterating-ruby/</id>
		<content type="html"></content>
	</entry>
	<entry xml:lang="en">
		<title>Introducción a JavaScript. Programación con prototipos</title>
		<published>2014-06-24T00:00:00+00:00</published>
		<updated>2014-06-24T00:00:00+00:00</updated>
		<link href="https://dch.lu/posts/javascript-proto/" type="text/html"/>
		<id>https://dch.lu/posts/javascript-proto/</id>
		<content type="html"></content>
	</entry>
</feed>