<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Frank Riccobono</title>
    <description>The latest articles on DEV Community by Frank Riccobono (@aelfric5578).</description>
    <link>https://dev.to/aelfric5578</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F215195%2F0cd22fe5-e464-43be-b017-55736a5c70d7.jpeg</url>
      <title>DEV Community: Frank Riccobono</title>
      <link>https://dev.to/aelfric5578</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aelfric5578"/>
    <language>en</language>
    <item>
      <title>But What About the Trophies?</title>
      <dc:creator>Frank Riccobono</dc:creator>
      <pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate>
      <link>https://dev.to/aelfric5578/but-what-about-the-trophies-5bp1</link>
      <guid>https://dev.to/aelfric5578/but-what-about-the-trophies-5bp1</guid>
      <description>&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;It was the fall of 2020. A new school year had just started, but amidst the continuing pandemic safety measures, we in the speech and debate community were wondering whether we would be able to continue the activity in some form or another. Thanks to a video platform developed that summer by the National Speech and Debate Association, we were fairly confident we could hold virtual tournaments, but we had another practical issue: how would we recognize the winners?&lt;/p&gt;

&lt;p&gt;Speech and debate is primarily an educational activity. We don’t encourage students to participate for the trophies, but at the same time, doing well at a tournament is difficult. We still wanted to reward these students for their success. Trophies were the league’s largest expense when running in-person tournaments, and mailing them out after virtual tournaments would have been prohibitive.&lt;/p&gt;

&lt;p&gt;Our league director came to me with an idea: certificates. More specifically, we needed a way to generate hundreds of printable certificates automatically, personalize them, and distribute them digitally. Here’s how I did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout
&lt;/h2&gt;

&lt;p&gt;Maybe I was just biased from years of working in web development, but when I looked at the sample certificates we had printed, I saw a familiar box model.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxuwsudue9rz4jm2e7ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxuwsudue9rz4jm2e7ej.png" alt="The original reference image for a certificate" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The layout was primarily centered text with some borders and spacing. I decided to use HTML and CSS. A certificate can be represented as just a few lines of text and markup. The structure was straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"certificate_border gold finalist"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"certificate_body placement_certificate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"The tournament logo"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/nycfl-logo.svg"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100px"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nycfl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;New York Catholic Forensic League&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"award_certificate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Award Certificate&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_details"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"host"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Regis High School&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;NYCFL First Regis&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;September 26, 2020&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;        
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"place"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;First Place&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"before_text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This certificate is given to&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Jane Doe&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"before_text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;to recognize outstanding performance in the category of&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"event_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Dramatic Performance&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature_block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Thomas Beck&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"position"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;NYCFL President &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"date_block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;09/26/2020&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"date-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Date&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I found a royalty-free guilloché border vector image and found a few suitable web fonts with the right look. My reference certificate was a Word Document based on a print template from an office supply store. When translating a design into HTML/CSS, we usually use units like pixels or REMs, but in this case, it was easier to use inches, a less commonly used unit in web design. That allowed me to make the full size of a certificate to be based on US Letter paper size (8.5 x 11 inches).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8.5in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;11in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fany1megzlg3fpix57y4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fany1megzlg3fpix57y4r.png" alt="Example certificate" width="800" height="618"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because certificates are fixed-size documents, HTML print styles made it easy to produce consistent, printable layouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Templates
&lt;/h2&gt;

&lt;p&gt;The core idea was to extract data from &lt;a href="https://www.tabroom.com" rel="noopener noreferrer"&gt;Tabroom&lt;/a&gt;, the software we used to run tournaments and use it to generate the certificates. Tabroom was built with a programmer’s mindset and makes much of its data available as comma-separated-value (CSV) exports. There were several types of reports we wanted to generate from this data so I decided the best starting point was to parse the files once and import the data into a database.&lt;/p&gt;

