<p>Most people understand the basis of numerical sequences and can see how one set of digits changes with each iteration.</p>
<p>This makes numerical sequences a very good fit for teaching people iterations and iterations are usually done in a loop.</p>
<p>The two examples you provide show two different types of loops. One appears to be sequential numbers, increasing by one digit for each line of the output, and the other repeats the same numbers, increases and then decreases the number of digits in the output.</p>
<p>The display of those simple numerical digits are a lot easier to understand than my description.</p>

CC BY-SA 4.0
2022-04-02T07:55:20.943Z
2022-04-02T07:55:20.943Z
Andy  Gee
<blockquote>
<p>Are these kinds of pattern questions just for fun and to get better at using loops, or are there any interesting applications of these types of pattern questions? Or any interesting math behind them?</p>
</blockquote>
<p>All of the above.</p>
<p>Fun is important. If learners aren't having fun, they're likely to quit. As an educator working with young children to adults from all walks of life, I've seen a lot of folks lose interest in programming, often because (I suspect) they didn't see the magic and power in it. Sure, for some learners, jumping into business applications might feel more purposeful than playing with patterns, so there is audience-specificity here.</p>
<p>There's something magical about loops and iterative processes in general. Being able to write a few lines of code and generate a pattern involves making the leap from 1 to 2 to 3 to an arbitrary <code>n</code>. Generalizing code and figuring out which parts are dynamic (i.e. parameters and variables) is a critical skill in programming. These loops provide visual feedback for this process and allow students to iterate on naive, hardcoded attempts until they've generalized the logic.</p>
<p>If you think of the characters on the screen as pixels, these nested loop exercises translate very well into computer graphics. I have a <a href="https://cseducators.stackexchange.com/questions/349/what-program-follows-hello-world/7112#7112">post</a> on how you can animate these patterns. This is a useful teaching approach for languages other than Scratch and JavaScript that don't have a particularly easy way to make images and animations other than ASCII.</p>
<p>ASCII text applications like this connect students to computer history while increasing their comfort working in the always-relevant terminal ecosystem. <a href="https://en.wikipedia.org/wiki/ASCII_art" rel="nofollow noreferrer">ASCII art</a>, <a href="https://en.wikipedia.org/wiki/Interactive_fiction" rel="nofollow noreferrer">Text adventures</a>, <a href="https://en.wikipedia.org/wiki/Creative_coding" rel="nofollow noreferrer">creative coding</a>, <a href="https://www.10print.org/" rel="nofollow noreferrer">10 PRINT</a>, <a href="https://en.wikipedia.org/wiki/FIGlet" rel="nofollow noreferrer">Figlet banners</a> and other console-based applications are just as fun and useful today as they've ever been. npm is chock full of packages for <a href="https://www.npmjs.com/package/chalkercli" rel="nofollow noreferrer">animations</a>, <a href="https://www.npmjs.com/package/ora" rel="nofollow noreferrer">spinners</a>, <a href="https://www.npmjs.com/package/cfonts" rel="nofollow noreferrer">banners</a> and <a href="https://www.npmjs.com/package/chalk" rel="nofollow noreferrer">colors</a> to create user-friendly command line tools for programmers.</p>
<p>From a purely technical perspective, these exercises provide great opportunities for nesting conditions in loops, counting forwards and backwards, incrementing by something other than 1, understanding when <code>for</code> vs <code>while</code> is appropriate, getting comfortable with string manipulation and building up to arrays and functions. Given the fun factor and possibilities available, I don't think building an introductory course around ASCII patterns is a particulary absurd idea.</p>
<p>In regards to math, there can be as much or as little of it as you want in making these patterns. Consider patterns in <a href="https://en.wikipedia.org/wiki/Triangular_number" rel="nofollow noreferrer">triangular numbers</a>, <a href="https://en.wikipedia.org/wiki/Pascal%27s_triangle" rel="nofollow noreferrer">Pascal's Triangle</a> and <a href="https://en.wikipedia.org/wiki/Cellular_automaton" rel="nofollow noreferrer">cellular automata</a>, for starters. For the right audience, integrating trigonometric functions like sine and cosine functions can provide a great extension of possibilities. <a href="https://en.wikipedia.org/wiki/L-system" rel="nofollow noreferrer">Fractals</a> and <a href="https://en.wikipedia.org/wiki/Fractal" rel="nofollow noreferrer">L-Systems</a> can be fun to play with, given the right resolution and reasonably experienced coders.</p>
<p>Finally, as an educator, puzzles like these offer a great source of assignments that are relatively difficult to find direct solutions for on the internet, potentially helping combat plagiarism. It's easy to communicate the deliverables by showing a few example runs and explaining that it should work on any <code>n</code>. These problems are language-agnostic.</p>
<p><a href="https://codegolf.stackexchange.com/">Code Golf SE</a> has over 1000 posts in the <a href="https://codegolf.stackexchange.com/questions/tagged/ascii-art">ascii-art</a> tag ripe for exploration. <a href="https://www.codewars.com/kata/search?q=ascii" rel="nofollow noreferrer">Codewars</a> has a good deal of ASCII shape printing problems with test cases (disclosure: I consult for the company that owns Codewars).</p>

CC BY-SA 4.0
2022-04-05T16:32:35.767Z
2022-04-06T02:14:54.097Z
2022-04-06T02:14:54.097Z
ggorlen
<p>I think examples like these</p>
<pre class="lang-text prettyprint-override"><code>1
1 2
1 2 3
1 2
1

1 
2 3
4 5 6
7 8 9 10
11 12 13 14 15 etc.
</code></pre>
<p>serve different purposes, e.g.:</p>
<ul>
<li>Recognize or derive a construction (input)pattern from the optical (output) pattern</li>
<li>Numbers are probably the most primitive example of unique absolutely order-able items</li>
<li>It's probably rather easy to verify whether the solution is correct (comparing outputs)</li>
<li>the human brain is rather good detecting and recognizing patterns</li>
<li>Adding details like fancy strings instead of simple digits will just hide the essential structure</li>
</ul>
<p>BTW: The first example is a stack where elements are popped from the right, while the second example is a stack where elements are popped at the left ;-)</p>

