How to refactor

Working problems for experience, my answer is on top. They both work. The second one was in the book example and I think this is a good test bed for explaining refactoring. The script takes a word and prints it backward one line at a time.

word = input('Enter a word: ')
for letters in word[::-1]: # print letters in reverse

word = input('Enter a word: ')
length = len(word)
num = 1
for x in word:
    position = length - num
    letter = word[position]
    num = num + 1

Thanks for the explaination. Great forum.

1 Like

Thank you, @woodturner550 . Are you asking a question, or showcasing the results of your refactoring?

No I’m new to Python. Been reading and trying to put in practice what I have learned so far. I knew the the second script was a ‘smell code’. I to know how one writes a poor code, OK how did you get from the poor code to the upper code. I believe it can be done using the ‘write each step out and look at the steps’ just like for any program. It was not followed in the second example. They had to many steps and objects. They needed to reduce the steps and object to what is necessary. This is what I think, don’t know for sure yet.
Thanks for your time and explaining that my final code would be a refactoring of the poor code. Tells me there is hope for me yet.

You refactor is quite good, Leonard. If you’re interested in refactoring further, you can do away with the loop entirely by using str.join to insert a newline character (\n) between each letter:

word = input("Enter a word: ")
reverse = word[::-1]
as_lines = "\n".join(reverse)

or as a single line:

print("\n".join(input("Enter a word: ")[::-1]))

If the objective is to print the letters in reversed order then we can skip the building of new string with join:

>>> word = "spam"
>>> print(*word[::-1], sep="\n")

Of course, Python has built-in function reversed, so why not to use it? This way it’s much more clear what is going on:

>>> print(*reversed(word), sep="\n")

If the objective is to reverse word and keep it on one line then:

>>> print(''.join(word[::-1]))
1 Like

Indeed, that is better. I admit, I tend to forget about the sep argument to print.

1 Like

Thanks for clarifing how to do the refactoring further. Since I’m so new to Python some of the further refactoring does not seem to be as clear reading it. At my experience level, my code seem easier to understand.
‘refactoring does not necessarily mean your code needs to be shorter after refactoring – but just somehow simpler and more understandable.’
Interesting topic. If one does the planing and writing out the problem to reduce it to it’s base functions and objects, maybe it will be refactored to start with. That seems to be the goal. At least there should be less need for refactoring if written right in the first place. Great goals, now to put them into practice.
Thanks again.

As a quick question. Does the refactored code always run faster after refactoring? Speed increased and using resourses are reduced as I see it.

As a general answer, the only way to be sure that code runs faster after refactoring is to time it. Run the old code on some standard data, measuring the execution time. Be sure to eliminate extraneous factors (like the time to write output to a file). Run the new code on the same data, measuring the execution time. Compare.

For a small problem like reversing this 4-character word, you might need to measure the time taken for several thousand or million repetitions of the code, in order to make the time difference large enough to accurately measure.

How to do good timing trials is its own area of software engineering skill.

I’ve added it to my to read list. I try to read a few hours on new programming subjects everyday.
I have two further questions. I understand the timing idea, but what about the resources being used? Or at this level don’t worry about it. Is there a module for that also?
Thanks, I like concepts, I’m getting a better picture all the time.

One of the difficulties of doing timing analysis well is that you have to understand what exactly you are measuring. For instance, in your example, if you include the print statement, you are including the print mechanism in your test. So maybe you get more meaningful results if you leave out the print statement. But maybe the interpreter has some optimisation which gets rid of the operation you want to measure if you don’t do something with the result — which means leaving out the print statement might make the test invalid.

Sorry, no, you just have to rely on your judgement and insight.