2

This is from finger exercise 3.1 in Introduction to Computation and Programming Using Python.

Write a program that asks the user to input an integer and prints two integers, root and pwr, such that 0 < pwr < 6 and root**pwr is equal to the integer entered by the entered. If no such pair of integers exists, it should print a message to that effect.

I got damn close, thanks in part to some suggestions in Stack Overflow. But nobody got quite all the way there, partially because the point of the exercise is to use nested While loops, and not For loops or anything else more complex than that. It's an exercise is exhaustive enumeration.

I'm really really close. Here's what I have so far:

num = int(raw_input('Enter a positive integer: '))
power = 0
root = 0
while power < 6:
    if root ** power == num:
        break
    power += 1
    root= 0
    while root ** power < num:    
        root += 1

if root**power == num:
    print('Root = ' + str(root) + ' and power = ' + str(power))
else:
    print('No pair of integers exist such that one has an exponent that is between 1 and 6')

There's just two problems here: I have to run a check to see if root and power equal user input and that feels unnecessary. Was wondering how to make that cleaner.

Also when user inputs 1 for input, the program outputs Root 0 and Power 0 which is outside of the parameters of the exercise.

1
  • 0 < pwr < 6 means power should never equal 0. Commented Oct 27, 2013 at 22:06

6 Answers 6

1

Was wondering how to make that cleaner.

Easy. You can collapse it onto one line, turning

while power < 6:
    if root ** power == num:
        break

into

while (power < 6) and (root ** power != num):

(the parens are unnecessary, but I find it helps readability.)

Sign up to request clarification or add additional context in comments.

2 Comments

why did you change the logic with (root ** power != num)
There's no logic change; the two are equivalent."Break when (root ** power == num) at the beginning of the loop" is the same as "continue only if (root ** power != num)".
1

You need to invert your loops. You need to increase the root in the outer loop, then iterate through the powers in the inner loop. Otherwise, you'll always match on "power == 1" because root will be increased to the target number and that's it.

The way you have it, if you have num = 42, power will be set to 1, then root will just be iterated up to 42. If you have the power increased in the inner loop, then you'll have:

root == 1, power == 1, root**power == 1
root == 1, power == 2, root**power == 1
root == 1, power == 3, root**power == 1
root == 1, power == 4, root**power == 1
root == 1, power == 5, root**power == 1
root == 2, power == 1, root**power == 2
root == 2, power == 2, root**power == 4
root == 2, power == 3, root**power == 16
root == 2, power == 4, root**power == 64
root == 3, power == 1, root**power == 3
root == 3, power == 2, root**power == 9
... and so forth ...

Is this not the behavior you're looking for?

Comments

1

Here's my solution if anyone is still interested. (With added prints for each iteration)

x = int(raw_input('Enter an  integer: '))


pwr = 1
root = 0
while root**pwr < abs(x)+1:  
    #print  "Root ->" , root 
    #print "x - >", x
    #print "Current root**pwr", root**pwr
    while pwr < 6:
        if root**pwr == abs(x):
              print "Root and Power: " , root, pwr
        #print  " pwr, root**pwr->", pwr, root**pwr
        pwr = pwr + 1


    pwr = 1
    root = root+1

Comments

0

Currently you have set:

power = 0
root = 0

If the user inputs 1 then 0**0 = 1 so you break out of your while loop and the first print condition passes. There are several ways to catch this, one way is to add an extra condition to your if that checks if the value of num is 1 before printing.

if (root**power == num) and (not num == 1):
    print('Root = ' + str(root) + ' and power = ' + str(power))

Another way to solve this would be to update the initial value of power to be 1. In the problem specification 0<power<6 so the lower limit for power is 1 and the upper is 5.

power = 1
root = 0

To make the code cleaner you can incorporate the if statement in your while loop to be a check condition on the while loop. The main reason you can do this is because you break from this if statement anyway.

while (power < 6)and not (root**power == num):
    power+=1
    while root ** power < num:
        root+=1

1 Comment

And indeed starting power at 1 is the nicest solution.
0
x = int(raw_input('Enter an integer:'))
num = 2
for pwr in range(2,7):
  while num ** pwr < x:
        num += 1
        if num ** pwr == x:
          False

  if num ** pwr == x:
      break
  num = 2
if num ** pwr != x:
    print 'no root'
else:
    print num,pwr

Comments

0

As sdanzig said, you should increment the root in the outer loop, and the power in the inner loop. But there's more that needs to be done. Here's the working code:

integer = int(input('Type an integer: '))
power = 2
root = 1

while root ** power < integer:
    root = root + 1
    while root ** power < integer and power < 5:
        power = power + 1
    if root ** power != integer:
        power = 2

if root ** power == integer:
    print(str(root) + ' ** ' + str(power) + ' = ' + str(root ** power))
else:
    print('Unable to locate a combination of root and power that results in the chosen integer')

What is happening here?

First, both loops work under the condition root ** power < integer. That's essential.

The outer loop is performing 3 different tasks:

  1. Incrementing root
  2. Starting the inner loop.
  3. Conditionally resetting the power

The inner loop does one thing only:

  1. Increments power

    As long as power does not exceed 5

Simulation

Let's consider integer = 27.

2 ** 2 = 4
2 ** 3 = 8
2 ** 4 = 16
2 ** 5 = 32

32 causes the inner loop to break, but this is not the number we're looking for, so reset power before the outer loop restarts.

if root ** power != integer:
    power = 2
3 ** 2 = 9
3 ** 3 = 27

That's it. Bingo.

A caveat

As you can see, we're assigning 2 as the lowest possible power. This prevents strange results such as 27 ** 1 = 27. Unfortunately, this violates the requirements described in the book. If you know an alternative solution to this, please let us know.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.