{"id":23608,"date":"2021-05-15T18:50:56","date_gmt":"2021-05-16T01:50:56","guid":{"rendered":"https:\/\/www.podfeet.com\/blog\/?p=23608"},"modified":"2021-05-21T15:30:06","modified_gmt":"2021-05-21T22:30:06","slug":"knit-like-a-programmer","status":"publish","type":"post","link":"https:\/\/www.podfeet.com\/blog\/2021\/05\/knit-like-a-programmer\/","title":{"rendered":"Knit Like a Programmer"},"content":{"rendered":"<p>After I had written most of this article, I realized that I may have come up with a subject that interests absolutely no one but me. You see, this is about knitting like a programmer. How many of you both program, and knit?  I mentioned this problem to Bart and he explained that there\u2019s a long history of the intersection of programming and textiles.  Bart went on to explain that programming punch cards have their origins in weaving.<\/p>\n<p>He pointed me to a Wikipedia article about the Jacquard machine, which was designed to program a  loom to automate the process of weaving.  From the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Jacquard\\_machine\" target=\"_blank\" rel=\"noopener\">Wikipedia article about the Jacquard machine<\/a>:<\/p>\n<blockquote><p>\n  The machine was controlled by a &#8220;chain of cards&#8221;; a number of punched cards laced together into a continuous sequence. Multiple rows of holes were punched on each card, with one complete card corresponding to one row of the design.\n<\/p><\/blockquote>\n<p>So maybe this intersection of programming and knitting will be of some interest after all.<\/p>\n<p>I\u2019ve been programming for a few years now, but I\u2019ve been knitting since I was very young.  I actually taught myself to knit when I was around 9 years old, learning from a book. I can distinctly remember learning the stockinette stitch at the kitchen table and being SO frustrated until I figured out that the dumb instructions didn\u2019t tell you to move the yarn from back to front to back as you switch from knit to purl and back again.  Once I figured that out it was smooth sailing.<\/p>\n<p>I haven\u2019t knit for a very long time, keeping my fingers busy with crocheting and cross-stitching for at least the last 25 years.  But my daughter-in-law Nikki chose a knitted pattern for the baby blanket I&#8217;m making for my future grandson.  It was time to get back into the game.<\/p>\n<h3>The Problem to be Solved<\/h3>\n<figure style=\"float: right; margin-left: 5px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2021\/05\/Photo-of-Blanket-on-Pattern.jpeg\" alt=\"Photo of Blanket on Pattern\" title=\"#title#\" width=\"300 \" height=\"500\"><figcaption style=\"text-align:center\">Photo of the Actual Desired Blanket<\/figcaption><\/figure>\n<p>Execution of some knitting patterns wouldn\u2019t benefit from thinking like a programmer, but the particular pattern I\u2019m working on cries out for it.  Knitting patterns (and crochet patterns for that matter) will give you row by row instructions, but whenever a complex bit is repeated, they\u2019ll often throw an asterisk on either side and say \u201crepeat from &ast; to &ast;\u201d.<\/p>\n<p>In programming, if you\u2019re going to repeat something, you make it a function so you can repeat it predictably.  Already we can see that knitting and programming have something in common.<\/p>\n<p>The problem I was trying to solve was that this pattern is written in a very complicated way.  This resulted in constant mistakes on my part until I started to break the pattern down in a different way.<\/p>\n<p>If you look at the photo on the cover of the instructions, you see an alternating pattern of big square blocks.  Every other big square block is either checked or striped, and there are four big rows of blocks.  The instructions call these big rows of blocks \u201csets\u201d.  So on the first set, it\u2019s blocks of check\/stripe\/check\/stripe, but on set two it\u2019s stripe\/check\/stripe\/check.<\/p>\n<p>That photo is <em>critical<\/em> to figuring out the pattern, because down in the weeds of the instructions, it&#8217;s very difficult to see this big picture view I&#8217;ve described.<\/p>\n<figure style=\"float: left; margin-right: 5px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2021\/05\/Knitting-Pattern-as-Written.jpeg\" alt=\"Knitting Pattern as Written\" title=\"#title#\" width=\"450 \" height=\"549\"><figcaption style=\"text-align:center\">Knitting Pattern as Written<\/figcaption><\/figure>\n<p>The pattern describes the sets in a very complex way. Let\u2019s say you\u2019re on row 26.<\/p>\n<p>Row 26 isn\u2019t explicitly explained. It says that row 26 is row 21 in the check pattern. Ok, what\u2019s row 21? Well, row 21 is a repeat of row 1 in the check pattern.  I\u2019m not making this up.<\/p>\n<p>I started by creating two lookup tables but it was like doing two coordinate transformations in your head!  I tore out many rows many times.<\/p>\n<p>That\u2019s when I started to think of it as functions and it became much clearer to me.<\/p>\n<p>Let\u2019s think of the check and stripe blocks as functions, because inside each of those blocks, we have a set of instructions. We\u2019re going to call them stripeBlock and checkBlock.<\/p>\n<p><code>function stripeBlock() {do stripe-type stuff}<\/code><\/p>\n<p><code>function checkBlock() {do check-type stuff}<\/code><\/p>\n<h3>StripeBlock<\/h3>\n<aside>And yes, I\u2019ve had a lot of trouble writing the knitting term purl because it\u2019s spelled with a \u201cu\u201d and my brain really wants to write it with an \u201ce\u201d like the programming language.  <\/aside>\n<p>Now let\u2019s dig down inside our two functions.  The instructions for the stripeBlock function defines explicitly what to do on rows 1-8.  All of the even rows (2, 4, 6, and 8) are a simple purl stitch all the way across.<\/p>\n<p>So we could think of the purl rows (the even ones) as their own function, which we\u2019ll simply call purl.<\/p>\n<p><code>function purl() {purl}<\/code><\/p>\n<p>Rows 1 and 5 are both a simple knit stitch, so we\u2019ll define a knit function for those rows.<\/p>\n<p><code>function knit() {knit}<\/code><\/p>\n<p>That leaves rows 3 and 7 for the interesting functions.  Both rows 3 and 7 are what creates the look of the stripe in the pattern.  It\u2019s what I\u2019d call a bumpy-looking row created by alternating knit and purl.  But to make it a little more interesting, rows 3 and 7 are offset from each other so the bumps don\u2019t line up.  For that reason, we have to define two functions, which we\u2019ll call stripe3 and stripe7.  In the function stripe3, we\u2019re going to knit 2, but then 15 times we will purl 1, knit 1.  Well, that sounds like a for loop in programming to me!<\/p>\n<pre><code>function stripe3() {\n  k2;\n  for (i=1; i&lt;16; i++){ \/\/ e.g. repeat 15X\n    p1,k1;\n  };    \n};\n<\/code><\/pre>\n<p>The stripe7 function is just slightly different so that we get the offset I was talking about. Instead of starting with knit 2, it starts with knit 1 and ends with a knit 1, but it has the same for loop inside. If I was refactoring this to clean it up, I\u2019d probably define our little for loop of p1, k1 15 times as yet another function.<\/p>\n<pre><code>function stripe7() {\n  k1;\n  for (i=1; i&lt;16; i++){ \/\/ e.g. repeat 15X\n    p1,k1\n  };\n  k1;   \n};\n<\/code><\/pre>\n<p>Now the reason it\u2019s helpful to think of this knitting pattern as this series of functions is that this group of 8 rows gets repeated 5 times for a total of 40 rows in one stripeBlock.<\/p>\n<p>Putting the stripeBlock function together then, we need to repeat our pattern of 1 to 8, five times.<\/p>\n<pre><code>function stripeBlock(){\n  for (j=1; j&lt;6; j++){ \/\/ repeat 5x\n    for (k=1; k&lt;9; k++){ \/\/ 8 rows\n      if (i=even){ \/\/ all even rows\n        purl();\n      };\n      if (i=1 | i=5){ \/\/ just rows 1 and 5\n        knit();\n      };\n      if (i=3){ \/\/ just row 3\n        stripe3();\n      };\n      if (i=7){ \/\/ just row 7\n        stripe7();\n      };\n    };\n  };\n};\n<\/code><\/pre>\n<h3>How about that checkBlock?<\/h3>\n<p>This would be a great stopping point if the checkBlock repeated at the same rate internally as the stripeBlock, but nooooo, the inventor of this pattern made them repeat at different rates.<\/p>\n<p>While the stripeBlock function cycles through every 8 rows, the checkBlock cycles every 20 rows!  Now, this wouldn\u2019t be so bad if the two blocks were independent, but they\u2019re not. Remember we\u2019re going across and making a stripeBlock then a checkBlock then a stripeBlock then a checkBlock.<\/p>\n<p>That means that at 8 rows we have to start our repeat over again for the stripeBlock, but we don\u2019t yet change the checkBlocks.  At 20 rows though, the checkBlocks start their repeat, but the stripeBlocks don\u2019t change.  It\u2019s really really hard to keep track!<\/p>\n<p>I know you\u2019re really hoping that I\u2019ll go through the pseudo-code for the checkBlock but for brevity, I\u2019ll just put it in the shownotes.<\/p>\n<pre><code>function check1() {\n  k1;\n  for (i=1; i&lt;6; i++){ \/\/ repeat 5X\n    p3,k3;\n  };\n  k1;   \n};\n\nfunction check2() {\n  k4;\n  for (i=1; i&lt;5; i++){ \/\/ repeat 4X\n    p3,k3;\n  };\n  p3,k1;    \n};\n\nfunction checkBlock(){\n  for (j=1; j&lt;6; j++){ \/\/ repeat 5x \n    for (k=1; k&lt;20; k++){ \/\/ 20 rows\n      if (i=even){ \/\/ all even rows\n        purl();\n      };\n      if (i=1 | i=3 | i=11 | i=13){ \/\/ rows 1, 3, 11, and 13\n        check1;\n      };\n      if (i=15 | i=17 | i=19){ \/\/ rows 15, 17 and 19\n        check2;\n      };\n  };\n};\n<\/code><\/pre>\n<p>Understanding this pattern at this fundamental level was critical to being able to even tell if I\u2019d messed up.  But it doesn\u2019t help me actually knit each row. I can&#8217;t run these functions. I have to still create every stitch one at a time.<\/p>\n<p>I pulled out one of my favorite tools when working on crafts: <a href=\"https:\/\/apps.apple.com\/us\/app\/notability\/id360593530\" target=\"_blank\" rel=\"noopener\">Notability<\/a>. I wrote out all 40 rows of this first set by hand using the Apple Pencil on my iPad Pro.<\/p>\n<figure style=\"float: center; margin: 10px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2021\/05\/Notability-Row-by-Row-Instructions.jpeg\" alt=\"Notability Row by Row Instructions\" title=\"#title#\" width=\"600 \" height=\"450\"><figcaption style=\"text-align:center\">Notability Row-by-Row Instructions<\/figcaption><\/figure>\n<p>I wrote the stripe instructions in green for each row and the check instructions in red.  That turned out to be invaluable in figuring out where I was.  Since I\u2019d figured out the pattern in a programming way, once I had 20 row numbers written out, I could copy and paste between rows to reduce errors.  For example, in the checkBlock, rows 1, 3, 11, and 13 are the same so I could just write it out once, copy, and paste it three times.<\/p>\n<figure style=\"float: right; margin-left: 5px\"><img decoding=\"async\" src=\"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2021\/05\/Knitting-with-iPad-Pro-Notability.jpeg\" alt=\"Knitting with iPad Pro, Notability, and a Cat\" title=\"#title#\" width=\"599 \" height=\"353\"><figcaption style=\"text-align:center\">Knitting with iPad Pro, Notability, and a Cat<\/figcaption><\/figure>\n<p>Once I had the 40 rows written out for the first set of four blocks, I could finally start knitting the pattern predictably. I sit in my easy chair with my iPad Pro in the Magic Keyboard as a stand. I open to Notability while I knit, and use the Apple Pencil to check off each row.  On a few occasions I\u2019ve been knitting in the car, and the iPhone is a more practical tool for that environment. Notability works on both platforms (and the Mac) and syncs notes perfectly. I can zoom way up on Notability on iPhone and use my big, fat fingers to make my little checkmarks and it works surprisingly well.<\/p>\n<p>I\u2019m not going to pretend that I\u2019m not making mistakes with this process, mind you, but I have a much better feel for the pattern with the process I followed.<\/p>\n<p>I\u2019ve just finished the first 40 rows, and that means I get to start set 2. Set 1 was stripe\/check\/stripe\/check, and set 2 will be check\/stripe\/check\/stripe.  You would think that I could just grab the blocks and swap them, but I can&#8217;t.  I\u2019m going to have to write out every single row by hand again because of that darn cycling by 8 rows vs. cycling by 20 rows.<\/p>\n<h3>Bottom line<\/h3>\n<p>The bottom line is that it baffles me how \u201cnormal\u201d people knit. This pattern is rated \u201cEasy\u201d, and yet I find it very complicated. My suspicion is that the difficulty rating is weighted more heavily by the difficulty of the stitches themselves, rather than the entire pattern as a whole.  This only has knit and purl in it, no cable stitches, no ribbing, no stockinette, so I\u2019m thinking that\u2019s why they think it is easy.<\/p>\n<p>I\u2019m having fun making the blanket, and while the journey in this kind of craft is half the enjoyment, I can\u2019t wait to wrap it around my new grandson when he makes his arrival.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After I had written most of this article, I realized that I may have come up with a subject that interests absolutely no one but me. You see, this is about knitting like a programmer. How many of you both program, and knit? I mentioned this problem to Bart and he explained that there\u2019s a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":23607,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[147],"tags":[4597,4595,176,4596],"class_list":["post-23608","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-posts","tag-knit","tag-knitting","tag-programming","tag-purl"],"jetpack_featured_media_url":"https:\/\/www.podfeet.com\/blog\/wp-content\/uploads\/2021\/05\/Knitting-and-Programming.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/23608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/comments?post=23608"}],"version-history":[{"count":6,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/23608\/revisions"}],"predecessor-version":[{"id":23628,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/posts\/23608\/revisions\/23628"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/media\/23607"}],"wp:attachment":[{"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/media?parent=23608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/categories?post=23608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.podfeet.com\/blog\/wp-json\/wp\/v2\/tags?post=23608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}