9
\$\begingroup\$

For example if I start with the number 146. I first reverse it, so it becomes 641. Then I add this to the original number to make 787 which is a palindrome. I would repeat the process if the answer is not a palindrome.

I made this program show how long it ran for when it finishes or is interrupted and also to write the output to a file called output.txt.

from sys import exit
from signal import SIGINT, signal
from timeit import default_timer


def n(x):

    counter = 0
    b = 0
    start = default_timer()

    def t(*args):

        end = default_timer()
        total = end - start
        print (total)

        with open('output.txt','w') as f:

            f.write('{}\n{}\n{}'.format(b, counter, total))

        exit(0)

    signal(SIGINT,t)


    while True:

        b += int(str(x)[::-1])

        if b == int(str(b)[::-1]):

            end = default_timer()
            print (b, counter)
            t()
            break

        else:

            counter += 1
            print (b,counter)
            x = b
\$\endgroup\$
2
  • 5
    \$\begingroup\$ First improvement I'd suggest is to use decent names for variables and methods, add comments, and skip fewer lines. \$\endgroup\$
    – BusyAnt
    Commented Jul 28, 2016 at 13:53
  • 2
    \$\begingroup\$ @BusyAnt I just realised that I pasted the wrong version of my code. The only thing different is that the newer one has more sensible variable names but still doesn't have comments/less blank lines. Thanks for pointing that out! \$\endgroup\$
    – Farhan.K
    Commented Jul 28, 2016 at 13:58

1 Answer 1

6
\$\begingroup\$

A few notes:

  • A more pythonic way to determine if a given value is a palindrome:

    str(n) == str(n)[::-1]
    

    You do something similar in your code, but are converting from a string back to an int. This is more readable to me.

    However, this can slow down the code if we do this sort of casting a lot, so it would be better to abstract this functionality to a loop to reduce the number of casts and further increase readablity:

    def is_palindrome(num):
        string = str(num)
        return string == string[::-1]
    
  • Use the palindrome test as a check with the while loop

  • In the while loop, use the logic you already have to add on a reversed int:

    n += int(str(n)[::-1])
    
  • I would make it easier to input a number for the code to use, I did this with argparse.

    def get_args():
        parser = argparse.ArgumentParser(description=
            'Generate palindrome from number when added to its reverse')
        parser.add_argument('num', type=int, help='number for palindrome generator')
        return parser.parse_args()
    
  • Right now you are writing just a snippet of data to a file, but it is being overwritten every time. I'd recommend just outputting to stdout with this current method, or changing it so you append to a file instead of overwrite it. I've gone with the former recommendation in my final code.

  • For profiling and timing code, it's recommended you use a Python profiler instead of writing code yourself.


Final Code

import argparse


def get_args():
    parser = argparse.ArgumentParser(description=
        'Generate palindrome from number when added to its reverse')
    parser.add_argument('num', type=int, help='number for palindrome generator')
    return parser.parse_args()


def is_palindrome(num):
    string = str(num)
    return string == string[::-1]


def main():
    args = get_args()
    while not is_palindrome(args.num):
        args.num += int(str(args.num)[::-1])

    return args.num


if __name__ == "__main__":
    print(main())

Test run:

$ python test.py 146
787
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.