First n Happy Numbers
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I wrote a piece of code to generate a list of $n$ Happy Numbers, would love to see how I can write it better. More information below.
#a happy number is defined is found by taking a number, and adding the sum of its digits, and repeating the steps to add the sum of square
#of the resultant digits until we reach 1, if the result never reaches 1 then it is not a happy number
# example: number = 7
# 7^2 = 49
# 4^2 + 9^2 = 16+81 = 97
# 9^2 + 7^2 = 81 + 49 = 130
# 1^2 + 3^2 + 0 = 1+9 = 10
# 1^2 + 0 = 1 HAPPY number
#defining a emtpy list that will be populate as soon as we encounter a happy number
happy_numbers =
sqdict=str(i):i**2 for i in range(10)
#lets define our adder
def adder3(num):
return sum(sqdict[i] for i in str(num))
#now we need to take a number and keep adding until we get a 1 or the loop keeps repeating
# lets define a function for that
def happynum (num, counter):
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
if i_sum == 1: # check for happy number
happy_numbers.append(number)
# print("The given number is a happy number.".format(number))
return 1
else: # we continue to keep splitting and adding until we reach 1 or attain infinite loop
counter +=1
if counter > 50:
# print("The number isnt happy :(.".format(number))
return False
else:
happynum(i_sum,counter)
counter = 0 # initializing a counter to keep keep track of the infinite loop if it does reach that.
# user_num = 7
for i in range (0, 1000):
number = i
happynum(number, counter)
print(happy_numbers[10])
The code above is working well for what I am trying to achieve. However, I tried defining the counter as a global variable before all the methods, but when called in the method I was not able to increment. It threw aa error "local variable referenced before assignment".
Additionally, I am not sure using a for loop in the end to generate 1000 Happy Numbers is an efficient way, it seems somewhat limiting. Would appreciate some help on this.
python mathematics
add a comment |Â
up vote
3
down vote
favorite
I wrote a piece of code to generate a list of $n$ Happy Numbers, would love to see how I can write it better. More information below.
#a happy number is defined is found by taking a number, and adding the sum of its digits, and repeating the steps to add the sum of square
#of the resultant digits until we reach 1, if the result never reaches 1 then it is not a happy number
# example: number = 7
# 7^2 = 49
# 4^2 + 9^2 = 16+81 = 97
# 9^2 + 7^2 = 81 + 49 = 130
# 1^2 + 3^2 + 0 = 1+9 = 10
# 1^2 + 0 = 1 HAPPY number
#defining a emtpy list that will be populate as soon as we encounter a happy number
happy_numbers =
sqdict=str(i):i**2 for i in range(10)
#lets define our adder
def adder3(num):
return sum(sqdict[i] for i in str(num))
#now we need to take a number and keep adding until we get a 1 or the loop keeps repeating
# lets define a function for that
def happynum (num, counter):
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
if i_sum == 1: # check for happy number
happy_numbers.append(number)
# print("The given number is a happy number.".format(number))
return 1
else: # we continue to keep splitting and adding until we reach 1 or attain infinite loop
counter +=1
if counter > 50:
# print("The number isnt happy :(.".format(number))
return False
else:
happynum(i_sum,counter)
counter = 0 # initializing a counter to keep keep track of the infinite loop if it does reach that.
# user_num = 7
for i in range (0, 1000):
number = i
happynum(number, counter)
print(happy_numbers[10])
The code above is working well for what I am trying to achieve. However, I tried defining the counter as a global variable before all the methods, but when called in the method I was not able to increment. It threw aa error "local variable referenced before assignment".
Additionally, I am not sure using a for loop in the end to generate 1000 Happy Numbers is an efficient way, it seems somewhat limiting. Would appreciate some help on this.
python mathematics
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I wrote a piece of code to generate a list of $n$ Happy Numbers, would love to see how I can write it better. More information below.
#a happy number is defined is found by taking a number, and adding the sum of its digits, and repeating the steps to add the sum of square
#of the resultant digits until we reach 1, if the result never reaches 1 then it is not a happy number
# example: number = 7
# 7^2 = 49
# 4^2 + 9^2 = 16+81 = 97
# 9^2 + 7^2 = 81 + 49 = 130
# 1^2 + 3^2 + 0 = 1+9 = 10
# 1^2 + 0 = 1 HAPPY number
#defining a emtpy list that will be populate as soon as we encounter a happy number
happy_numbers =
sqdict=str(i):i**2 for i in range(10)
#lets define our adder
def adder3(num):
return sum(sqdict[i] for i in str(num))
#now we need to take a number and keep adding until we get a 1 or the loop keeps repeating
# lets define a function for that
def happynum (num, counter):
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
if i_sum == 1: # check for happy number
happy_numbers.append(number)
# print("The given number is a happy number.".format(number))
return 1
else: # we continue to keep splitting and adding until we reach 1 or attain infinite loop
counter +=1
if counter > 50:
# print("The number isnt happy :(.".format(number))
return False
else:
happynum(i_sum,counter)
counter = 0 # initializing a counter to keep keep track of the infinite loop if it does reach that.
# user_num = 7
for i in range (0, 1000):
number = i
happynum(number, counter)
print(happy_numbers[10])
The code above is working well for what I am trying to achieve. However, I tried defining the counter as a global variable before all the methods, but when called in the method I was not able to increment. It threw aa error "local variable referenced before assignment".
Additionally, I am not sure using a for loop in the end to generate 1000 Happy Numbers is an efficient way, it seems somewhat limiting. Would appreciate some help on this.
python mathematics
I wrote a piece of code to generate a list of $n$ Happy Numbers, would love to see how I can write it better. More information below.
#a happy number is defined is found by taking a number, and adding the sum of its digits, and repeating the steps to add the sum of square
#of the resultant digits until we reach 1, if the result never reaches 1 then it is not a happy number
# example: number = 7
# 7^2 = 49
# 4^2 + 9^2 = 16+81 = 97
# 9^2 + 7^2 = 81 + 49 = 130
# 1^2 + 3^2 + 0 = 1+9 = 10
# 1^2 + 0 = 1 HAPPY number
#defining a emtpy list that will be populate as soon as we encounter a happy number
happy_numbers =
sqdict=str(i):i**2 for i in range(10)
#lets define our adder
def adder3(num):
return sum(sqdict[i] for i in str(num))
#now we need to take a number and keep adding until we get a 1 or the loop keeps repeating
# lets define a function for that
def happynum (num, counter):
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
if i_sum == 1: # check for happy number
happy_numbers.append(number)
# print("The given number is a happy number.".format(number))
return 1
else: # we continue to keep splitting and adding until we reach 1 or attain infinite loop
counter +=1
if counter > 50:
# print("The number isnt happy :(.".format(number))
return False
else:
happynum(i_sum,counter)
counter = 0 # initializing a counter to keep keep track of the infinite loop if it does reach that.
# user_num = 7
for i in range (0, 1000):
number = i
happynum(number, counter)
print(happy_numbers[10])
The code above is working well for what I am trying to achieve. However, I tried defining the counter as a global variable before all the methods, but when called in the method I was not able to increment. It threw aa error "local variable referenced before assignment".
Additionally, I am not sure using a for loop in the end to generate 1000 Happy Numbers is an efficient way, it seems somewhat limiting. Would appreciate some help on this.
python mathematics
edited Jan 27 at 12:41
asked Jan 27 at 11:11
user9267433
163
163
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
1
down vote
Coding style
There is too little white space at many places, for example
sqdict=str(i):i**2 for i in range(10)
This and other PEP8 coding style
violations (most of them related to spacing and too long comment lines)
can be detected by checking your code at PEP8 online.
Unnecessary comments
There are some comments which add no information to the code and can safely be removed,
such as
#lets define our adder
def adder3(num):
or
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
Naming
def adder3(num):
Is is impossible to guess from the function name what its purpose might be.
I'd suggest something like square_digit_sum
.
def happynum (num, counter):
Here we know what the function is about, what does it do? Compute a happy number,
check for happy number, ...?
Code structure:
The global variable counter = 0
is not used at all and can be removed.
A global variable number = i
is used to "remember" the argument of
the inital call to the recursive happynum
function, and the function
(as a "side effect") appends to the global happy_numbers
array.
This is error-prone and not very elegant.
I'd suggest to define a function is_happy
instead, which takes a number and
recursion limit, and returns True or False. The default recursion limit can be
defined as a default parameter value:
def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)
Note also that no else:
block is needed if the if:
block
has a return statement. This saves indenting levels.
Then you can use list comprehension
happy_numbers = [num for num in range(1000) if is_happy(num)]
or a filter
happy_numbers = filter(is_happy, range(1000))
to create an array with the first 1000 happy numbers.
Also it is a good habit to put add a "main guard" so that the source file can be
imported as a module:
if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)
Performance improvements:
Computing the square digit sum can be made slightly faster by using integer
arithmetic only, without string conversions:
def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum
(This makes the sqdict
hash obsolete.)
The recursion limit of 50 is somewhat arbitrary, and might not be sufficient for
large numbers. A possible alternative is to remember all numbers seen so far
in a set:
def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True
More suggestions:
Add docstring comments to all functions.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Coding style
There is too little white space at many places, for example
sqdict=str(i):i**2 for i in range(10)
This and other PEP8 coding style
violations (most of them related to spacing and too long comment lines)
can be detected by checking your code at PEP8 online.
Unnecessary comments
There are some comments which add no information to the code and can safely be removed,
such as
#lets define our adder
def adder3(num):
or
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
Naming
def adder3(num):
Is is impossible to guess from the function name what its purpose might be.
I'd suggest something like square_digit_sum
.
def happynum (num, counter):
Here we know what the function is about, what does it do? Compute a happy number,
check for happy number, ...?
Code structure:
The global variable counter = 0
is not used at all and can be removed.
A global variable number = i
is used to "remember" the argument of
the inital call to the recursive happynum
function, and the function
(as a "side effect") appends to the global happy_numbers
array.
This is error-prone and not very elegant.
I'd suggest to define a function is_happy
instead, which takes a number and
recursion limit, and returns True or False. The default recursion limit can be
defined as a default parameter value:
def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)
Note also that no else:
block is needed if the if:
block
has a return statement. This saves indenting levels.
Then you can use list comprehension
happy_numbers = [num for num in range(1000) if is_happy(num)]
or a filter
happy_numbers = filter(is_happy, range(1000))
to create an array with the first 1000 happy numbers.
Also it is a good habit to put add a "main guard" so that the source file can be
imported as a module:
if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)
Performance improvements:
Computing the square digit sum can be made slightly faster by using integer
arithmetic only, without string conversions:
def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum
(This makes the sqdict
hash obsolete.)
The recursion limit of 50 is somewhat arbitrary, and might not be sufficient for
large numbers. A possible alternative is to remember all numbers seen so far
in a set:
def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True
More suggestions:
Add docstring comments to all functions.
add a comment |Â
up vote
1
down vote
Coding style
There is too little white space at many places, for example
sqdict=str(i):i**2 for i in range(10)
This and other PEP8 coding style
violations (most of them related to spacing and too long comment lines)
can be detected by checking your code at PEP8 online.
Unnecessary comments
There are some comments which add no information to the code and can safely be removed,
such as
#lets define our adder
def adder3(num):
or
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
Naming
def adder3(num):
Is is impossible to guess from the function name what its purpose might be.
I'd suggest something like square_digit_sum
.
def happynum (num, counter):
Here we know what the function is about, what does it do? Compute a happy number,
check for happy number, ...?
Code structure:
The global variable counter = 0
is not used at all and can be removed.
A global variable number = i
is used to "remember" the argument of
the inital call to the recursive happynum
function, and the function
(as a "side effect") appends to the global happy_numbers
array.
This is error-prone and not very elegant.
I'd suggest to define a function is_happy
instead, which takes a number and
recursion limit, and returns True or False. The default recursion limit can be
defined as a default parameter value:
def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)
Note also that no else:
block is needed if the if:
block
has a return statement. This saves indenting levels.
Then you can use list comprehension
happy_numbers = [num for num in range(1000) if is_happy(num)]
or a filter
happy_numbers = filter(is_happy, range(1000))
to create an array with the first 1000 happy numbers.
Also it is a good habit to put add a "main guard" so that the source file can be
imported as a module:
if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)
Performance improvements:
Computing the square digit sum can be made slightly faster by using integer
arithmetic only, without string conversions:
def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum
(This makes the sqdict
hash obsolete.)
The recursion limit of 50 is somewhat arbitrary, and might not be sufficient for
large numbers. A possible alternative is to remember all numbers seen so far
in a set:
def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True
More suggestions:
Add docstring comments to all functions.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Coding style
There is too little white space at many places, for example
sqdict=str(i):i**2 for i in range(10)
This and other PEP8 coding style
violations (most of them related to spacing and too long comment lines)
can be detected by checking your code at PEP8 online.
Unnecessary comments
There are some comments which add no information to the code and can safely be removed,
such as
#lets define our adder
def adder3(num):
or
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
Naming
def adder3(num):
Is is impossible to guess from the function name what its purpose might be.
I'd suggest something like square_digit_sum
.
def happynum (num, counter):
Here we know what the function is about, what does it do? Compute a happy number,
check for happy number, ...?
Code structure:
The global variable counter = 0
is not used at all and can be removed.
A global variable number = i
is used to "remember" the argument of
the inital call to the recursive happynum
function, and the function
(as a "side effect") appends to the global happy_numbers
array.
This is error-prone and not very elegant.
I'd suggest to define a function is_happy
instead, which takes a number and
recursion limit, and returns True or False. The default recursion limit can be
defined as a default parameter value:
def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)
Note also that no else:
block is needed if the if:
block
has a return statement. This saves indenting levels.
Then you can use list comprehension
happy_numbers = [num for num in range(1000) if is_happy(num)]
or a filter
happy_numbers = filter(is_happy, range(1000))
to create an array with the first 1000 happy numbers.
Also it is a good habit to put add a "main guard" so that the source file can be
imported as a module:
if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)
Performance improvements:
Computing the square digit sum can be made slightly faster by using integer
arithmetic only, without string conversions:
def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum
(This makes the sqdict
hash obsolete.)
The recursion limit of 50 is somewhat arbitrary, and might not be sufficient for
large numbers. A possible alternative is to remember all numbers seen so far
in a set:
def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True
More suggestions:
Add docstring comments to all functions.
Coding style
There is too little white space at many places, for example
sqdict=str(i):i**2 for i in range(10)
This and other PEP8 coding style
violations (most of them related to spacing and too long comment lines)
can be detected by checking your code at PEP8 online.
Unnecessary comments
There are some comments which add no information to the code and can safely be removed,
such as
#lets define our adder
def adder3(num):
or
i_sum = adder3(num) # storing the value from the adder fucntion to i_sum
Naming
def adder3(num):
Is is impossible to guess from the function name what its purpose might be.
I'd suggest something like square_digit_sum
.
def happynum (num, counter):
Here we know what the function is about, what does it do? Compute a happy number,
check for happy number, ...?
Code structure:
The global variable counter = 0
is not used at all and can be removed.
A global variable number = i
is used to "remember" the argument of
the inital call to the recursive happynum
function, and the function
(as a "side effect") appends to the global happy_numbers
array.
This is error-prone and not very elegant.
I'd suggest to define a function is_happy
instead, which takes a number and
recursion limit, and returns True or False. The default recursion limit can be
defined as a default parameter value:
def is_happy(num, reclimit=50):
if num == 1:
return True
if reclimit <= 0:
return False
return is_happy(square_digit_sum(num), reclimit - 1)
Note also that no else:
block is needed if the if:
block
has a return statement. This saves indenting levels.
Then you can use list comprehension
happy_numbers = [num for num in range(1000) if is_happy(num)]
or a filter
happy_numbers = filter(is_happy, range(1000))
to create an array with the first 1000 happy numbers.
Also it is a good habit to put add a "main guard" so that the source file can be
imported as a module:
if __name__ == "__main__":
happy_numbers = filter(is_happy, range(1000))
print(happy_numbers)
Performance improvements:
Computing the square digit sum can be made slightly faster by using integer
arithmetic only, without string conversions:
def square_digit_sum(num):
sum = 0
while num > 0:
digit = num % 10
sum += digit * digit
num //= 10
return sum
(This makes the sqdict
hash obsolete.)
The recursion limit of 50 is somewhat arbitrary, and might not be sufficient for
large numbers. A possible alternative is to remember all numbers seen so far
in a set:
def is_happy(num):
seen = set()
while num > 1:
if num in seen:
return False
seen.add(num)
num = square_digit_sum(num)
return True
More suggestions:
Add docstring comments to all functions.
edited Jan 28 at 14:31
answered Jan 28 at 14:26
Martin R
14.1k12257
14.1k12257
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186119%2ffirst-n-happy-numbers%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password