CC BY-SA 4.0
2022-03-31T13:47:42.257Z
You are right about the first one, that is a classic stack, but you missed the second one, it's a simple nested loop. You wouldn't use a stack for this and if you use a queue then you've overcomplicated things, there are better patterns to compare stacks to queues.
Chris Schaller
CC BY-SA 4.0
2022-03-31T14:05:04.123Z
+1 unlike in many other exercises, the output closely matches the flow of the program, making it easy to visualize whats happening in the code. It looks just like the output of a "printf-debugged" program.
PhilipRoman
CC BY-SA 4.0
2022-04-01T20:27:28.787Z
@PhilipRoman: I think [Owen Reynold's answer](https://cseducators.stackexchange.com/a/7326/1654) comes closer to saying exactly that, but yeah, I'm not sure anyone's posted an answer where that's the main point.  Except the question's not asking why these are good teaching exercises, so maybe not.
Peter Cordes
CC BY-SA 4.0
2022-03-31T12:59:12.197Z
2022-03-31T12:59:12.197Z
U. Windl
<p>Patterns are everywhere in programming, and pattern recognition is the skill that is often so noticeably absent in fresh grads. They would often prefer to copy and paste code ad infinitum rather than recognize a pattern and avoid repetition through better design, inheritance, modularity, decorators, etc. Good question.</p>

CC BY-SA 4.0
2022-03-30T20:25:12.737Z
2022-03-30T20:25:12.737Z
postoronnim
<p>A colleague of mine once said that it is important to let students &quot;practice success&quot; occasionally.  Some students lack confidence, so it is a good idea to give them something relatively simple to do, so that they can find out that they <em>can</em> program.  This sort of task is good for that, because it involves some simple but non-trivial problem solving and some simple, but not trivial coding, and the student can immediately tell from the output whether they have got it working correctly.  I don't think there is more too it than that.  Back in the 1980s getting a computer to do that sort of thing was impressive/cool, but much less so now (which is a shame).</p>
<p>I often start with printing patterns of asterisks.</p>

CC BY-SA 4.0
2024-09-08T19:22:27.983Z
2024-09-08T19:32:40.510Z
2024-09-08T19:32:40.510Z
Dikran Marsupial
<blockquote>
<p>Are these kinds of pattern questions just for fun and to get better at
using loops [...] ?</p>
</blockquote>
<p>Absolutely yes. Practical applications of such patterns nearly don't exist. It's good training for control constructs like loops, and you can immediately see whether you got it right.</p>

CC BY-SA 4.0
2022-03-31T03:02:18.247Z
Practical applications of algorithms that can generate such patterns do exist and are very common. They include: generating node traversal sequences in pathfinding or graph crawling algorithms, generating brute force password sequences, similar to the brute force, generating permutations or combinations to solve word problems (eg, Wordle solver, Scrabble solver or the first part of decoding an encrypted message if you have a rough idea of some of the content of the message) etc..
slebetman
CC BY-SA 4.0
2022-03-31T10:01:53.270Z
I almost applied for a job once at a company building sewing machines with lots of very clever software - yes, I might have written lots of code to create patterns. Seriously :-)
gnasher729
CC BY-SA 4.0
2022-04-02T15:35:44.413Z
The `tree` command is another nice example of loops, recursion and printing. It is great visual tool for understanding the structure of directories and their contents.
Fritz Sieker
CC BY-SA 4.0
2022-03-30T10:54:36.983Z
2022-03-30T10:54:36.983Z
Ralf Kleberhoff
<blockquote>
<p>Why do we practice printing patterns while coding?</p>
</blockquote>
<p>Because bugs love to hide in <a href="https://cseducators.stackexchange.com/a/4303/1401">loops</a>.</p>
<p>Talk students into using <a href="https://softwareengineering.stackexchange.com/a/315968/131624">loops</a> to print these patterns and they will create bugs. Tracking down and squishing bugs in the confusing code this exercise produces is a skill that will last as long as their coding career.</p>
<p>Fail to talk them into using loops and you'll find they very wisely write a bug free print statement for each line of your output. Which solves the problem without learning the lesson. Have a good explanation why this isn't preferred. Understand that you likely wont find a good technical explanation. Sometimes pros do the same thing. It's called loop unrolling.</p>
<p>Don't claim loops are more flexible, efficient, or readable. They aren't. Loops just follow patterns. Sometimes they are a good way to express the pattern. Capturing a pattern in a loop gives you expressive power. It lets you create, manipulate, and display things that follow the pattern by manipulating a few numbers rather than a lot of text. That's cool because numbers can be calculated.</p>
<p>This is an exercise in pattern recognition, loop construction, and debugging. Pull this off and I consider you a real coder.</p>
<blockquote>
<p>are there any interesting applications of these types of pattern questions?</p>
</blockquote>
<p>Absolutely. They range from silly toys most often used in job interviews:
<a href="https://en.wikipedia.org/wiki/Fizz_buzz" rel="nofollow noreferrer">FizzBuzz</a></p>
<p>To beefy algorithms used to keep growing networks working:
<a href="https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm" rel="nofollow noreferrer">Dijkstra's_algorithm</a></p>
<p>While they have wildly different applications, both really just manipulate numbers to follow a pattern.</p>

