I completed the JavaScript Practice problem #3 but I’m wondering why my first attempt using a switch statement didn’t work. The function always returns default.
Coding question
Create a function numberDigits() that takes the variable x as its only parameter.
If the variable x is between 0 and 9, return the string ‘One digit: N’, where N is the value of x. For example, numberDigits(5) would return: ‘One digit: 5’
If the variable x is between 10 and 99, return the string ‘Two digits: N’, where N is the value of x. For example, numberDigits(12) would output: ‘Two digits: 12’
Any other value of x, including negative numbers, return the string ‘The number is: N’, where N is the value of x. For example, numberDigits(-202) would output: ‘The number is: -202’
My code:
function numberDigits(x){
switch(x) {
case (x>=0 && x<=9):
return One digit: ${x}
break;
case (x>=10 && x<=99):
return Two digits: ${x}
break;
default:
return The number is: ${x}
}
}
Hint: In the switch() argument, swap out x and substitute instead, true (no quotes).
switch (true) {
}
Now the types match.
Aside
The are some problems that are solvable with switch control flow, however, this problem is not, to my mind, one of them. It is a tool with limitations. How many cases do we need for a twenty digit number? Take what you can learn from this ‘experiment’ and resolve to find a solution that works for arbitrarily large numbers, with no real limitation.
One example might be counting how many times we can floor divide a number by 10 before it is reduced to zero. Below is an example, only written in Python:
>>> n = 7654321
>>> m = 0
>>> while n > 0:
... m += 1
... n //= 10
...
...
>>> n
0
>>> m
7
>>>
We can do the same thing in JavaScript, except // would be written as,
Total aside that will take some pondering, but the gist is there for you to port this code over to JavaScript and write a nice clean function. Again, its in Python, except this time with a little added logic.
# digit_count.py
def digs(x):
'''
x is integer ? hasattr(x, 'to_bytes') expect, True
x is boolean ? hasattr(x, 'to_bytes') expect, True (moot)
x is negative ? x = abs(x)
x is zero ? return m or 1
'''
if hasattr(x, 'to_bytes'): # only int & bool have this attr
x = abs(x)
m = 0
while x > 0:
m += 1
x //= 10
return m or 1
else: raise TypeError
Not that I really want to interfere in your discovery of a working solution, but if you are reading this, you are technically ‘discovering’ something new, so here goes with a working JS port of the Python code, above:
const digs = function (n) {
n = Math.abs(+n)
if (n % 1 == 0) {
m = 0
while (n > 0) {
m += 1
n = Math.floor(n / 10)
}
return m || 1
} else {
throw TypeError
}
}
It might take you to the end of this course to fully decipher it, so don’t be using it unless you have already got the gist and could write this stuff yourself. Learn from it. Learners are always telling us they don’t get enough examples. Well, here’s one. By the time you fully understand it, you will be telling us about its possible weaknesses. We needn’t go there, today, or even next week. Just bookmark this and come back to it when you are further along.
When/if you care to discuss this for furtherance of learning, ping this topic and we can explore it together. JS is a very peculiar language, and it’s stuff like this that (bear/bare)s it out. There are some things that need to be discussed, to be sure. When you’re ready…
>>> def digits(n):
... from math import log10, floor
... if hasattr(n, 'to_bytes'):
... n = abs(n)
... return 1 if n == 0 else floor(log10(n) + 1)
... raise TypeError
...
>>> digits(10)
2
>>> digits(0)
1
>>> digits(True)
1
>>> digits(2.1)
Traceback (most recent call last):
File "<pyshell#136>", line 1, in <module>
digits(2.1)
File "<pyshell#130>", line 6, in digits
raise TypeError
TypeError
>>>
With the given insights, you should be able to port this to JS. Happy practice time!
This is built on an understanding of logarithms, a high school Maths concept usually introduced in the second year (Grade 11). It is such a useful concept going forward one will never worry about forgetting it, once learned.
logs permit us to work with numbers of any base, and translate those numbers to a specific base. In the digit count problem we are dealing with base 10, decimal. Given any number, in any base,
log_base10_of_x is log_any_base_of_x / log_any_base_of_10
Your studies will cover this ground, especially if you are going into analytics.
Just throwing this out there…
const digits = function (n) {
n = Math.abs(n)
if (n % 1 == 0) {
return n == 0 ? 1 : Math.floor(Math.log10(n) + 1)
}
throw TypeError
}
Would it were we could find the weaknesses and downsides to this code. Please test and report findings.