<p>I am mostly in agreement with @kevinWorkman on this  (I don't disagree with anything, there is just one thing he was silent on, that I think is very important).</p>
<ul>
<li>Yes break down the problem.</li>
<li>Yes do one thing at a time.</li>
<li>Yes test often.</li>
</ul>
<p>In addition:</p>
<h1>Test first</h1>
<ol>
<li>Decide what the test is before you code.</li>
<li>Run the test to check that it fails.</li>
<li>Write some code.</li>
<li>Run the test to check it passes.</li>
<li>Iterate as required.</li>
</ol>
<h1>Just in time planning</h1>
<p>As part of doing one thing at a time.</p>
<blockquote>
<p>Our goal is to draw a garden scene with grass, flowers, and a bird that flies around. First let's try to break that up into smaller pieces. Can we create a simple program that just displays the grass part? (Which we can further split into drawing a single blade of grass,</p>
</blockquote>
<p><strong>STOP</strong> Planning</p>
<p>Time to code (Time to write a test, then code):</p>
<p>Using test first, write the code to draw a blade of grass.</p>
<p><strong>STOP</strong> Coding</p>
<p>Time to plan</p>
<blockquote>
<p>then a small patch [of grass],</p>
</blockquote>
<p><strong>STOP</strong> Planning</p>
<p>Time to code</p>
<h1>Summary</h1>
<ul>
<li>The process uses «alternating repetition» of planning / coding. Do not do any more planning than needed (do not plan ahead). Do not write any code that is not planned.</li>
<li>Coding uses «strong  boundaries»  test around code, with «alternating repetition» of fail/pass in the tests. That is test surrounds the code, and is of a similar scale as the code. The tests alternate between pass and fail. Do write any tests that are not needed (do not test ahead). Do not write any code that does not have a test that has failed.</li>
</ul>
<p>The properties in «» are from Christopher Alexander's book “The nature of order”. They are what patterns are made of. see <a href="https://cseducators.stackexchange.com/a/2821/204">https://cseducators.stackexchange.com/a/2821/204</a> for a list of all 15.</p>

CC BY-SA 3.0
2017-10-21T09:02:19.877Z
2017-10-21T09:02:19.877Z
2020-06-18T08:36:57.023Z
ctrl-alt-delor
<p>I'm going to echo <a href="https://cseducators.stackexchange.com/questions/3848/teaching-critical-thinking#comment8784_3848">ctrl-alt-delor's comment</a> and say that as one of the answerers on the original question, my understanding was not that "a few people suggested intro programming with true novices might not be the best place to introduce critical thinking/planning skills for programs". I don't think anybody suggested that. In fact I'm pretty sure that 100% of the people on this site would agree that critical thinking and problem solving are very important lessons to learn, especially with computer science. (And maybe even that computer science is a great way to teach general problem solving, but I'll digress.)</p>

<blockquote>
  <p>critical thinking/planning skills for programs</p>
</blockquote>

<p>I think the source of our misunderstanding is that we haven't really defined what this actually means. Your original question mentioned having students come up with a glossary of classes and functions they might find useful, and drawing diagrams. Imho, <strong>neither one of these is very good at teaching critical thinking or planning skills.</strong></p>

<p>I agree with your <strong>goal</strong> of teaching problem solving, and maybe planning depending on what you mean. What I disagree with is the <strong>approach</strong> of using glossaries and diagrams to teach these things.</p>

<p>Instead, I think the best way to teach problem solving and planning is by teaching <strong>the process of breaking a problem down into smaller steps</strong> and then taking those steps on one at a time. I've written <a href="http://happycoding.io/tutorials/how-to/program" rel="nofollow noreferrer">this tutorial</a> on the topic, and I try to encourage this process (as opposed to just dumping syntax) in my answers on Stack Overflow.</p>

<p>I don't think diagrams or glossaries really help with this. I think the only way to learn it is by working through the process. You might do this by live-coding a few examples of taking a large problem and breaking it down. I would teach using <a href="https://processing.org/" rel="nofollow noreferrer">Processing</a>, so my examples would be visual:</p>

<blockquote>
  <p>Our goal is to draw a garden scene with grass, flowers, and a bird that flies around. First let's try to break that up into smaller pieces. Can we create a simple program that just displays the grass part? (Which we can further split into drawing a single blade of grass, then a small patch, then the whole screen.) Separately from that, can we create a program that just displays one flower? (Again, that might be further split into drawing a stem, the center of the flower, the petals, etc.) Now can we just get a circle flying around?</p>
</blockquote>

<p>The idea would be to actually walk through the process of taking a big amorphous problem and breaking it down into smaller actionable steps, and then writing code to accomplish each of those steps one at a time.</p>

<p>Spending any time on diagrams at this stage is, imho, wasted time. Students don't have a big picture yet, and diagrams aren't appropriate for the scale we're talking about at this level. Similarly, forcing students to come up with their own glossary honestly sounds pretty painful, and isn't how things work in the real world. I think that's what the answerers were saying.</p>

CC BY-SA 3.0
2017-10-20T23:52:55.883Z
2017-10-20T23:52:55.883Z
Kevin Workman
<p>First, Critical Thinking is a deep concept and in a first course only simple aspects of it can be taught. To explore the depth of it you need to have context and a novice, by definition, has little of that. See <a href="https://en.wikipedia.org/wiki/Critical_thinking" rel="nofollow noreferrer">Wikipedia</a> for a start on understanding how broad and deep Critical Thinking really is. </p>

<p>To me, the most important question to be answered by Critical Thinking is "What should be built?" (and what <em>not built</em>). But a novice has no basis on which to answer such a question. They have enough to do to try to understand what <em>can be built</em> at the start, so you can only give a glimpse of the deeper questions then. </p>

<p>I would suggest that any true education explore Critical Thinking in many ways and in many courses - philosophy, history, .... And that later in the CS curriculum the topic be taken up, again in several courses/classes to explore its complete depth. </p>

<p>However, the detail in your question seems to indicate that you are more interested in <em>Deep Thinking</em> rather than Critical Thinking as such. I'm a big believer in teaching problem decomposition and abstraction from the first days. My courses delay <code>if</code> and <code>while</code> constructs for as long as I can manage while the students think about abstraction and polymorphism. I don't always do it, but prefer to teach recursive thinking before loops and polymorphism before selection. That is true even in a course in Java. It doesn't require Scheme.</p>

<p>But some aspects of critical thinking are useful to novices. For example, the idea that if what you are doing isn't working, then do something different. Also "Ask for help" when you are stuck. "Don't make assumptions" is another good idea that can be taught fairly early. "Test your assumptions."</p>

<p>Ultimately you want them to use evidence based decision making, of course rather than wishful or magical thinking, but that, as I said above, requires context and some "seasoning." Novices are naturally focused on the "how" rather than the "what" - especially the "what is appropriate" and "what is important." </p>

CC BY-SA 3.0
2017-10-20T18:49:26.277Z
2017-10-20T18:49:26.277Z
Buffy
<p>In answers to a <a href="https://cseducators.stackexchange.com/questions/3844/encouraging-critical-thinking-on-programs-before-students-write-them">previous question</a>, a few people suggested intro programming with true novices might not be the best place to introduce critical thinking/planning skills for programs. To me, intro programming is the perfect place - many of these skills relate to the ideas of breaking problems down (which tie in nicely with loops), abstraction (e.g., methods/classes), and so on. Particularly with many students only taking intro programming as part of a degree for an unrelated field (e.g., physics, math) in the hopes of being able to do some application-based work, I feel that students would benefit from these skills for such projects.</p>

<p>I am certainly open to be convinced on this topic! Should these skills be explicitly taught in a CS curriculum? If so, where?</p>

CC BY-SA 3.0
2017-10-20T18:03:27.327Z
At on of the answerers on you other question, I am sorry if you interpreted the answers this way. I said nothing about critical thinking, and for planning I only said that there should not be too much planning. Start with none and build it up. However I did say that some people do too much planning; Planning should be useful. I had a section in my answer to the other question **The value of planning** that (partly) answers this one.
ctrl-alt-delor
CC BY-SA 3.0
2017-10-20T20:23:57.497Z
@ctrl-alt-delor Nope, didn't mean to be critical! The answers just challenged me to reconsider whether such skills should even be taught at all, and if so, where in the curriculum. I personally think they should, and early, but wanted to solicit thoughts from others, particularly if there is any research on the matter.
cryptic_star
<curriculum-design><computational-thinking>
Teaching Critical Thinking
# Teaching Critical Thinking

(Asked by: username_0 on 2017-10-20)

In answers to a [previous question](https://cseducators.stackexchange.com/questions/3844/encouraging-critical-thinking-on-programs-before-students-write-them), a few people suggested intro programming with true novices might not be the best place to introduce critical thinking/planning skills for programs. To me, intro programming is the perfect place - many of these skills relate to the ideas of breaking problems down (which tie in nicely with loops), abstraction (e.g., methods/classes), and so on. Particularly with many students only taking intro programming as part of a degree for an unrelated field (e.g., physics, math) in the hopes of being able to do some application-based work, I feel that students would benefit from these skills for such projects.

I am certainly open to be convinced on this topic! Should these skills be explicitly taught in a CS curriculum? If so, where?

**Tags:** curriculum-design, computational-thinking

> **Comments:**
> **username_1**: At on of the answerers on you other question, I am sorry if you interpreted the answers this way. I said nothing about critical thinking, and for planning I only said that there should not be too much planning. Start with none and build it up. However I did say that some people do too much planning; Planning should be useful. I had a section in my answer to the other question **The value of planning** that (partly) answers this one.  
> **username_0**: @username_1 Nope, didn't mean to be critical! The answers just challenged me to reconsider whether such skills should even be taught at all, and if so, where in the curriculum. I personally think they should, and early, but wanted to solicit thoughts from others, particularly if there is any research on the matter.  

---

## 3 answers

### Answer by username_2 on 2017-10-20. Score: 2

I'm going to echo [username_1's comment](https://cseducators.stackexchange.com/questions/3848/teaching-critical-thinking#comment8784_3848) and say that as one of the answerers on the original question, my understanding was not that "a few people suggested intro programming with true novices might not be the best place to introduce critical thinking/planning skills for programs". I don't think anybody suggested that. In fact I'm pretty sure that 100% of the people on this site would agree that critical thinking and problem solving are very important lessons to learn, especially with computer science. (And maybe even that computer science is a great way to teach general problem solving, but I'll digress.)

> critical thinking/planning skills for programs

I think the source of our misunderstanding is that we haven't really defined what this actually means. Your original question mentioned having students come up with a glossary of classes and functions they might find useful, and drawing diagrams. Imho, **neither one of these is very good at teaching critical thinking or planning skills.**

I agree with your **goal** of teaching problem solving, and maybe planning depending on what you mean. What I disagree with is the **approach** of using glossaries and diagrams to teach these things.

Instead, I think the best way to teach problem solving and planning is by teaching **the process of breaking a problem down into smaller steps** and then taking those steps on one at a time. I've written [this tutorial](http://happycoding.io/tutorials/how-to/program) on the topic, and I try to encourage this process (as opposed to just dumping syntax) in my answers on Stack Overflow.

I don't think diagrams or glossaries really help with this. I think the only way to learn it is by working through the process. You might do this by live-coding a few examples of taking a large problem and breaking it down. I would teach using [Processing](https://processing.org/), so my examples would be visual:

> Our goal is to draw a garden scene with grass, flowers, and a bird that flies around. First let's try to break that up into smaller pieces. Can we create a simple program that just displays the grass part? (Which we can further split into drawing a single blade of grass, then a small patch, then the whole screen.) Separately from that, can we create a program that just displays one flower? (Again, that might be further split into drawing a stem, the center of the flower, the petals, etc.) Now can we just get a circle flying around?

The idea would be to actually walk through the process of taking a big amorphous problem and breaking it down into smaller actionable steps, and then writing code to accomplish each of those steps one at a time.

Spending any time on diagrams at this stage is, imho, wasted time. Students don't have a big picture yet, and diagrams aren't appropriate for the scale we're talking about at this level. Similarly, forcing students to come up with their own glossary honestly sounds pretty painful, and isn't how things work in the real world. I think that's what the answerers were saying.


---

### Answer by username_3 on 2017-10-20. Score: 2

First, Critical Thinking is a deep concept and in a first course only simple aspects of it can be taught. To explore the depth of it you need to have context and a novice, by definition, has little of that. See [Wikipedia](https://en.wikipedia.org/wiki/Critical_thinking) for a start on understanding how broad and deep Critical Thinking really is.

To me, the most important question to be answered by Critical Thinking is "What should be built?" (and what *not built*). But a novice has no basis on which to answer such a question. They have enough to do to try to understand what *can be built* at the start, so you can only give a glimpse of the deeper questions then.

I would suggest that any true education explore Critical Thinking in many ways and in many courses - philosophy, history, .... And that later in the CS curriculum the topic be taken up, again in several courses/classes to explore its complete depth.

However, the detail in your question seems to indicate that you are more interested in *Deep Thinking* rather than Critical Thinking as such. I'm a big believer in teaching problem decomposition and abstraction from the first days. My courses delay `if` and `while` constructs for as long as I can manage while the students think about abstraction and polymorphism. I don't always do it, but prefer to teach recursive thinking before loops and polymorphism before selection. That is true even in a course in Java. It doesn't require Scheme.

But some aspects of critical thinking are useful to novices. For example, the idea that if what you are doing isn't working, then do something different. Also "Ask for help" when you are stuck. "Don't make assumptions" is another good idea that can be taught fairly early. "Test your assumptions."

Ultimately you want them to use evidence based decision making, of course rather than wishful or magical thinking, but that, as I said above, requires context and some "seasoning." Novices are naturally focused on the "how" rather than the "what" - especially the "what is appropriate" and "what is important."


---

### Answer by username_1 on 2017-10-21. Score: 0

I am mostly in agreement with @kevinWorkman on this (I don't disagree with anything, there is just one thing he was silent on, that I think is very important).

* Yes break down the problem.
* Yes do one thing at a time.
* Yes test often.

In addition:

# Test first

1. Decide what the test is before you code.
2. Run the test to check that it fails.
3. Write some code.
4. Run the test to check it passes.
5. Iterate as required.

# Just in time planning

As part of doing one thing at a time.

> Our goal is to draw a garden scene with grass, flowers, and a bird that flies around. First let's try to break that up into smaller pieces. Can we create a simple program that just displays the grass part? (Which we can further split into drawing a single blade of grass,

**STOP** Planning

Time to code (Time to write a test, then code):

Using test first, write the code to draw a blade of grass.

**STOP** Coding

Time to plan

> then a small patch [of grass],

**STOP** Planning

Time to code

# Summary

* The process uses «alternating repetition» of planning / coding. Do not do any more planning than needed (do not plan ahead). Do not write any code that is not planned.
* Coding uses «strong boundaries» test around code, with «alternating repetition» of fail/pass in the tests. That is test surrounds the code, and is of a similar scale as the code. The tests alternate between pass and fail. Do write any tests that are not needed (do not test ahead). Do not write any code that does not have a test that has failed.

The properties in «» are from Christopher Alexander's book “The nature of order”. They are what patterns are made of. see <https://cseducators.stackexchange.com/a/2821/204> for a list of all 15.


---

