First n Happy Numbers

The name of the pictureThe name of the pictureThe name of the pictureClash 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.







share|improve this question



























    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.







    share|improve this question























      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.







      share|improve this question













      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.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jan 27 at 12:41
























      asked Jan 27 at 11:11









      user9267433

      163




      163




















          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.






          share|improve this answer























            Your Answer




            StackExchange.ifUsing("editor", function ()
            return StackExchange.using("mathjaxEditing", function ()
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            );
            );
            , "mathjax-editing");

            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "196"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: false,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );








             

            draft saved


            draft discarded


















            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






























            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.






            share|improve this answer



























              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.






              share|improve this answer

























                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.






                share|improve this answer















                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.







                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited Jan 28 at 14:31


























                answered Jan 28 at 14:26









                Martin R

                14.1k12257




                14.1k12257






















                     

                    draft saved


                    draft discarded


























                     


                    draft saved


                    draft discarded














                    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













































































                    Popular posts from this blog

                    Chat program with C++ and SFML

                    Function to Return a JSON Like Objects Using VBA Collections and Arrays

                    Will my employers contract hold up in court?