CC BY-SA 4.0
2022-03-30T21:11:17.777Z
"*Don't claim loops are more flexible […]. They aren't.*" - well hardcoding a pattern works well for a *single* pattern. Now make the exercise to print the pattern in an arbitrary size, or to print the first N lines of the infinite pattern… I can't see how you'd do that without the flexibility of a loop (or recursion).
Bergi
CC BY-SA 4.0
2022-03-30T21:35:16.380Z
@Bergi That isn't more flexibility. That's parameterizing. A student with access to copy and paste and the code has the same flexibility and easier to debug code. The trick is getting them to see why changing N is better than copy and paste. The answer is sometimes you don't know N until this code is running on some server at 3am. I could have my boss wake me up with phone call about it but I'd rather sleep through the night.
candied_orange
CC BY-SA 4.0
2022-03-31T02:30:47.073Z
By this argument, no code is more flexible than a collection of special-cases.  I'd argue the flexibility provided by loops is the flexibility provided to another individual, who may not have the same knowledge as you do.  In many cases, this is a user who provides input, in the form of a file or otherwise.  In the case of `std::sort`, it is in the form of a developer who may not have the understanding of sorting algorithms, or may not wish to exercise said understanding.
Cort Ammon
CC BY-SA 4.0
2022-03-31T10:03:04.947Z
If bugs love to hide in loops, then shouldn't students be taught *not* to use them? None of the examples in the question require loops, they can be solved using unfolds, folds, and maps. In fact, I have rarely seen a problem that required a loop or even was made simpler by one.
Jörg W Mittag
CC BY-SA 4.0
2022-03-31T11:18:31.607Z
@JörgWMittag writing loops gets students to write bugs. There is no substitute for having to fix your own bug. And no better teacher that already debugged canned loop alternatives are often preferable to writing your own loop.
candied_orange
CC BY-SA 4.0
2022-03-31T11:31:45.597Z
That said. Loops aren’t going away. Students should respect them and master them. Doesn’t mean they must prefer them.
candied_orange
CC BY-SA 4.0
2022-03-31T11:38:02.160Z
@candied_orange Loops are basically the reason why you program. Solved problem and need to do it 1000 times more? Wrap it into a loop... done! Without loops you'd constantly repeat yourself and where's the fun in that? Seriously I'm actually astonished people could not like loops. For real, "algorithms" are just breaking up a problem into a series of simpler problems with the intention of letting the computer run those simple problems in a loop. Without loops you wouldn't so much program you'd operate a machine. Seriously I can't wrap my head around how you could not think loops are cool.
haxor789
CC BY-SA 4.0
2022-03-31T12:43:50.257Z
@haxor789 I program to solve problems not write loops. Loops are cool except when I'm tired and want to go home but can't because this custom loop you made me look at still wont behave. If you want to fall in love with something try abstraction.
candied_orange
CC BY-SA 4.0
2022-03-31T12:52:32.210Z
@candied_orange As said you basically solve actual real world complex problems by breaking them down into machine processable parts, because machines are faster at doing those things and they are faster because of constructs like loops if you actually have to write down the commands you could almost do it yourself. Sure if you abstract things behind functions and program calls you're able to do a ton of magic, but then you're not teaching computer science you're instructing a user.
haxor789
CC BY-SA 4.0
2022-03-31T12:59:49.573Z
@haxor789 That way of thinking leads back to writing goto "like a real programmer". No, show me you can do abstraction well and I've got much more respect for you than if you just show me you know how to crank out a loop.
candied_orange
CC BY-SA 4.0
2022-03-31T13:14:22.803Z
@haxor789: The only time I ever need loops is to work around deficiencies in the programming language and/or the library. In most languages I work in, if you're using a loop you're doing it wrong. Some of them don't even have loops. I, personally, find recursion patterns like anamorphisms, catamorphisms, or hylomorphisms much easier to understand and most importantly much harder to get wrong (can't have an off-by-one indexing error if there's no index). If all else fails, there's always tail-recursion.
Jörg W Mittag
CC BY-SA 4.0
2022-03-31T13:19:48.783Z
@JörgWMittag completely agree (except, be aware that not every language optimizes tail-recursion).
candied_orange
CC BY-SA 4.0
2022-03-31T13:31:52.983Z
@candied_orange JörgWMittag The point is about the coding patterns that let you avoid repetition, perform an operation stepwise, let's you manipulate datastructures manually if necessary instead of relying on knowledge of the commands of a particular language and stuff like that. Whether you use go to, for/while/do-while/for each or recursions doesn't really matter. Does it even conceptually matter whether the language optimizes tail-recursions?
haxor789
CC BY-SA 4.0
2022-03-31T13:40:26.530Z
@haxor789 it does when you blow the stack
candied_orange
CC BY-SA 4.0
2022-03-31T13:44:26.477Z
@haxor789 If the language doesn't optimize tail-recursions, they're quite limited in the number of iterations they can do. They certainly can't emulate a loop from 1 to a million, for example.
prosfilaes
CC BY-SA 4.0
2022-03-31T13:44:36.517Z
@candied_orange Fair enough I had that stackoverflow joke coming. Though that just shows for why functions are not ideal to use as loops as they produce a lot of overhead necessary for functions but unnecessary for the loop part that you're interested in.
haxor789
CC BY-SA 4.0
2022-03-31T13:51:07.997Z
@haxor789 : ) ok seriously, you seem to think I'm arguing against loops. I'm not. I'm arguing that loops are buggy, hard to read, untrustworthy piles of code that any pro will regard with deep suspicion. They are powerfully expressive and they aren't going away no mater how many abstractions language designers throw at them. So they are a perfect lesson for new programmers to learn. Just give them plenty of time because this stuff aint easy.
candied_orange
CC BY-SA 4.0
2022-04-01T12:11:21.050Z
@candied_orange I mean I get that you argue for loops as a means for learning debugging. But I'd argue against the assertions that they are inherently buggy, hard to read or untrustworthy. They are as safe as their user. Sure if you multiply your coding power with a loop the impact of small bugs is getting amplified as well. But having that power is kinda what you aim for and would bite you with abstraction in pretty much the same way. Not to mention that you can always unroll a loop whereas rolling up a loop, so to say, is an actual challenge. And of course grasping a few lines is easier.
haxor789
CC BY-SA 4.0
2022-04-01T12:29:42.717Z
I must protest against you teaching a new generation of developers to think of bugs as mischievous actors who inevitably creep into our code when we aren't looking and "hide in loops." If your code does not make the machine behave as you expected it to behave, then your code is _defective._ It's long past time for software developers to acknowledge that when code contains a defect—no matter how subtle—it always was the programmer (or team of programmers) who created it and, who bear responsibility for finding it and fixing it.
Solomon Slow
CC BY-SA 4.0
2022-04-01T14:49:27.140Z
@SolomonSlow sigh. The point of the lesson is to experience the bugs: creating them, finding them, and fixing them. They do inevitably creep into our expressions. Note how many times I had to edit my answer. Heck I even deleted and reposted some of my comments. Call them defects, bugs (See Grace Hopper), or typos; reality often falls short of the ideal. This isn't even a new idea. Plato argued that any form of triangle we experience is an imperfect form of the ideal triangle. So we should expect the bugs. Or as my 11th grade English teacher put it: "Did you read this before you gave it to me?"
candied_orange
CC BY-SA 4.0
2022-04-01T15:03:43.153Z
You're completely missing my point. But I guess that's on purpose, so I won't argue it any further.
Solomon Slow
CC BY-SA 4.0
2022-04-01T15:16:14.747Z
If I'm missing something I'm not doing it willfully. If someone is willing to make me see it I'm willing to listen. Look at my profile to see how I approach this.
candied_orange
CC BY-SA 4.0
2022-04-01T16:45:27.090Z
OK, That's fair. My point is, I can divide developers with whom I have worked into two groups; those who said "bug," and those who said "defect." The ones who said "bug" tended to create more software defects and, tended to show less concern for them than the ones who said, "defect." An attitude—not a common attitude, but one that was exclusive to the "bugs" crowd—said, "It's not my problem, until the testing department reports it." (Same crowd also was more likely to look down on the testers, or even to consider them as adversaries.) In short: the "defect" people were better team players.
Solomon Slow
CC BY-SA 4.0
2022-04-01T17:02:23.520Z
@SolomonSlow I had thought you wanted me to back up my thesis that loops are hard to read.  Which I can if you like. But now it seems you want me to choose to use stuffy formal language to express myself because it will somehow make me a better coder. I really don't know where that idea came from. In my experience everyone says bug and defect and choses which to use based mostly on who they are talking to. Students certainly should know both terms. But if you have some actual data or study that backs up your claim I'd love to see it.
candied_orange
CC BY-SA 4.0
2022-04-01T17:35:23.957Z
Re, "don't know where that idea came from." It came from my personal experience—40+ years of writing code. You said, "bugs love to hide..." OK, that sounds more fun than saying "its really hard to write defect-free code." But, when you personify bugs like that, IMO, it sounds like an invitation to shift the blame. In my experience, developers who personify bugs have more of a lax attitude toward them. It's as if, at _some_ level, when they say, "Weird! I don't know how that bug got in there" instead of saying, "Damn! I sure ***ed that up," they're denying their culpability for the problem.
Solomon Slow
CC BY-SA 4.0
2022-04-01T20:29:01.623Z
@SolomonSlow I'm not sure that translates to every team. On my team, the people who say "bug" are more likely to be interested in making the software work right no matter how things happened. The people who say "defect" are more interested in figuring out how to assign blame.
user3067860
CC BY-SA 4.0
2022-03-30T19:16:53.290Z
2024-08-29T11:52:30.353Z
2024-08-29T11:52:30.353Z
candied_orange
<p>I was skeptical about this as well. Those pictures feel like a cheesy attempt to make programming cool, from an era when that meant ASCII graphics; or the sort of cutsie junk we need to keep the attention of non-majors. But I've come around to realize they're nice teaching examples of nested loops, at a few levels.</p>
<p>The way nested loops work isn't obvious. Showing how <code>for i=1 to 8; { for j=1 to 5; print &quot;*&quot; }</code> actually prints 40 stars (and not 13) is helpful. Adding the newline for that 8x5 box is a nice way to visualize how the loops run.</p>
<p>Making a silly right triangle with <code>for i=0 to 7; for j=0 to i</code> introduces the idea of using the outer loop variable to influence the inner loop. That's an idea we'll need later for O(<span class="math-container">$n^2$</span>) selection and insertion sorts. Different patterns allow us to use i in different places <code>j=i to WIDTH</code> (right-triangle on right edge) or even both sides -- <code>j=i to WIDTH-i</code> (pyramid).</p>
<p>More complex things, pyramids or X's or a hollow square, are nice practice with 0-based index math -- how i runs from 0 to HEIGHT-1 and how to plug that into <code>j&lt;HEIGHT-i</code> to reason about the length of the 1st and last row. Off-by-one errors are very easy to spot in these pictures.</p>
<p>All of this is nice for ComSci majors who'll need to be good with this stuff for their algorithms classes. But even for an aspiring web developer in a 2-year program, these are a quick warm-up for creating a table, before adding all of the mark-up.</p>
<p>Coding note: the examples change a little for console vs. graphical system, but not the essence. If printed on a simple console, sometimes the inner loop must run 0 to WIDTH, with the interesting part inside. Ex: <code>if(i&lt;WIDTH-j) ch=&quot; &quot;; else ch=&quot;*&quot;;</code>. Whereas with a graphical system, the inner loop can do the work: <code>j=WIDTH-i to WIDTH; colorBox(i,j)</code>. Or on a console we can fake that by &quot;printing&quot; into a 2D array which a function displays later.</p>