&lt;p&gt;The basic workflow would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import CSV results&lt;/li&gt;
&lt;li&gt;Store in database for reuse&lt;/li&gt;
&lt;li&gt;Render certificates using a template&lt;/li&gt;
&lt;li&gt;Export as printable HTML/PDF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I decided to use &lt;a href="https://quarkus.io" rel="noopener noreferrer"&gt;Quarkus&lt;/a&gt; to scaffold the application along with its Qute templating language. Its quick startup time, developer tooling, and simple Jakarta EE API implementations made it a great choice for building a prototype that could evolve into the final product.&lt;/p&gt;

&lt;p&gt;Students compete in one of several categories. For each category, I would get a final results CSV file that looked something like this. I used the Apache Commons CSV library to parse the files.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Ranking&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name 1&lt;/th&gt;
&lt;th&gt;School&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;508&lt;/td&gt;
&lt;td&gt;Jane Doe&lt;/td&gt;
&lt;td&gt;Some Academy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;td&gt;John Smith&lt;/td&gt;
&lt;td&gt;P.S. 1337&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Since I would be the one generating the certificates, I used an H2 file-based database. We were all working remotely so both the application and the database file lived on my desktop. When I needed to generate something, I could start up the application using Quarkus development mode.&lt;/p&gt;

&lt;p&gt;To interact with the application, I created a REST API that could power a small React front end. Below is a simplified version of the JAX-RS resource. Most of the endpoints are general CRUD operations. These endpoints provided for the following workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create a tournament with basic information like the name, date, and virtual host school&lt;/li&gt;
&lt;li&gt;create a list of events in the tournament&lt;/li&gt;
&lt;li&gt;upload the CSV results for each event&lt;/li&gt;
&lt;li&gt;render the certificates into the template
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Consumes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CertificatesResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Inject&lt;/span&gt;
    &lt;span class="nc"&gt;Template&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@POST&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tournaments"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Tournament&lt;/span&gt; &lt;span class="nf"&gt;createTournament&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Tournament&lt;/span&gt; &lt;span class="n"&gt;tournament&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;@POST&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/events"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Tournament&lt;/span&gt; &lt;span class="nf"&gt;createEvents&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EventList&lt;/span&gt; &lt;span class="n"&gt;eventList&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;@POST&lt;/span&gt;
    &lt;span class="nd"&gt;@Consumes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MULTIPART_FORM_DATA&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tournaments/{tournamentId}/events/{eventId}/results"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Tournament&lt;/span&gt; &lt;span class="nf"&gt;addResults&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nd"&gt;@MultipartForm&lt;/span&gt; &lt;span class="nc"&gt;MultipartBody&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"eventId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;eventId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tournamentId"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;tournamentId&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nd"&gt;@GET&lt;/span&gt;
    &lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_HTML&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tournaments/{id}/certificates"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateCertificates&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;tournamentId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;generateCertificates&lt;/code&gt; endpoint would render the Qute template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;'stylesheet'&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;'/certs.css'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
{#for event in tournament.events}
{#for result in event.results}
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"overflow: hidden; height: 8.5in; width: 11in; padding: 0.5in"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"certificate_border {result.certColor}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"certificate_body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/nycfl-logo.svg"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"100px"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nycfl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;New York Catholic Forensic League&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"award_certificate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Award Certificate&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_details"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"host"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{tournament.host}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{tournament.name}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tournament_date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{tournament.longDate}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"place"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{result.placeString}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"before_text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This certificate is given to&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{result.name}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"before_text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;to recognize outstanding performance in the category of&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"event_name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{event.name}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature_block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Thomas Beck&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"position"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;NYCFL President&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"date_block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"signature-date"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;{tournament.shortDate}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"date-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Date&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"page-break-after: always; visibility: hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
{/for}
{/for}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first version of this, I had several border images to produce different placements. Gold for first place, silver for second, bronze for third, red for fourth through sixth place, and light blue for any other finalists. I quickly realized that it would be beneficial to have more flexibility to support more placements and custom designs without maintaining multiple static images. Thankfully, since the border was an SVG file, I could also turn &lt;em&gt;it&lt;/em&gt; into a Qute template as well and add one more endpoint that would adjust colors in the SVG.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@GET&lt;/span&gt;  
&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/background.svg"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"image/svg+xml"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  
&lt;span class="nd"&gt;@PermitAll&lt;/span&gt;  
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getBackgroundImage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;  
    &lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"color"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nd"&gt;@DefaultValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ffffff"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  
    &lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"color2"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nd"&gt;@DefaultValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"323131"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;  
    &lt;span class="nd"&gt;@QueryParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"color3"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nd"&gt;@DefaultValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"323131"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;color3&lt;/span&gt;  
&lt;span class="o"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we could reference this endpoint in CSS like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.certificate_border.gold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('/certs/background.svg?color=D4AF37')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.certificate_border.black&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('/certs/background.svg?color=D8D8FF')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.certificate_border.silver&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('/certs/background.svg?color=C0C0C0')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.certificate_border.bronze&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('/certs/background.svg?color=CD7F32')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.certificate_border.red&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('/certs/background.svg?color=C76C67')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, since the certificates were rendered as HTML, generating PDFs was straightforward. I used Chrome’s built-in “Print to PDF” feature, which handled layout and pagination reliably without needing additional libraries or tooling. While this wasn’t fully automated, it was simple and dependable—and more than sufficient for our needs. For ease of downloading, I uploaded the resulting PDF to an Amazon S3 bucket because the file was too large to email.&lt;/p&gt;

&lt;p&gt;On September 30th, I sent out the first set of certificates for our first online speech tournament, 45 pages altogether, and it was just the beginning. Soon, I needed to accommodate events with other formats, larger tournaments with quarterfinals and semifinals, tournaments for other leagues, and customization for other purposes. The strength of the original implementation was how easy it was to evolve. I’ve since generated certificates and slides (more on that later) for over 150 tournaments, and the software has continued to evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTML and CSS work well for print layouts.&lt;/strong&gt; Browsers provided a reliable and flexible way to generate certificates without specialized tooling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Templates make scaling easy.&lt;/strong&gt; Once the certificate layout was templated, generating hundreds of certificates became trivial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SVGs can be treated as templates too.&lt;/strong&gt; Converting the border into a template made it easy to customize designs without maintaining multiple assets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual steps can be the right starting point.&lt;/strong&gt; Using Chrome’s Print to PDF feature was simple, dependable, and fast to implement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple systems can go a long way.&lt;/strong&gt; A lightweight architecture was enough to support over 150 tournaments and six years of iterative feature development.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>html</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Programmer's Journey</title>
      <dc:creator>Frank Riccobono</dc:creator>
      <pubDate>Sat, 20 Jul 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/aelfric5578/a-programmers-journey-1bd</link>
      <guid>https://dev.to/aelfric5578/a-programmers-journey-1bd</guid>
      <description>&lt;p&gt;I was fortunate to be introduced to computers at an early age. According to an old school report I found in my hoard, we got our first family computer when I was four. You probably wouldn't take my dad for your typical computer geek, but he latched onto the technology when it started transforming the workplace. He, in turn, taught me the basics. By the time I was five years old, I already knew a handful of basic DOS commands. (At that point it was limited to switching directories and launching games – &lt;a href="https://en.wikipedia.org/wiki/Reader_Rabbit" rel="noopener noreferrer"&gt;Reader Rabbit&lt;/a&gt; was an early favorite). By eight, I was using Microsoft Office to write silly short stories and PowerPoint to make “art."&lt;/p&gt;

&lt;p&gt;I started programming almost by accident. Although I liked school and my teachers, I wasn't quite a star student in my earliest primary education. I hated coloring inside the lines, my penmanship was atrocious, and I've always tended towards absent-mindedness. I would forget to do homework or frequently leave books at home. That changed once I got to third grade and even more so by fourth and fifth. That's the point where school became less about learning behaviors and more about acquiring knowledge. I was (and still am) insatiably curious, and this new chapter of education was what I had been waiting for. I was also very impatient. I would look ahead in my textbooks, anxious for the next lesson even before the current one had fully sunken in. What was worse was that many of our books were longer than we'd be able to cover in a school year. I found myself particularly drawn to the final chapters that we would otherwise never see.&lt;/p&gt;

&lt;p&gt;One day in fifth grade, something in the appendix of my math textbook caught my eye. It was an extra credit assignment of sorts written in a mono-spaced font. The instructions said to type the instructions into a program called QBasic, which at that time was still bundled with Windows. I don't quite remember what the program was, but it was something simple like a coin flip simulator. Whatever it was, when I entered the instructions, it worked! I was experiencing some new kind of magic that I didn't fully appreciate at the time. I flipped through the book and found a few more extended code listings and tried them out. I was exclusively following the textbook instructions, though. I had no idea what any of the keywords meant, and it never occurred to me to change anything or to try to write my own program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8ellnpsygaf0wr4eyoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn8ellnpsygaf0wr4eyoq.png" alt="Fake QBasic Screenshot" width="640" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;BASIC...the entrypoint for many a programmer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another joy at that time was the annual Scholastic Book Fair (I’m a nerd if you haven’t figured that out by now). A year or so after my first foray into QBasic, I found a book and accompanying CD at the book fair called&lt;a href="https://www.kotaku.com.au/2016/04/heres-the-movie-interplay-made-in-1998-about-learning-to-program-games/" rel="noopener noreferrer"&gt;“Learn to Program BASIC”&lt;/a&gt; by Interplay. In it, a bizarre-looking cartoon character named Media Man( reminiscent of Clippy) taught you through wacky video clips how to write a dialect of BASIC developed by the game company. I learned about strings, subroutines, sprites, arrays, and much more. I still didn't stray far from the tutorials, but I was able to internalize much of the material. In particular, programming in an XY-coordinate system gave me a leg up in math class when we started learning how to plot various graphs. It also helped in Computers Class where Sr. Blanche was introducing us to Logo.&lt;/p&gt;

&lt;p&gt;LTPB felt more like a video game than a useful tool, though, and I lost interest when I’d finished all the lessons. I still never thought to try creating something original, and I did not do much more than that until another coincidence occurred in high school. I was chatting with a friend at the end of freshman year, and we somehow got into the topic of programming. His father was a programmer, and he was learning Visual Basic 6. I'd never heard of it, but it had Basic in the name, so I assumed it was similar to what I'd seen before. He agreed to teach two other friends and me. The four of us had bold plans to create a video game company that summer, powered by VB6. Those plans never materialized, but I did learn the language and my friend, the ringleader, did write an Apple Catcher game that "went viral" in the sophomore class (before "going viral" was a thing).&lt;/p&gt;

&lt;p&gt;Part of the problem with our ill-fated video game company endeavor was that we couldn’t agree on what type of game to make. I had suggested an RPG, not imagining at the time, how much work was involved. I spent the summer learning a bunch of things including how to do Bit Block Transfers (BitBlt) to remove the backgrounds from sprites (something I missed about LTPB), how to generate tile-based maps, and, most-ambitiously, how to implement the A* path-finding algorithm. When that last one (mostly) worked, I was ecstatic. Mind you, at that time, I still had no sort of formal training.&lt;/p&gt;

&lt;p&gt;Throughout the rest of high school, I dabbled in various other technical things. I learned HTML/CSS in the age of CssZenGarden. I set up a personal website on Tripod and even wrote a few Perl-CGI scripts to automate some of the maintenance of it. My dad found this browser-based 3D game engine from Wild Tangent that allowed you to write in Javascript. I built a few simple websites for a theater company I was working with at the time. One of my favorite TV shows at the time, &lt;a href="https://en.wikipedia.org/wiki/The_Screen_Savers" rel="noopener noreferrer"&gt;&lt;em&gt;The Screensavers&lt;/em&gt;&lt;/a&gt;, introduced me to Linux and I started playing around with that in my spare time. It was all a hobby for me. I had no idea that I could make a career out of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y6q1tuilfvw89rpoa2y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2y6q1tuilfvw89rpoa2y.png" alt="My First Website" width="640" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My first website...what was I thinking?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When the college admissions process started in my junior year, I received an advertisement for a summer program at one of the schools I was considering (Stevens Institute of Technology). The program allowed high school students to take an online college-level class over the summer. I signed up for CS115, Introduction to Computer Science. I didn't know what "computer science" was at the time, but the syllabus mentioned programming, and that was enough for me. The class involved learning Java, which had enough in common with VB6 that I was able to pick it up pretty quickly. That class convinced me to choose the heretofore unknown Computer Science as my major when the time came.&lt;/p&gt;

&lt;p&gt;I ended up attending Stevens for college. It was a blur of languages including C, PHP, Assembly, Scheme, Matlab, MySQL, and even a smidge of COBOL. Like most graduates, I thought all that was everything I needed to know about programming. One concept I later learned was conspicuously missing from the CS course load was the idea of "Legacy Code" and how to work with it.&lt;/p&gt;

&lt;p&gt;My first job out of college had me working with a several-years-old Java project that had been cobbled together by outsourced contractors. I can't say too much about the experience due to confidentiality agreements. It suffices to say that academic knowledge of Java did not prepare me for J2EE, or for making sense of tens of thousands of lines of code and a bunch of terrible variable names. I was not given a lot of guidance since our lead developer worked remotely and only at night. And my conservative inclination left me afraid to change much. I did eventually get to the point where I could contribute to the project. I was writing software for a business, but I had no real sense of what business software engineering entailed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxovof9k0uzixzog8e0l.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjxovof9k0uzixzog8e0l.jpg" alt="Programming in the Real World" width="640" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Programming in the "Real World"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The next milestone didn’t come until three years later. There were two sources. First, I was taking some graduate-level classes in Natural Language Processing, a topic that had long interested me. As bad as corporate code can get, academic code is generally worse. PhDs and grad students typically write software for an upcoming paper and, unless their discipline is software engineering, they usually don't write with maintenance in mind. "Battle-scarred" as I was by the corporate world, I rejected this writing style and strove to try to make any code I wrote for those courses as clean as possible. This goal required reading lots of tutorials outside of class, but I think it paid off. Most of those courses required us to code in Python, and I made an effort to learn the Pythonic way. For the first time, I wasn’t just thinking about whether or not my code worked but also how it was structured.&lt;/p&gt;

&lt;p&gt;The other influence was a part-time gig I took on in between grad school semesters. One of my college professors contacted me regarding an opportunity with a startup looking for an intern. They were developing a Ruby on Rails e-commerce site. Ruby and Python had enough similarities that I was able to pick up the former pretty quickly, but Rails was eye-opening. I had never used a framework. I was fascinated by tools that not only reduced boilerplate code, but that also imposed structure on the application.&lt;/p&gt;

&lt;p&gt;On top of that, the team was also using Capistrano to automate building and deploying the app, and they had AUTOMATED UNIT TESTS through rake! I had used simple makefiles in my college C-programming days, but, for a technology aimed at creating efficiencies, programming and testing of programs always seemed very manual to me. My college professors had even convinced us not to use IDEs when learning because they introduced too much magic. The idea that you could introduce automation and tooling seemed revolutionary.&lt;/p&gt;

&lt;p&gt;In the end, the startup didn't work out (long story for another time, but no hard feelings toward anyone involved). In the meantime, I found myself in the lead developer role for that software product I had started working on after college. The time had come to put some of what I'd recently learned to use. Over the next few years, a junior developer and I worked to wrangle the legacy code. We imposed structure where there was disorder and wrote automated tests where there had been none. It was exciting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fgn57o01lx83y5udna4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fgn57o01lx83y5udna4.png" alt="Test-Driven Development" width="640" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All Hail Test-Driven Development!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Today we’re working on a new system. We’re using technologies like Hibernate in the back-end and React in the front-end. It's been a bit of a paradigm shift from never using any frameworks. There are various challenges and successes every day, but the best part is there is always plenty to learn. I can still be that curious kid, stealing furtive glances at advanced topics, that I was when I started.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
