4

I'm learning Python (using 3.6.2) and on my last class, they asked me to do something where I need to make an infinite for loop. For some reason, the teacher doesn't want us to use while for the entire practice. This is where it gets complicated...

So, I've been looking for a way to do it. But, it's also difficult because the teacher doesn't want us to use any commands we haven't seen in class. So I can't use .append, sys functions, well, I can't even use a break. I must find a way to do with "simple" commands.

I thought I could do it this way;

x=1
    for i in range(x):
    do_something()
    x += 1

However, it didn't seemed to work. I think that's because Python doesn't read the value for the range again?

I couldn't find a way, but after hours of thinking I found myself a small workaround I could use:

def ex():
    print("Welcome")
    for i in range(1):
        math = int(input("Please insert grades obtained at Math, or insert 666 to exit" ))
        if(math > 0 and math < 60):
            print("Sorry. You failed the test")
            return ex():
        elif(math >= 60 and math <= 100):
            print("Congratulations. You passed the test")
            return ex():
        elif(math == 666):
            return exit()
        else:
            print("ERROR: Please insert a valid number")
            return ex():

def exit():
     pass

As you can see, what makes it "infinite" is that it returns to the function once and once again, until you tell the program to "exit", by entering "666". I'd also like to have a more proper way to exit the function.

I'm still wondering if there's a better way to make my for loop infinite until the user calls it to stop. However, one way or another I got this exercise working. The problem came when I started with the second one, which is more or less like this:

Imagine the same past program, but this time, it will not just show you if you passed the test or not. It wants to collect as many grades you enter through the input, and then calculate the average of all the grades. I'm not able to save those values (the grades) because I kind of "restart" my own function every time.

And according to my teacher's instructions, I can't ask the user how many grades he wants me to calculate. It must be infinite and keep asking for inputs until the user choses not to.