CC BY-SA 4.0
2022-03-31T19:26:32.780Z
It's not really "cool designs" from way back. It's to get non-programmers their first experience with looping. - I taught CS.
Rick Henderson
CC BY-SA 4.0
2022-03-31T20:47:58.210Z
@RickHenderson They are from way back -- books of BASIC programs from the 1980's had them. But thanks for the "for non-majors" idea. That aligns with my 1st para that it's easy to assume these are cutsie junk, useless for "real" CS majors.
Owen Reynolds
CC BY-SA 4.0
2022-04-01T20:20:16.003Z
*Off-by-one errors are very easy to spot in these pictures* - I think that's really the key point.  Not only is the desired output tied closely to each step of execution, like a debug-print and unlike for example a sorting algorithm, the actual shape will be visually wrong for some kinds of bugs.  For students who might not have learned how to use a debugger yet, this code is still very debugable except in the very lowest-level languages (like assembly) where even printing numbers as ASCII digit-strings takes some work and there are calling-conventions you can get wrong.
Peter Cordes
CC BY-SA 4.0
2022-04-01T20:23:46.730Z
Loops where you aren't printing something every iteration as part of the desired output don't have this feature, and debugging them might require single-stepping in a debugger (or adding debug-prints), and could still be trickier to follow.
Peter Cordes
CC BY-SA 4.0
2022-04-01T22:45:10.887Z
@OwenReynolds The idea holds that it's still about learning loops and not pretty pictures. There are CS majors who start first year having never coded before. Trust me.
Rick Henderson
CC BY-SA 4.0
2022-04-05T15:36:32.320Z
It's funny how one person's "cutsie junk" is another person's art. I see no harm in making CS fun, even if patterns like this didn't have obvious practical application (they do). What's the problem with making programming accessible to non-CS majors, exactly? That seems like a social imperative in this day and age to me.
ggorlen
CC BY-SA 4.0
2022-03-31T16:12:08.250Z
2022-04-01T01:41:10.760Z
2022-04-01T01:41:10.760Z
Owen Reynolds
<p>I let my students generate Pascal's triangle as a data structure. That's an exercise in loops.</p>
<p>And then they have print the triangle modulo some number n: print a star when the entry modulo n is non-zero, a space otherwise. Instant fractals!</p>
<p>So there you essentially need to generate screen output.</p>

