<p>You say “when he is finished, he no longer fully understands them.”</p>

<p>There is a good practice to write self documenting code. This is done not with comments, but with well named entities (methods, classes, objects). This helps you to see what the code does (I do not mean how it does it, but in turn it will help you understand how it works).</p>

<p>Therefore teach him how to do self documenting code.</p>

<p>Example
<code>if ((n+"").length() == (((n+1)+"").length())) {</code></p>

<p>Do</p>

<pre><code>private static boolean digitsInInteger( int n ) {
    return n.ToString().length();
}

private static boolean integersHaveSameNumberOfDigits(int a, int b){
    return digitsInInteger(a) == digitsInInteger(b);
}

if ( integersHaveSameNumberOfDigits( n, n+1 ) ) { …
</code></pre>

<p>You can even put <code>integersHaveSameNumberOfDigits( n, n+1 )</code> into a function, but I did not know what to call it.</p>

<p>Example
<code>while (temperature &lt; 100 &amp;&amp; unHatched())</code></p>

<p>Do</p>

<pre><code>private static boolean isColdEnoughNotToCookEggs( int temperature ){
    return temperature &lt; 100;
}

private boolean eggsAreStillViable(){
    return isColdEnoughNotToCookEggs(temperature) &amp;&amp; eggs.areUnHatched();
}

while (eggsAreStillViable() ){ …
</code></pre>

<p><em>This example was a bit harder to refactor, as I had to guess the intent.</em></p>

<hr>

<p>Code in this answer may not be Java. </p>

CC BY-SA 3.0
2017-08-11T14:47:15.407Z
How  To call ?  isNotAPowerOf10minus1 (int n)
Michel Billaud
CC BY-SA 3.0
2017-08-15T09:37:54.363Z
@MichelBillaud can you repeat your comment, with context and grammar; I have no idea what its meaning is.
ctrl-alt-delor
CC BY-SA 3.0
2017-08-15T10:45:55.727Z
n and n+1 (I suppose n is strictly positive) have the same number of digits (in the decimal representation), except when n is made of sequence of 9's.  That is when n = 10^k - 1, for some k (and then n+1 = 10^k. n has k-1 digits, n+1 has k.
Thus the name of a predicate should state something about n not being a power of 10 minus 1.
Michel Billaud
CC BY-SA 3.0
2017-08-15T11:02:46.993Z
@MichelBillaud I grok you now. However to name something well, you have to know the intention. It should not be based on how it does it, but on what it does. That is what externally visible behaviour it has.
ctrl-alt-delor
CC BY-SA 3.0
2017-08-15T15:01:05.173Z
Of course, you're right.   
boolean hasTheSameNumberOfDigitsAsItsSuccessor(int n) { return ! isAPowerOf10(n+1); }
Michel Billaud
CC BY-SA 3.0
2017-08-15T17:05:22.480Z
@michel I would find out what the intention of the code is. Instead of searching for mathematical explanations that are coincident with the intention. These coincident functions are good for implementing, but will not make the code easier to understand. E.g. isHouseOnLeft(int house number) may use isEven(int n) for some roads (but will also need direction of travel ). So call it by what it does, not by how it does it.
ctrl-alt-delor
CC BY-SA 3.0
2017-08-15T17:36:21.607Z
"if(hasTheSameNumberOfDigitsAsItsSuccessor(n))" is a clear explicit and non-ambiguous description of the intention of "if((n+"").length() == (((n+1)+"").length()))". Checking powers of 10 and computing/comparing the number of digits are 2 possible implementations.  The formula as given relies on tricks (eg.  n+""  to convert a number into a string - instead of the standard Integer.toString()), and code duplication (for n and n+1). So it should never have been written as such, from the beginning. "if (numberOfdigits(n) == numberOfDigits(n+1))" is ok, of course.
Michel Billaud
CC BY-SA 3.0
2017-08-09T21:34:55.887Z
2017-08-15T17:08:17.663Z
2017-08-15T17:08:17.663Z
ctrl-alt-delor
<p>Package this in a static method like so.  You are only really interested in whether the successor of a number has more digits than the number. This is clean and it avoids interface clutter.   It also keeps the intermediate variables local; unless you have a need, you do not want to expose them in your interface.  Note it is static since it is state-invariant.</p>

<p><code>
/**<br>
*   This &lt;code&gt;static&lt;/code&gt; method tells if an integer's successor has<br>
*   more digits than the integer.
*   @param n the integer you are checking
*   @return true if the integer &lt;code&gt;n&lt;/code&gt;'s successor has more
*   digits than &lt;code&gt;n&lt;/code&gt;.
*/<br>
public static boolean successorLonger(n)
{
    String nString = "" + n;
    String succString = "" + (n + 1);
    return nString.length() != succString.length();
}
</code></p>

CC BY-SA 3.0
2017-08-14T18:00:33.830Z
2017-08-15T17:06:55.723Z
2017-08-15T17:06:55.723Z
ncmathsadist
<p>I suspect that <em>you</em> handle such situations by informally building the parse tree of the expression in your mind. Maybe not all at once, but a bit at a time, perhaps. I'm not a cognition expert, of course, but it might help him if you teach him to do it explicitly on paper. He needs a table of operator precedence, of course and needs to be able to deal with parentheses, but otherwise it is just a mechanical process. Put the lowest precedence operator at the root of a tree and then work on the operands. The interior nodes are operators and the leaves are operands. </p>

<p>Can't promise it will work, but it would be my next step. With time, he may learn to rely less on the paper. Or, he might learn how to build a tool to do it automatically. That might be nice to have. </p>

CC BY-SA 3.0
2017-08-09T17:05:59.967Z
2017-08-09T17:05:59.967Z
Buffy
<p>I think the student's problem is not with types, but first with the <strong>parsing</strong> of complex expressions (not to be confused with the <strong>tracing</strong> of it's evaluation). Mentally building the abstract syntax tree from the linear text representation.</p>

<p>First rewrite remove the extra parentheses at right, and introduce a line break</p>

<pre><code>if (    (n+"").length() 
     == ((n+1)+"").length()) {
</code></pre>

<p>to split the expression. It make clear you are comparing two lengths = ints.</p>

<p>Second make it obvious that the 2 sides of the comparison have the same pattern</p>

<pre><code>if (    (n    +"").length() 
     == ((n+1)+"").length()) {
</code></pre>

<p>a cosmetic change which drastically reduces the problem space : there's a hope that if we can figure what happens at the left for n, we'll understand the right part too.</p>

<p>What's left is producing a string from an int. Not the best way (what about <code>Integer.toString</code> ?) but anyway.</p>

<p>Actually, only one typecast is involved, twice.</p>

<p><a href="https://i.sstatic.net/d7m4h.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/d7m4h.png" alt="abstract tree"></a></p>

<p>As for "writing code he can't understand later", it'a common symptom. The  problem is not he cannot understand it, but that he wrote too complex code in the first place. Beginners always overestimate their cognition abilities. And they are reluctant to decomposition because it requires an effort to clearly identify a sub-task (and find a nice name for it !) </p>

<p>Remedies : insist on </p>

<ul>
<li>using auxiliary variables</li>
<li>define and use of "helper" functions, predicates.</li>
</ul>

CC BY-SA 3.0
2017-08-16T09:25:12.107Z
2017-08-16T10:23:42.217Z
2017-08-16T10:23:42.217Z
Michel Billaud
<p>I'd maybe suggest an exercise of splitting these kinds of statements up into multiple variables and lines of code.</p>

<p>So take this line:</p>

<pre><code>if ((n+"").length() == (((n+1)+"").length())) {
</code></pre>

<p>And come up with this code:</p>

<pre><code>String nString = n + "";
int nLength = stringN.length();
int nPlusOne = n+1;
String nPlusOneString = nPlusOne + "";
int nPlusOneLength = nPlusOneString.length();
boolean nLengthEqualsNPlusOneLength = (nLength == nPlusOneLength);
if(nLengthEqualsNPlusOneLength){
</code></pre>

<p>This is what you're asking the student to do in their head, so maybe the intermediate step of actually writing out the breakdown like this would help. Make sure the student uses descriptive variable names so they can more easily keep track of what each step is doing.</p>

<p>If you do this process of breaking a line down into smaller sub-lines enough, eventually you'll become more "natural" at it, and you won't have to explicitly break it down anymore.</p>

<p>It's worth noting that if I saw a line like the original in "the real world" I would ask the author of the code to split it up into multiple pieces, or at least add a comment or isolate it into a self-descriptive function.</p>

CC BY-SA 3.0
2017-08-13T20:12:19.470Z
You have broken this into steps that are too small.  There is a lot of namespace clutter here.
ncmathsadist
CC BY-SA 3.0
2017-08-13T20:43:44.770Z
@ncmathsadist What exactly do you mean by "namespace clutter" in this context? I would assume these are all local variables inside a function. Also please keep in mind that the point of this exercise is to get the student to a point where they no longer need to do this. Code you write while learning != code you write in real life.
Kevin Workman
CC BY-SA 3.0
2017-08-14T01:14:54.130Z
too many variable names.
ncmathsadist
CC BY-SA 3.0
2017-08-14T02:17:09.890Z
@ncmathsadist You understand that the point of this exercise is to break it down into smaller steps, right? And that this type of code is meant for learning and not for production?
Kevin Workman
CC BY-SA 3.0
2017-08-14T13:33:31.857Z
but not too small.
ncmathsadist
CC BY-SA 3.0
2017-08-14T16:02:40.123Z
@ncmathsadist I'm really not sure what your point is. If this was production code, I *might* agree with you. But this is code meant to teach the process of breaking things down into smaller steps. Smaller is better in this context.
Kevin Workman
CC BY-SA 3.0
2017-08-16T12:57:01.790Z
It's about seeing *what happens* in some parts of the expression (namely:  `n+""`), not necessarily refactoring it into many variables until they're all dead.
Michel Billaud
CC BY-SA 3.0
2017-08-16T17:17:57.820Z
Smaller is not _always_ better.  If it was, then we'd all be writing assembly language.  IMO `nPlusOne` is slightly _harder_ to read than `(n+1)`.  Also, the goal of the exercise is to compare the number of digits in `n` to the number of digits in `(n+1)`, but the word "digits" appears nowhere in your "simpler" example.
Solomon Slow
CC BY-SA 3.0
2017-08-17T14:46:11.703Z
@jameslarge This is code I threw together without really thinking about it. Imho the actual code is secondary to the real "meat" of the answer, which is the exercise in general. Getting hung up on the precise syntax of the code (which is based on example code from the question anyway) is missing the point of the question and my answer, I think.
Kevin Workman
CC BY-SA 3.0
2017-08-09T17:06:15.023Z
2017-08-09T17:06:15.023Z
Kevin Workman
<p>So, take a Java statement like this one, given some int <code>n</code>:</p>

<pre><code>if ((n+"").length() == (((n+1)+"").length())) {
</code></pre>

<p>Or perhaps this one, given some double, <code>temperature</code>, and some method that returns a boolean, <code>unHatched()</code>:</p>

<pre><code>while (temperature &lt; 100 &amp;&amp; unHatched())
</code></pre>

<p>In both of these cases, multiple auto-casts are made during the evaluation of the statement, and in both cases, the final determination is a boolean that is passed into some sort of control structure.</p>

<p>In my work with gifted students, the most that I have ever had to do to help someone understand statements like these is to do a simple trace.  We write the statement down, mark each item by its type, and then cross off areas of the statement (and write down the new types) as we walk through the evaluation.  This method has worked pretty consistently with my students at my day-job.</p>

<p>However, lately I have begun tutoring an adult student who is having a <em>great deal of trouble</em>, and I have been struggling to break apart statements like the above examples in ways that he can parse and keep straight.</p>

<p>He is at the right point, curricularly-speaking, to be examining them, but I am really struggling to help him trace and understand such statements.  (Ironically enough, because he can guess and modify a statement repeatedly, he can actually <em>write</em> statements like these with a fair amount of success, though when he is finished, he no longer fully understands them.)</p>

<p>For various reasons, learning a small concept usually takes him 3-5 weeks.  This timescale is fine, it is simply the speed at which he operates.  However, this adds a constraint for me: approaches that I take to the material must lend themselves to a fair amount of repetition with only very minor variations, or they won't be effective. </p>

<p>I am really having trouble finding a good approach here.  How can I give him the tools to break down statements with complex data type transformations?</p>

CC BY-SA 3.0
2017-08-09T21:17:44.143Z
That 2nd example `while (temperature < 100 && unHatched())`, has no cast or type conversion: `<` takes 2 comparable, and returns a boolean, then `&&` takes 2 booleans and returns a boolean, then `while` takes a boolean.
ctrl-alt-delor
CC BY-SA 3.0
2017-08-15T15:20:41.210Z
May be he could write such statements, but he should know (and use) other ways to express the same idea. For example : write auxiliary functions (here numberOfDigits(int n)), use superfluous parentheses  to help readability ( around temperature<100).  The key challenge in programming is to manage the complexity and the readability of the text we produce. The milk quickly goes over.
Michel Billaud
CC BY-SA 3.0
2017-08-15T17:45:30.033Z
Another point : be careful with such exercices. Some students could conclude they are expected to write programs this way if they want to look smart.
Michel Billaud
<data-types><casting>
Breaking down the operations when auto-casting gets complex
# Breaking down the operations when auto-casting gets complex

(Asked by: username_0 on 2017-08-09)

So, take a Java statement like this one, given some int n:
if ((n+"").length() == (((n+1)+"").length())) {

Or perhaps this one, given some double, temperature, and some method that returns a boolean, unHatched():
while (temperature < 100 && unHatched())

In both of these cases, multiple auto-casts are made during the evaluation of the statement, and in both cases, the final determination is a boolean that is passed into some sort of control structure.
In my work with gifted students, the most that I have ever had to do to help someone understand statements like these is to do a simple trace.  We write the statement down, mark each item by its type, and then cross off areas of the statement (and write down the new types) as we walk through the evaluation.  This method has worked pretty consistently with my students at my day-job.
However, lately I have begun tutoring an adult student who is having a great deal of trouble, and I have been struggling to break apart statements like the above examples in ways that he can parse and keep straight.
He is at the right point, curricularly-speaking, to be examining them, but I am really struggling to help him trace and understand such statements.  (Ironically enough, because he can guess and modify a statement repeatedly, he can actually write statements like these with a fair amount of success, though when he is finished, he no longer fully understands them.)
For various reasons, learning a small concept usually takes him 3-5 weeks.  This timescale is fine, it is simply the speed at which he operates.  However, this adds a constraint for me: approaches that I take to the material must lend themselves to a fair amount of repetition with only very minor variations, or they won't be effective. 
I am really having trouble finding a good approach here.  How can I give him the tools to break down statements with complex data type transformations?

**Tags:** data-types, casting

> **Comments:**
> **username_1**: That 2nd example `while (temperature < 100 && unHatched())`, has no cast or type conversion: `<` takes 2 comparable, and returns a boolean, then `&&` takes 2 booleans and returns a boolean, then `while` takes a boolean.  
> **username_2**: May be he could write such statements, but he should know (and use) other ways to express the same idea. For example : write auxiliary functions (here numberOfDigits(int n)), use superfluous parentheses  to help readability ( around temperature<100).  The key challenge in programming is to manage the complexity and the readability of the text we produce. The milk quickly goes over.  
> **username_2**: Another point : be careful with such exercices. Some students could conclude they are expected to write programs this way if they want to look smart.  

---

## 5 answers

### Answer by username_4 on 2017-08-09. Score: 4

I suspect that *you* handle such situations by informally building the parse tree of the expression in your mind. Maybe not all at once, but a bit at a time, perhaps. I'm not a cognition expert, of course, but it might help him if you teach him to do it explicitly on paper. He needs a table of operator precedence, of course and needs to be able to deal with parentheses, but otherwise it is just a mechanical process. Put the lowest precedence operator at the root of a tree and then work on the operands. The interior nodes are operators and the leaves are operands.

Can't promise it will work, but it would be my next step. With time, he may learn to rely less on the paper. Or, he might learn how to build a tool to do it automatically. That might be nice to have.


---

### Answer by username_5 on 2017-08-09. Score: 4

I'd maybe suggest an exercise of splitting these kinds of statements up into multiple variables and lines of code.
So take this line:
if ((n+"").length() == (((n+1)+"").length())) {

And come up with this code:
String nString = n + "";
int nLength = stringN.length();
int nPlusOne = n+1;
String nPlusOneString = nPlusOne + "";
int nPlusOneLength = nPlusOneString.length();
boolean nLengthEqualsNPlusOneLength = (nLength == nPlusOneLength);
if(nLengthEqualsNPlusOneLength){

This is what you're asking the student to do in their head, so maybe the intermediate step of actually writing out the breakdown like this would help. Make sure the student uses descriptive variable names so they can more easily keep track of what each step is doing.
If you do this process of breaking a line down into smaller sub-lines enough, eventually you'll become more "natural" at it, and you won't have to explicitly break it down anymore.
It's worth noting that if I saw a line like the original in "the real world" I would ask the author of the code to split it up into multiple pieces, or at least add a comment or isolate it into a self-descriptive function.

> **Comments:**
> **username_3**: You have broken this into steps that are too small.  There is a lot of namespace clutter here.  
> **username_5**: @username_3 What exactly do you mean by "namespace clutter" in this context? I would assume these are all local variables inside a function. Also please keep in mind that the point of this exercise is to get the student to a point where they no longer need to do this. Code you write while learning != code you write in real life.  
> **username_3**: too many variable names.  
> **username_5**: @username_3 You understand that the point of this exercise is to break it down into smaller steps, right? And that this type of code is meant for learning and not for production?  
> **username_3**: but not too small.  
> **username_5**: @username_3 I'm really not sure what your point is. If this was production code, I *might* agree with you. But this is code meant to teach the process of breaking things down into smaller steps. Smaller is better in this context.  
> **username_2**: It's about seeing *what happens* in some parts of the expression (namely:  `n+""`), not necessarily refactoring it into many variables until they're all dead.  
> **username_6**: Smaller is not _always_ better.  If it was, then we'd all be writing assembly language.  IMO `nPlusOne` is slightly _harder_ to read than `(n+1)`.  Also, the goal of the exercise is to compare the number of digits in `n` to the number of digits in `(n+1)`, but the word "digits" appears nowhere in your "simpler" example.  
> **username_5**: @jameslarge This is code I threw together without really thinking about it. Imho the actual code is secondary to the real "meat" of the answer, which is the exercise in general. Getting hung up on the precise syntax of the code (which is based on example code from the question anyway) is missing the point of the question and my answer, I think.  

---

### Answer by username_2 on 2017-08-16. Score: 3

I think the student's problem is not with types, but first with the parsing of complex expressions (not to be confused with the tracing of it's evaluation). Mentally building the abstract syntax tree from the linear text representation.
First rewrite remove the extra parentheses at right, and introduce a line break
if (    (n+"").length() 
     == ((n+1)+"").length()) {

to split the expression. It make clear you are comparing two lengths = ints.
Second make it obvious that the 2 sides of the comparison have the same pattern
if (    (n    +"").length() 
     == ((n+1)+"").length()) {

a cosmetic change which drastically reduces the problem space : there's a hope that if we can figure what happens at the left for n, we'll understand the right part too.
What's left is producing a string from an int. Not the best way (what about Integer.toString ?) but anyway.
Actually, only one typecast is involved, twice.

As for "writing code he can't understand later", it'a common symptom. The  problem is not he cannot understand it, but that he wrote too complex code in the first place. Beginners always overestimate their cognition abilities. And they are reluctant to decomposition because it requires an effort to clearly identify a sub-task (and find a nice name for it !) 
Remedies : insist on 

using auxiliary variables
define and use of "helper" functions, predicates.


---

### Answer by username_1 on 2017-08-09. Score: 1

You say “when he is finished, he no longer fully understands them.”
There is a good practice to write self documenting code. This is done not with comments, but with well named entities (methods, classes, objects). This helps you to see what the code does (I do not mean how it does it, but in turn it will help you understand how it works).
Therefore teach him how to do self documenting code.
Example
if ((n+"").length() == (((n+1)+"").length())) {
Do
private static boolean digitsInInteger( int n ) {
    return n.ToString().length();
}

private static boolean integersHaveSameNumberOfDigits(int a, int b){
    return digitsInInteger(a) == digitsInInteger(b);
}

if ( integersHaveSameNumberOfDigits( n, n+1 ) ) { …

You can even put integersHaveSameNumberOfDigits( n, n+1 ) into a function, but I did not know what to call it.
Example
while (temperature < 100 && unHatched())
Do
private static boolean isColdEnoughNotToCookEggs( int temperature ){
    return temperature < 100;
}

private boolean eggsAreStillViable(){
    return isColdEnoughNotToCookEggs(temperature) && eggs.areUnHatched();
}

while (eggsAreStillViable() ){ …

This example was a bit harder to refactor, as I had to guess the intent.

Code in this answer may not be Java.

> **Comments:**
> **username_2**: How  To call ?  isNotAPowerOf10minus1 (int n)  
> **username_1**: @MichelBillaud can you repeat your comment, with context and grammar; I have no idea what its meaning is.  
> **username_2**: n and n+1 (I suppose n is strictly positive) have the same number of digits (in the decimal representation), except when n is made of sequence of 9's.  That is when n = 10^k - 1, for some k (and then n+1 = 10^k. n has k-1 digits, n+1 has k. Thus the name of a predicate should state something about n not being a power of 10 minus 1.  
> **username_1**: @MichelBillaud I grok you now. However to name something well, you have to know the intention. It should not be based on how it does it, but on what it does. That is what externally visible behaviour it has.  
> **username_2**: Of course, you're right.    boolean hasTheSameNumberOfDigitsAsItsSuccessor(int n) { return ! isAPowerOf10(n+1); }  
> **username_1**: @michel I would find out what the intention of the code is. Instead of searching for mathematical explanations that are coincident with the intention. These coincident functions are good for implementing, but will not make the code easier to understand. E.g. isHouseOnLeft(int house number) may use isEven(int n) for some roads (but will also need direction of travel ). So call it by what it does, not by how it does it.  
> **username_2**: "if(hasTheSameNumberOfDigitsAsItsSuccessor(n))" is a clear explicit and non-ambiguous description of the intention of "if((n+"").length() == (((n+1)+"").length()))". Checking powers of 10 and computing/comparing the number of digits are 2 possible implementations.  The formula as given relies on tricks (eg.  n+""  to convert a number into a string - instead of the standard Integer.toString()), and code duplication (for n and n+1). So it should never have been written as such, from the beginning. "if (numberOfdigits(n) == numberOfDigits(n+1))" is ok, of course.  

---

### Answer by username_3 on 2017-08-14. Score: -1

Package this in a static method like so. You are only really interested in whether the successor of a number has more digits than the number. This is clean and it avoids interface clutter. It also keeps the intermediate variables local; unless you have a need, you do not want to expose them in your interface. Note it is static since it is state-invariant.

`/**  
* This static method tells if an integer's successor has  
* more digits than the integer.
* @param n the integer you are checking
* @return true if the integer n's successor has more
* digits than n.
*/  
public static boolean successorLonger(n)
{
String nString = "" + n;
String succString = "" + (n + 1);
return nString.length() != succString.length();
}`


---

