0

I have this python problem:

Write a program that asks the user for a limit, and then prints out the sequence of square numbers that are less than or equal to the limit provided.

Max: 10

1

4

9 ​

Here the last number is 9 because the next square number (16) would be greater than the limit (10).

Here is another example where the maximum is a square number:

Max: 100 1

4

9

16

25

36

49

64

81

100

But I don't exactly know how to do this. So far I have

maximum = int(input("Max: "))

for i in range(1, maximum):

But don't really know how to process the numbers and squaring them.

Thanks

Edit: I have

maximum = int(input("Max: "))

for i in range(1, maximum):
  if i*i <= maximum:
    print(i*i)
  • 5
    Hint: `i*i` is the square of `i` – John Coleman Aug 25 '18 at 01:10
  • 2
    You don't need a nested loop, just the `for` loop. What you want inside is an `if` statement. `if i*i > maximum…` then what? What do you when `maximum` is `10`, but `i*i` is 16? You `break` out of the loop, because you're done. – abarnert Aug 25 '18 at 01:17
  • Thanks. But how do I make it so when I enter '1' as the max, it prints 1? Because currently when I type 1 nothing shows –  Aug 25 '18 at 01:26
  • got it nevermind thank you. I had to use `for i in range(1, maximum + 1):` –  Aug 25 '18 at 01:35
  • @HollyM Please consider to [accept at least one answer](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) if your problem is solved. :) – KaiserKatze Aug 30 '18 at 11:52

6 Answers6

4
'''
Ask the user input a limit and
convert input string into integer value
'''
limit = int(input("Please input the limit: "))

'''
Extract the squre root of `limit`.
In this way we discard every number (i) in range [0, limit]
whose square number ( i * i ) is not in range [0, limit].
This step improves the efficiency of your program.
'''
limit = int(limit ** .5)

'''
`range(a, b)` defines a range of [a, b)
In order to exclude zero,
we assign `a = 1`;
in order to include `limit`,
we assign `b = limit + 1`;

thus we use `range(1, limit + 1)`.
'''
for i in range(1, limit + 1):
    print(i * i)
KaiserKatze
  • 1,521
  • 2
  • 20
  • 30
  • 1
    This answer is good, but in general it is clearer to have the explanations in the comments as text. – Olivier Melançon Aug 25 '18 at 01:44
  • I can't help but wonder: Will it (having explanations in texts) bring about performance burden in larger projects? – KaiserKatze Aug 25 '18 at 01:48
  • Comments bringing performance burden is not common. I'm suggesting this for readability, not for performance – Olivier Melançon Aug 25 '18 at 01:50
  • 1
    @OlivierMelançon, your comment got e thinking, I searched and got https://stackoverflow.com/questions/10486666/will-excessive-commenting-of-code-slow-execution. Do you have some source where it provides some timing stats in highly commented v/s non commented code. – Deepak Saini Aug 25 '18 at 02:00
  • 1
    @DeepakSaini Once the code is compiled, the comments don't exist. For a module, it's pretty easy to test the difference in compile time; for a top-level script it's a bit more annoying. But in real life, it's almost never going to make a difference—if you're compiling the same code a million times, you've done something very wrong; normally you compile once per edit during development, then once per install, and that's it. – abarnert Aug 25 '18 at 02:13
3

I think a while loop may be better suited for this problem.

maximum = int(input("Max: "))

i = 1
while(i*i <= maximum):
   print(i*i) 
   i+=1
Deepak Saini
  • 2,810
  • 1
  • 19
  • 26
2

You got a few good, detailed answers.

But let's also have some fun, here is a one-line solution:

print(*(x**2 for x in range(1, 1 + int(int(input('Limit: '))**(1/2)))))
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
  • 2
    Nice, you even crammed the `input` in there. Well, maybe not _nice_, but… you know what I mean. – abarnert Aug 25 '18 at 02:10
  • @abarnert If you appreciate how the input in *crammed in*, have a look at that one: `print(*takewhile(lambda x, i=int(input('Limit: ')): x <= i, map(lambda x: x*x, count())))` I know you like `itertools`. – Olivier Melançon Aug 25 '18 at 02:15
  • 1
    Yeah, after reading your answer, I thought about cramming the input into my itertools answer exactly that way, except with `lambda x, *, _i=…` to make it clear that I was using the "default value as local" idiom instead of just golfing. But then I realized that really, I was just golfing anyway. – abarnert Aug 25 '18 at 02:17
2

First, the simplest change to your existing code is to get rid of that nested loop. Just have the for loop and an if:

for i in range(1, maximum+1):
    if i*i > maximum:
        break
    print(i*i)

Or just have the while loop and increment manually:

i = 1
while i*i <= maximum:
    print(i*i)
    i += 1

One thing: Notice I used range(1, maximum+1)? Ranges are half-open: range(1, maximum) gives us all the numbers up to but not including maximum, and we need to include maximum itself to have all the numbers up to maximum squared, in case it's 1. (That's the same reason to use <= instead of < in the while version.


But let’s have a bit more fun. If you had all of the natural numbers:

numbers = itertools.count(1)

… you could turn that into all of the squares:

squares = (i*i for i in numbers)

Don’t worry about the fact that there are an infinite number of them; we’re computing them lazily, and we’re going to stop once we pass maximum:

smallsquares = itertools.takewhile(lambda n: n<=maximum, squares)

… and now we have a nice finite sequence that we can just print out:

print(*smallsquares)

Or, if you’d prefer if all on one line (in which case you probably also prefer a from itertools import count, takewhile):

print(*takewhile(lambda n: n<=maximum, (i*i for i in count(1)))

But really, that lambda expression is kind of ugly; maybe (with from functools import partial and from operator import ge) it’s more readable like this:

print(*takewhile(partial(ge, maximum), (i*i for i in count(1)))
abarnert
  • 354,177
  • 51
  • 601
  • 671
1

I have decided to post the answer that works. Thanks all for the help.

maximum = int(input("Max: "))

for i in range(1, maximum + 1):
  if i*i <= maximum:
    print(i*i)
  • 2
    this indeed works, but is highly inefficient. For example say you have maximum=10000, you loop over 10k numbers, but you should ideally do over 100. – Deepak Saini Aug 25 '18 at 02:12
  • It just works for the task I was doing, and the task didn't say anything about bigger numbers but thanks. –  Aug 25 '18 at 02:14
  • 1
    Just adding `else:` `break` will solve that performance problem, without making it significantly harder to understand. – abarnert Aug 25 '18 at 02:19
  • Or just `range(1, int(math.sqrt(maximum))+1)` - seems equally understandable. – AChampion Aug 25 '18 at 17:59
0

THE BELOW PROGRAM IS TO FIND SQUARE VALUE OF GIVE NUMBERS

  1. Enter the value you want to find.(Give a range)
  2. the value you give runs and goes to r command.
  3. i have used for loop in this case.
  4. output will be displayed

give the input

maximum = input("Enter Max: ")

r = range(1, maximum)

Square = maximum * maximum

Execute THE loop

for i in r:

if i * i <= Square:

  print (i * i),
Community
  • 1
  • 1