CC BY-SA 4.0
2022-03-30T17:37:31.477Z
2024-10-13T22:10:50.823Z
2024-10-13T22:10:50.823Z
Victor Eijkhout
<p>Why do we practice printing patterns while coding? Patterns like:</p>
<pre><code>1
1 2
1 2 3
1 2
1

1
2 3
4 5 6
7 8 9 10
11 12 13 14 15, etc.
</code></pre>
<p>Are these kinds of pattern questions just for fun and to get better at using loops, or are there any interesting applications of these types of pattern questions? Or any interesting math behind them?</p>

CC BY-SA 4.0
2022-03-30T19:09:32.450Z
Fast feedback loops!
WBT
CC BY-SA 4.0
2022-03-30T23:08:34.950Z
Depending on the language and the pattern, it may also be to get better at using recursion properly. Assuming I was told to do a parameterized implementation of either of your examples in a language like Elixir (or pretty much any other language with proper TCO) I would actually jump first to a recursive implementation even if looping were possible in the language.
Austin Hemmelgarn
CC BY-SA 4.0
2022-04-01T16:01:21.747Z
Turning a mathematical expression or idea into an algorithm is not always a 1:1 translation.  It seems to be a "hard thing", generally, for programmers to adapt mathematics into code.  This type of practice helps those skills, and they are important in many fields of applied science and engineering.
J...
CC BY-SA 4.0
2022-04-05T15:41:19.600Z
@AustinHemmelgarn These sort of patterns would likely be poor applications of recursion for imperative languages, though, which is the common case. CS educators forcing students to use recursion for O(n^2) loop problems like this causes a lot of hapless students to wind up in [the recursion tag](https://stackoverflow.com/questions/tagged/recursion) on Stack Overflow.
ggorlen
CC BY-SA 4.0
2022-04-05T16:44:00.987Z
@ggorlen Agreed, which is why I prefaced my comment with ‘depending on the language’. I would never consider recursion for something like this in a language like C or Python, but would absolutely prefer it to any other looping-equivalent construct in something like Elixir or Erlang.
Austin Hemmelgarn
CC BY-SA 4.0
2022-04-05T17:10:46.980Z
@AustinHemmelgarn Yes, you nailed it in the original but I wanted to over-emphasize for posterity. Misapplication of recursion in education is a pet peeve of mine.
ggorlen
<programming><exercises>
Why do we practice printing patterns while coding?
# Why do we practice printing patterns while coding?

(Asked by: username_0 on 2022-03-30)

Why do we practice printing patterns while coding? Patterns like:
1
1 2
1 2 3
1 2
1

1
2 3
4 5 6
7 8 9 10
11 12 13 14 15, etc.

Are these kinds of pattern questions just for fun and to get better at using loops, or are there any interesting applications of these types of pattern questions? Or any interesting math behind them?

**Tags:** programming, exercises

> **Comments:**
> **username_1**: Fast feedback loops!  
> **username_2**: Depending on the language and the pattern, it may also be to get better at using recursion properly. Assuming I was told to do a parameterized implementation of either of your examples in a language like Elixir (or pretty much any other language with proper TCO) I would actually jump first to a recursive implementation even if looping were possible in the language.  
> **username_3**: Turning a mathematical expression or idea into an algorithm is not always a 1:1 translation.  It seems to be a "hard thing", generally, for programmers to adapt mathematics into code.  This type of practice helps those skills, and they are important in many fields of applied science and engineering.  
> **username_4**: @AustinHemmelgarn These sort of patterns would likely be poor applications of recursion for imperative languages, though, which is the common case. CS educators forcing students to use recursion for O(n^2) loop problems like this causes a lot of hapless students to wind up in [the recursion tag](https://stackoverflow.com/questions/tagged/recursion) on Stack Overflow.  
> **username_2**: @username_4 Agreed, which is why I prefaced my comment with ‘depending on the language’. I would never consider recursion for something like this in a language like C or Python, but would absolutely prefer it to any other looping-equivalent construct in something like Elixir or Erlang.  
> **username_4**: @AustinHemmelgarn Yes, you nailed it in the original but I wanted to over-emphasize for posterity. Misapplication of recursion in education is a pet peeve of mine.  

---

## 9 answers

### Answer by username_16 on 2022-03-30. Score: 34

> Why do we practice printing patterns while coding?

Because bugs love to hide in [loops](https://cseducators.stackexchange.com/a/4303/1401).

Talk students into using [loops](https://softwareengineering.stackexchange.com/a/315968/131624) to print these patterns and they will create bugs. Tracking down and squishing bugs in the confusing code this exercise produces is a skill that will last as long as their coding career.

Fail to talk them into using loops and you'll find they very wisely write a bug free print statement for each line of your output. Which solves the problem without learning the lesson. Have a good explanation why this isn't preferred. Understand that you likely wont find a good technical explanation. Sometimes pros do the same thing. It's called loop unrolling.

Don't claim loops are more flexible, efficient, or readable. They aren't. Loops just follow patterns. Sometimes they are a good way to express the pattern. Capturing a pattern in a loop gives you expressive power. It lets you create, manipulate, and display things that follow the pattern by manipulating a few numbers rather than a lot of text. That's cool because numbers can be calculated.

This is an exercise in pattern recognition, loop construction, and debugging. Pull this off and I consider you a real coder.

> are there any interesting applications of these types of pattern questions?

Absolutely. They range from silly toys most often used in job interviews:
[FizzBuzz](https://en.wikipedia.org/wiki/Fizz_buzz)

To beefy algorithms used to keep growing networks working:
[Dijkstra's\_algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)

While they have wildly different applications, both really just manipulate numbers to follow a pattern.

> **Comments:**
> **username_17**: "*Don't claim loops are more flexible […]. They aren't.*" - well hardcoding a pattern works well for a *single* pattern. Now make the exercise to print the pattern in an arbitrary size, or to print the first N lines of the infinite pattern… I can't see how you'd do that without the flexibility of a loop (or recursion).  
> **username_16**: @username_17 That isn't more flexibility. That's parameterizing. A student with access to copy and paste and the code has the same flexibility and easier to debug code. The trick is getting them to see why changing N is better than copy and paste. The answer is sometimes you don't know N until this code is running on some server at 3am. I could have my boss wake me up with phone call about it but I'd rather sleep through the night.  
> **username_18**: By this argument, no code is more flexible than a collection of special-cases.  I'd argue the flexibility provided by loops is the flexibility provided to another individual, who may not have the same knowledge as you do.  In many cases, this is a user who provides input, in the form of a file or otherwise.  In the case of `std::sort`, it is in the form of a developer who may not have the understanding of sorting algorithms, or may not wish to exercise said understanding.  
> **username_19**: If bugs love to hide in loops, then shouldn't students be taught *not* to use them? None of the examples in the question require loops, they can be solved using unfolds, folds, and maps. In fact, I have rarely seen a problem that required a loop or even was made simpler by one.  
> **username_16**: @JörgWMittag writing loops gets students to write bugs. There is no substitute for having to fix your own bug. And no better teacher that already debugged canned loop alternatives are often preferable to writing your own loop.  
> **username_16**: That said. Loops aren’t going away. Students should respect them and master them. Doesn’t mean they must prefer them.  
> **username_20**: @username_16 Loops are basically the reason why you program. Solved problem and need to do it 1000 times more? Wrap it into a loop... done! Without loops you'd constantly repeat yourself and where's the fun in that? Seriously I'm actually astonished people could not like loops. For real, "algorithms" are just breaking up a problem into a series of simpler problems with the intention of letting the computer run those simple problems in a loop. Without loops you wouldn't so much program you'd operate a machine. Seriously I can't wrap my head around how you could not think loops are cool.  
> **username_16**: @username_20 I program to solve problems not write loops. Loops are cool except when I'm tired and want to go home but can't because this custom loop you made me look at still wont behave. If you want to fall in love with something try abstraction.  
> **username_20**: @username_16 As said you basically solve actual real world complex problems by breaking them down into machine processable parts, because machines are faster at doing those things and they are faster because of constructs like loops if you actually have to write down the commands you could almost do it yourself. Sure if you abstract things behind functions and program calls you're able to do a ton of magic, but then you're not teaching computer science you're instructing a user.  
> **username_16**: @username_20 That way of thinking leads back to writing goto "like a real programmer". No, show me you can do abstraction well and I've got much more respect for you than if you just show me you know how to crank out a loop.  
> **username_19**: @username_20: The only time I ever need loops is to work around deficiencies in the programming language and/or the library. In most languages I work in, if you're using a loop you're doing it wrong. Some of them don't even have loops. I, personally, find recursion patterns like anamorphisms, catamorphisms, or hylomorphisms much easier to understand and most importantly much harder to get wrong (can't have an off-by-one indexing error if there's no index). If all else fails, there's always tail-recursion.  
> **username_16**: @JörgWMittag completely agree (except, be aware that not every language optimizes tail-recursion).  
> **username_20**: @username_16 JörgWMittag The point is about the coding patterns that let you avoid repetition, perform an operation stepwise, let's you manipulate datastructures manually if necessary instead of relying on knowledge of the commands of a particular language and stuff like that. Whether you use go to, for/while/do-while/for each or recursions doesn't really matter. Does it even conceptually matter whether the language optimizes tail-recursions?  
> **username_16**: @username_20 it does when you blow the stack  
> **username_21**: @username_20 If the language doesn't optimize tail-recursions, they're quite limited in the number of iterations they can do. They certainly can't emulate a loop from 1 to a million, for example.  
> **username_20**: @username_16 Fair enough I had that stackoverflow joke coming. Though that just shows for why functions are not ideal to use as loops as they produce a lot of overhead necessary for functions but unnecessary for the loop part that you're interested in.  
> **username_16**: @username_20 : ) ok seriously, you seem to think I'm arguing against loops. I'm not. I'm arguing that loops are buggy, hard to read, untrustworthy piles of code that any pro will regard with deep suspicion. They are powerfully expressive and they aren't going away no mater how many abstractions language designers throw at them. So they are a perfect lesson for new programmers to learn. Just give them plenty of time because this stuff aint easy.  
> **username_20**: @username_16 I mean I get that you argue for loops as a means for learning debugging. But I'd argue against the assertions that they are inherently buggy, hard to read or untrustworthy. They are as safe as their user. Sure if you multiply your coding power with a loop the impact of small bugs is getting amplified as well. But having that power is kinda what you aim for and would bite you with abstraction in pretty much the same way. Not to mention that you can always unroll a loop whereas rolling up a loop, so to say, is an actual challenge. And of course grasping a few lines is easier.  
> **username_22**: I must protest against you teaching a new generation of developers to think of bugs as mischievous actors who inevitably creep into our code when we aren't looking and "hide in loops." If your code does not make the machine behave as you expected it to behave, then your code is _defective._ It's long past time for software developers to acknowledge that when code contains a defect—no matter how subtle—it always was the programmer (or team of programmers) who created it and, who bear responsibility for finding it and fixing it.  
> **username_16**: @SolomonSlow sigh. The point of the lesson is to experience the bugs: creating them, finding them, and fixing them. They do inevitably creep into our expressions. Note how many times I had to edit my answer. Heck I even deleted and reposted some of my comments. Call them defects, bugs (See Grace Hopper), or typos; reality often falls short of the ideal. This isn't even a new idea. Plato argued that any form of triangle we experience is an imperfect form of the ideal triangle. So we should expect the bugs. Or as my 11th grade English teacher put it: "Did you read this before you gave it to me?"  
> **username_22**: You're completely missing my point. But I guess that's on purpose, so I won't argue it any further.  
> **username_16**: If I'm missing something I'm not doing it willfully. If someone is willing to make me see it I'm willing to listen. Look at my profile to see how I approach this.  
> **username_22**: OK, That's fair. My point is, I can divide developers with whom I have worked into two groups; those who said "bug," and those who said "defect." The ones who said "bug" tended to create more software defects and, tended to show less concern for them than the ones who said, "defect." An attitude—not a common attitude, but one that was exclusive to the "bugs" crowd—said, "It's not my problem, until the testing department reports it." (Same crowd also was more likely to look down on the testers, or even to consider them as adversaries.) In short: the "defect" people were better team players.  
> **username_16**: @SolomonSlow I had thought you wanted me to back up my thesis that loops are hard to read.  Which I can if you like. But now it seems you want me to choose to use stuffy formal language to express myself because it will somehow make me a better coder. I really don't know where that idea came from. In my experience everyone says bug and defect and choses which to use based mostly on who they are talking to. Students certainly should know both terms. But if you have some actual data or study that backs up your claim I'd love to see it.  
> **username_22**: Re, "don't know where that idea came from." It came from my personal experience—40+ years of writing code. You said, "bugs love to hide..." OK, that sounds more fun than saying "its really hard to write defect-free code." But, when you personify bugs like that, IMO, it sounds like an invitation to shift the blame. In my experience, developers who personify bugs have more of a lax attitude toward them. It's as if, at _some_ level, when they say, "Weird! I don't know how that bug got in there" instead of saying, "Damn! I sure ***ed that up," they're denying their culpability for the problem.  
> **username_23**: @SolomonSlow I'm not sure that translates to every team. On my team, the people who say "bug" are more likely to be interested in making the software work right no matter how things happened. The people who say "defect" are more interested in figuring out how to assign blame.  

---

### Answer by username_12 on 2022-03-30. Score: 10

> Are these kinds of pattern questions just for fun and to get better at
> using loops [...] ?

Absolutely yes. Practical applications of such patterns nearly don't exist. It's good training for control constructs like loops, and you can immediately see whether you got it right.

> **Comments:**
> **username_13**: Practical applications of algorithms that can generate such patterns do exist and are very common. They include: generating node traversal sequences in pathfinding or graph crawling algorithms, generating brute force password sequences, similar to the brute force, generating permutations or combinations to solve word problems (eg, Wordle solver, Scrabble solver or the first part of decoding an encrypted message if you have a rough idea of some of the content of the message) etc..  
> **username_14**: I almost applied for a job once at a company building sewing machines with lots of very clever software - yes, I might have written lots of code to create patterns. Seriously :-)  
> **username_15**: The `tree` command is another nice example of loops, recursion and printing. It is great visual tool for understanding the structure of directories and their contents.  

---

### Answer by username_24 on 2022-03-31. Score: 7

I was skeptical about this as well. Those pictures feel like a cheesy attempt to make programming cool, from an era when that meant ASCII graphics; or the sort of cutsie junk we need to keep the attention of non-majors. But I've come around to realize they're nice teaching examples of nested loops, at a few levels.

The way nested loops work isn't obvious. Showing how `for i=1 to 8; { for j=1 to 5; print "*" }` actually prints 40 stars (and not 13) is helpful. Adding the newline for that 8x5 box is a nice way to visualize how the loops run.

Making a silly right triangle with `for i=0 to 7; for j=0 to i` introduces the idea of using the outer loop variable to influence the inner loop. That's an idea we'll need later for O($n^2$) selection and insertion sorts. Different patterns allow us to use i in different places `j=i to WIDTH` (right-triangle on right edge) or even both sides -- `j=i to WIDTH-i` (pyramid).

More complex things, pyramids or X's or a hollow square, are nice practice with 0-based index math -- how i runs from 0 to HEIGHT-1 and how to plug that into `j to reason about the length of the 1st and last row. Off-by-one errors are very easy to spot in these pictures.`

All of this is nice for ComSci majors who'll need to be good with this stuff for their algorithms classes. But even for an aspiring web developer in a 2-year program, these are a quick warm-up for creating a table, before adding all of the mark-up.

Coding note: the examples change a little for console vs. graphical system, but not the essence. If printed on a simple console, sometimes the inner loop must run 0 to WIDTH, with the interesting part inside. Ex: `if(i. Whereas with a graphical system, the inner loop can do the work: j=WIDTH-i to WIDTH; colorBox(i,j). Or on a console we can fake that by "printing" into a 2D array which a function displays later.`

> **Comments:**
> **username_25**: It's not really "cool designs" from way back. It's to get non-programmers their first experience with looping. - I taught CS.  
> **username_24**: @RickHenderson They are from way back -- books of BASIC programs from the 1980's had them. But thanks for the "for non-majors" idea. That aligns with my 1st para that it's easy to assume these are cutsie junk, useless for "real" CS majors.  
> **username_9**: *Off-by-one errors are very easy to spot in these pictures* - I think that's really the key point.  Not only is the desired output tied closely to each step of execution, like a debug-print and unlike for example a sorting algorithm, the actual shape will be visually wrong for some kinds of bugs.  For students who might not have learned how to use a debugger yet, this code is still very debugable except in the very lowest-level languages (like assembly) where even printing numbers as ASCII digit-strings takes some work and there are calling-conventions you can get wrong.  
> **username_9**: Loops where you aren't printing something every iteration as part of the desired output don't have this feature, and debugging them might require single-stepping in a debugger (or adding debug-prints), and could still be trickier to follow.  
> **username_25**: @OwenReynolds The idea holds that it's still about learning loops and not pretty pictures. There are CS majors who start first year having never coded before. Trust me.  
> **username_4**: It's funny how one person's "cutsie junk" is another person's art. I see no harm in making CS fun, even if patterns like this didn't have obvious practical application (they do). What's the problem with making programming accessible to non-CS majors, exactly? That seems like a social imperative in this day and age to me.  

---

### Answer by username_26 on 2022-03-30. Score: 4

I let my students generate Pascal's triangle as a data structure. That's an exercise in loops.

And then they have print the triangle modulo some number n: print a star when the entry modulo n is non-zero, a space otherwise. Instant fractals!

So there you essentially need to generate screen output.


---

### Answer by username_5 on 2022-04-02. Score: 2

Most people understand the basis of numerical sequences and can see how one set of digits changes with each iteration.

This makes numerical sequences a very good fit for teaching people iterations and iterations are usually done in a loop.

The two examples you provide show two different types of loops. One appears to be sequential numbers, increasing by one digit for each line of the output, and the other repeats the same numbers, increases and then decreases the number of digits in the output.

The display of those simple numerical digits are a lot easier to understand than my description.


---

### Answer by username_4 on 2022-04-05. Score: 2

> Are these kinds of pattern questions just for fun and to get better at using loops, or are there any interesting applications of these types of pattern questions? Or any interesting math behind them?

All of the above.

Fun is important. If learners aren't having fun, they're likely to quit. As an educator working with young children to adults from all walks of life, I've seen a lot of folks lose interest in programming, often because (I suspect) they didn't see the magic and power in it. Sure, for some learners, jumping into business applications might feel more purposeful than playing with patterns, so there is audience-specificity here.

There's something magical about loops and iterative processes in general. Being able to write a few lines of code and generate a pattern involves making the leap from 1 to 2 to 3 to an arbitrary `n`. Generalizing code and figuring out which parts are dynamic (i.e. parameters and variables) is a critical skill in programming. These loops provide visual feedback for this process and allow students to iterate on naive, hardcoded attempts until they've generalized the logic.

If you think of the characters on the screen as pixels, these nested loop exercises translate very well into computer graphics. I have a [post](https://cseducators.stackexchange.com/questions/349/what-program-follows-hello-world/7112#7112) on how you can animate these patterns. This is a useful teaching approach for languages other than Scratch and JavaScript that don't have a particularly easy way to make images and animations other than ASCII.

ASCII text applications like this connect students to computer history while increasing their comfort working in the always-relevant terminal ecosystem. [ASCII art](https://en.wikipedia.org/wiki/ASCII_art), [Text adventures](https://en.wikipedia.org/wiki/Interactive_fiction), [creative coding](https://en.wikipedia.org/wiki/Creative_coding), [10 PRINT](https://www.10print.org/), [Figlet banners](https://en.wikipedia.org/wiki/FIGlet) and other console-based applications are just as fun and useful today as they've ever been. npm is chock full of packages for [animations](https://www.npmjs.com/package/chalkercli), [spinners](https://www.npmjs.com/package/ora), [banners](https://www.npmjs.com/package/cfonts) and [colors](https://www.npmjs.com/package/chalk) to create user-friendly command line tools for programmers.

From a purely technical perspective, these exercises provide great opportunities for nesting conditions in loops, counting forwards and backwards, incrementing by something other than 1, understanding when `for` vs `while` is appropriate, getting comfortable with string manipulation and building up to arrays and functions. Given the fun factor and possibilities available, I don't think building an introductory course around ASCII patterns is a particulary absurd idea.

In regards to math, there can be as much or as little of it as you want in making these patterns. Consider patterns in [triangular numbers](https://en.wikipedia.org/wiki/Triangular_number), [Pascal's Triangle](https://en.wikipedia.org/wiki/Pascal%27s_triangle) and [cellular automata](https://en.wikipedia.org/wiki/Cellular_automaton), for starters. For the right audience, integrating trigonometric functions like sine and cosine functions can provide a great extension of possibilities. [Fractals](https://en.wikipedia.org/wiki/L-system) and [L-Systems](https://en.wikipedia.org/wiki/Fractal) can be fun to play with, given the right resolution and reasonably experienced coders.

Finally, as an educator, puzzles like these offer a great source of assignments that are relatively difficult to find direct solutions for on the internet, potentially helping combat plagiarism. It's easy to communicate the deliverables by showing a few example runs and explaining that it should work on any `n`. These problems are language-agnostic.

[Code Golf SE](https://codegolf.stackexchange.com/) has over 1000 posts in the [ascii-art](https://codegolf.stackexchange.com/questions/tagged/ascii-art) tag ripe for exploration. [Codewars](https://www.codewars.com/kata/search?q=ascii) has a good deal of ASCII shape printing problems with test cases (disclosure: I consult for the company that owns Codewars).


---

### Answer by username_6 on 2022-03-31. Score: 2

I think examples like these
1
1 2
1 2 3
1 2
1

1 
2 3
4 5 6
7 8 9 10
11 12 13 14 15 etc.

serve different purposes, e.g.:

Recognize or derive a construction (input)pattern from the optical (output) pattern
Numbers are probably the most primitive example of unique absolutely order-able items
It's probably rather easy to verify whether the solution is correct (comparing outputs)
the human brain is rather good detecting and recognizing patterns
Adding details like fancy strings instead of simple digits will just hide the essential structure

BTW: The first example is a stack where elements are popped from the right, while the second example is a stack where elements are popped at the left ;-)

> **Comments:**
> **username_7**: You are right about the first one, that is a classic stack, but you missed the second one, it's a simple nested loop. You wouldn't use a stack for this and if you use a queue then you've overcomplicated things, there are better patterns to compare stacks to queues.  
> **username_8**: +1 unlike in many other exercises, the output closely matches the flow of the program, making it easy to visualize whats happening in the code. It looks just like the output of a "printf-debugged" program.  
> **username_9**: @username_8: I think [Owen Reynold's answer](https://cseducators.stackexchange.com/a/7326/1654) comes closer to saying exactly that, but yeah, I'm not sure anyone's posted an answer where that's the main point.  Except the question's not asking why these are good teaching exercises, so maybe not.  

---

### Answer by username_10 on 2022-03-30. Score: 2

Patterns are everywhere in programming, and pattern recognition is the skill that is often so noticeably absent in fresh grads. They would often prefer to copy and paste code ad infinitum rather than recognize a pattern and avoid repetition through better design, inheritance, modularity, decorators, etc. Good question.


---

### Answer by username_11 on 2024-09-08. Score: 2

A colleague of mine once said that it is important to let students "practice success" occasionally. Some students lack confidence, so it is a good idea to give them something relatively simple to do, so that they can find out that they *can* program. This sort of task is good for that, because it involves some simple but non-trivial problem solving and some simple, but not trivial coding, and the student can immediately tell from the output whether they have got it working correctly. I don't think there is more too it than that. Back in the 1980s getting a computer to do that sort of thing was impressive/cool, but much less so now (which is a shame).

I often start with printing patterns of asterisks.


---