I'm really stuck and lost on it. It's very hard and frustrating because it'd be way easier if we could just use while's :( And also harder because we can't use any options we haven't seen...

So, I have 3 questions:

  • How do I make an appropiate "infinite" for loop?
  • How do I make a proper way to "finish" it?
  • How do I make it able to save values?

A lot of thanks in advance for anyone willing to help, and sorry for my ignorance.
I'm new to the community, so any advice about my problems, the question formatting or anything is well received :)

EDIT: I talked to my teacher and he allowed me to use either itertools or just a range big enough to not be reached. Now i'm wondering, how can I save those values inside the for for later manipulation?

oScarDiAnno
  • 184
  • 1
  • 1
  • 10
  • 4
    This is pretty difficult to answer as we have no idea what you have seen in class - but would importing and using `itertools.count` (https://docs.python.org/2/library/itertools.html#itertools.count) solve this problem? – Shadow Oct 16 '17 at 04:21
  • 7
    You have nothing to apologize for. This is a stupid task and being assigned it is not your fault. – Ignacio Vazquez-Abrams Oct 16 '17 at 04:24
  • I expected this to happen :/ And yes, unafortunately I can't use that. I found that here on the forums but i'm not able to use the `itertools`. Thank you for trying to help, though. It's very difficult to me too because I know it's hard to find a solution this way, but I don't know what else I could do :/ – oScarDiAnno Oct 16 '17 at 04:25
  • Thanks @downshift , I did see that thread before posting my question but unafortunately I'm not able to use any of those solutions. As you can see, the first codeblock I put on my question comes from one of the bottom answers of that thread, but it doesn't works :/ – oScarDiAnno Oct 16 '17 at 04:28
  • @oScarDiAnno I suppose we can't use a recursive function either...? – George Bou Oct 16 '17 at 04:28
  • @GregHewgill I'm curious about how you would go about implementing one of those without a while loop... – Shadow Oct 16 '17 at 04:29
  • 6
    ***the teacher doesn't want us to use any commands we haven't seen in class*** - This is ridiculous. Is there any way you can fire your idiotic teacher? – Michael Geary Oct 16 '17 at 04:34
  • 2
    Possible duplicate of [Infinite for loops possible in Python?](https://stackoverflow.com/questions/34253996/infinite-for-loops-possible-in-python). Apparently there’s a dupe for everything... – Taku Oct 16 '17 at 05:17
  • Probably way more advanced that where your class is, but this might work: https://stackoverflow.com/a/18506625 – Doug Coburn Oct 16 '17 at 05:56
  • Hey guys! I got permission to use either `itertools` or a range big enough, but I don't know how to store the values yet with this. Sorry for the bother, if you could help, I would appreciate any advice, either here or on the new [question](https://stackoverflow.com/questions/46782017/how-to-save-values-from-a-for-loop-python-3) – oScarDiAnno Oct 17 '17 at 03:32
  • Anyway this question for me doesn't fit to the rules of AskUbuntu: this page is not for solving homeworks, you are asking multiple questions, since the question follows some very special restrictions it is not very useful to other users.. – derHugo Oct 18 '17 at 13:37
  • Sorry about that, I don't want you or anyone else think I didn't do any research or anything, because I really did, but still needed help. It was difficult to find solutions that could match with the restrictions I had. However, if you think it's more proper, if I ever need help again I'll look for info and other questions (as I did this time) but also maybe post simpler questions, or making multiple question but at different posts would be more appropiate maybe? I appreciate any advice on this as well – oScarDiAnno Oct 18 '17 at 14:14

4 Answers4

5

Can you try something like this:

for i in iter(int, 1):
    print("Infinite for loop executing")

Refer to this question regarding infinte iterator without while for more info.

akhilsp
  • 1,063
  • 2
  • 13
  • 26
  • "For some reason, the teacher doesn't want us to use while for the entire practice." - This answer is invalid. – Shadow Oct 16 '17 at 04:29
  • 1
    Unafortunately i'm not able to use `while` for anything :(. Thanks for trying to help, though – oScarDiAnno Oct 16 '17 at 04:31
  • @oScarDiAnno can you use the `iter()` function? – akhilsp Oct 16 '17 at 04:50
  • 2
    @akhilsp Thanks bud. We haven't seen that function in class but seeing that there aren't any options I could use, I think I will use either this or the `itertools` solutions and tell my teacher I tried but I couldn't find another way. – oScarDiAnno Oct 16 '17 at 05:07
5

I hate "trick" questions like this that have very little to do with how you'd use Python in the real world. But anyway...

The trick here is to iterate over a list that you modify inside the for loop. This is generally regarded as a bad practice, but we can exploit it here for this contrived assignment.

We ask for user input inside a function so we can escape from the loop by using return, since you aren't permitted to use break.

def get_data(prompt):
    lst = [None]
    for i in lst:
        s = input(prompt)
        if not s:
            return lst[1:]
        lst += [int(s)]
        print(lst)

print('Enter data, one number at a time. Enter an empty line at the end of the data')
lst = get_data('Number: ')
print('Data:', lst)

demo

Enter data, one number at a time. Enter an empty line at the end of the data
Number: 3
[None, 3]
Number: 1
[None, 3, 1]
Number: 4
[None, 3, 1, 4]
Number: 1
[None, 3, 1, 4, 1]
Number: 5
[None, 3, 1, 4, 1, 5]
Number: 9
[None, 3, 1, 4, 1, 5, 9]
Number: 
Data: [3, 1, 4, 1, 5, 9]
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • Thanks a lot man, it's a smart and interesting solution, I agree with you that it's a "contrived" assignment. From your code, the only thing I see is that we haven't seen the `append`. However, I'll collect those solutions and show my teacher what I found so he can see that we actually tried but we just found no way to do that without using *whiles* or *anything we haven't seen*. So this is quite helpful, plus, it's always good to learn new stuff :). Thanks again! – oScarDiAnno Oct 16 '17 at 05:16
  • Awesome! I'll try to make my code work with this and present it to my teacher, hope it fulfills his expectations lol. Thank you :) – oScarDiAnno Oct 16 '17 at 05:51
  • Thank you man, I accepted your answer and tried the program. However, now I got permission to use `itertools` or a big range instead. I'd be interested in using either this solution or one of the others, whichever is more appropiate, but I still need a little help to understand how I can store values from the inputs at the foor loop. If you have any advice, I would appreciate it, I made a new [question](https://stackoverflow.com/questions/46782017/how-to-save-values-from-a-for-loop-python-3) if you prefer to reply there, in case you have any advice. Thanks again man! :) – oScarDiAnno Oct 17 '17 at 03:36
  • @oScarDiAnno If there's stuff in my code that you don't understand you should ask about it here. – PM 2Ring Oct 17 '17 at 04:52
  • Thank you man. I ran the code one more time and while running and reading the code I think I understood it better. I'm going to explain the code to see if I got it, please correct me if i'm wrong. We use [None], inside the range, which is a list, because if it was empty it wouldn't start the loop. But, • Q: What does the (prompt) inside the funcion and the "s" input and why is it needed? Then, We insert the number through the "s" input, then list = list + integer of s, the number we just entered into that variable... – oScarDiAnno Oct 17 '17 at 05:07
  • PD: The "if not s:" was quite interesting! I was wondering how I could stop the proccess if an "empty" input was entered! I guess this is the answer, very nice. – oScarDiAnno Oct 17 '17 at 05:08
  • Now, it prints the user's instruction and then the line: list = get_data("Number: ")... It works as the input parameter?? Then, print("Data:", lst) prints the current list of numbers, which I can skip if I don't want them to show in the screen, right? – oScarDiAnno Oct 17 '17 at 05:13
  • @oScarDiAnno The `prompt` string is the string that the `input` function prints to prompt the user to type in some input. I wrote `get_data` to take that `prompt` arg so it can be used to ask for different things. I didn't really _need_ to do that, since we're only asking the user for one kind of input in this program, but it's good design to make code flexible when it's easy to add that flexibility. – PM 2Ring Oct 17 '17 at 05:15
  • @oScarDiAnno Yes, `not s` is True when `s` is the empty string. It's pretty standard in Python (and various other languages) that zero or an empty container (string, tuple, list, set, dict, etc) evaluate to False when you put them into a test. – PM 2Ring Oct 17 '17 at 05:16
  • One last question for now, I believe I can't leave those prints outside the function, because my assignment contains a few excercises and I must call each one with their respective function, for example, e1(), e2(), etc... Is there a way I could make this inside the function, or maybe into another one to call it from there, so it doesn't get printed when I run the whole program?. I hope it's understandable enough, sorry, I can't do much formatting here. Thanks again – oScarDiAnno Oct 17 '17 at 05:17
  • @oScarDiAnno Yes, you can delete or comment out the `print` lines if you don't want to see what they print. And if you want, any of your `e1()`, `e2()`, etc... functions could call `get_data`, passing it whatever `prompt` string is appropriate for that exercise. – PM 2Ring Oct 17 '17 at 05:17
  • I had doubt on what was the [1:] doing, did a little research and seems like it makes it return everything BUT the first value on the list, right? That's it man, this is all I should need to complete this contrived assignment. Would you like to answer on my latest question, or how could I give you credit for this? Many thanks again, I really owe you a big one! – oScarDiAnno Oct 17 '17 at 05:32
  • @oScarDiAnno: That's correct, `lst[1:]` constructs a new list from `lst`, starting from the item at index 1. The answers on your new question look ok to me, I don't think I need to write another one. If you want to upvote this answer, please feel free (unless of course you've already upvoted it). ;) – PM 2Ring Oct 17 '17 at 05:43
  • Perfect, thanks again! :) And I did upvote your answer before, but I didn't have enough rep to make it visible by then, now I do :P – oScarDiAnno Oct 17 '17 at 05:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156939/discussion-between-oscardianno-and-pm-2ring). – oScarDiAnno Oct 17 '17 at 17:44
1

If you are not allowed to use itertools and you are limited to basic language constructs, and not allowed to use while then I have some sad news for you;

This might not be possible. At least not with a python for loop.

I suggest you get in contact with whoever is leading your class and get them to clarify the requirements. There is no real-world application for this knowledge, so I would be very interested to know what the goal of this assignment is.

Note; This is possible in other languages that support actual for loops (ie, rather than foreach loops) so maybe the assigner of this task ported this question from a different language class?


EDIT; Now that you're allowed to use itertools, I would suggest using the answer I gave in the comments originally;

from itertools import count
for i in count():
    pass  # this will loop for longer than you will live.

With this, plus a list created before the loop, you should have no difficulty keeping track of grades and calculating their average.

Shadow
  • 8,749
  • 4
  • 47
  • 57
  • I see... Well, it's quite sad that I spent many hours breaking my head trying to find a way to do it... But I think you're right. I'm not sure what is he expecting from us, but i'll keep you guys updated about anything we get to. Many thanks for the help. Should I close the question? – oScarDiAnno Oct 16 '17 at 04:34
  • 1
    Nah - leave it open. If there is indeed no solution that suits give me a tick - but if you find one or the teacher lets you know feel free to post it as your own answer. The question might get cleaned up later, but I'm curious as to this teachers intent if nothing else. – Shadow Oct 16 '17 at 04:49
  • 1
    It's certainly _possible_ to do this with a regular `for` loop, but I wouldn't recommend it. – PM 2Ring Oct 16 '17 at 05:27
  • Nor, I suspect, would I teach it :P It's the only thing I thought this teacher might have meant though. – Shadow Oct 16 '17 at 05:35
  • Thank you both for your help, guys. Today I didn't have class with that teacher, but I went to search him so we could talk. Seems like he understood and he told me I could use either itertools or just a range big enough (he told us not to - the day he gave us the assignment, though). So now, if it isn't much to ask, could you guide me a little on how I could use any of those options for a problem like the one in the yellow block on my question? Mostly, I don't know how to save those values in order to calculate the average later. – oScarDiAnno Oct 17 '17 at 02:02
  • @oScar. While it sucks that you had to waste your time like this, I bet this is the most Python you learned per unit time. – Mad Physicist Oct 17 '17 at 02:31
  • @MadPhysicist Can't deny it haha. It was an interesting research, a little frustrating at the same time, though. But definitely, I learned a good amount of new things :) – oScarDiAnno Oct 17 '17 at 02:47
0

Python 3.x infinite loop bassed on class:

class loop_iter(object):
    def __iter__(self):
        return self
    def __next__(self):
        # for python2.x rename this method to `next`

        # Return the next item from the container.
        # If there are no further items, raise the StopIteration exception.
        # Because this is infinite loop - StopIteration is not raised
        return None

class infinite_loop(object):
    def __iter__(self):
        # This method is called when an iterator is required for a container. 
        # This method should return a new iterator object that can iterate over all the objects in the container.
        # For mappings, it should iterate over the keys of the container, and should also be made available as the method keys().

        # Iterator objects also need to implement this method;
        # they are required to return themselves.
        # For more information on iterator objects, see Iterator Types.
        return loop_iter()

x = []
# thx PM 2Ring for text
print('Enter data, one number at a time. Enter an empty line at the end of the data')  

for _ in infinite_loop():
    line = input('Number: ')

    if line:
       x += [int(line)]
       continue

    print('Average:', sum(x)/len(x))  # average
    exit()
Yaroslav Surzhikov
  • 1,568
  • 1
  • 11
  • 16