-2

Here is the code - pretty simple - but it gives me the first exception in the main part of the program infinitely - without even asking for user input where I assumed it should at- at the first input of raw_input - I'm a beginner with a good grasp of the language in general - any ideas? Thanks

import re,sys

#program to take details of people name, address and telephone number from user
#user must specify number of people first

class details:
    def __init__(self,name=None,address=None,tel=None):
        self.name=name
        self.address=address
        self.tel=tel

    def changeAttribute(self,name=None,address=None,tel=None):
        if name!=None:
            self.name=name
        if address!=None:
            self.address=address
        if tel!=None:
            self.tel=tel



class main(): 

    peopleList =[]
    a=1

    while a==1:    
        try:

            numOfPeople = raw_input("enter number of people:")
            if re.search('[^0-9\n]', numOfPeople):
                raise Exception
        except (Exception):
            print ("illegal input ,must only be numbers - Please try again")
        else:
            numOfPeople=str(numOfPeople)
            a=0

    for i in range(0,numOfPeople):
        x=1
        while x==1:
            try:    

                name=raw_input("Please enter name")
                if re.search('[^a-zA-Z\n]',name):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only letters")
            else:
                peopleList.extend(details(name))
                x=0

        x=1    
        while x==1:
            try:    

                address=raw_input("Please enter address")
                if re.search('[^a-zA-Z\n]',address):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only letters")
            else:
                peopleList[-1].changeAttribute(None,address,None)
                x=0

        x=1    
        while x==1:
            try:    

                tel=raw_input("Please enter telephone number")
                if re.search('[^0-9]',tel):
                    raise Exception
            except (Exception):
                print("illegal name - Please use only numbers")
            else:
                peopleList[-1].changeAttribute(None,address,None)
                x=0
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504

2 Answers2

1

First of all, I'm going to give quite a lot of critical feedback about your code. Please keep in mind, that I'm not doing this to abuse you for bad coding, I'm doing it purely on teaching purposes, only trying to show you better ways of doing what you've done.

Doing what I'm going to list below will fix your problem, but only cause it removes the whole try-block. So it's not a direct answer to your question, and even tho I'm spending time on this, I don't actually ask for an accept on answer. I'm just (bored) trying to help a beginner.

Not all of these are even mistakes, they are just not the best ways to do what you're doing. For a beginner, your code is actually not that bad, but there's always new to learn, and here are few things related to your code:

1. "class main"

First problem, class main() you're missing : from the end, and I suppose this is meant to be a function, not a class? Change it to def main(): to define a function. Classes are for creating objects, functions are for completing simple tasks.

2. Exceptions

There are billion ways to get an input from user and checking if it's valid input. Unfortunately, your way ain't one of those. Here's one way to do the for loop:

for i in range(numOfPeople):

    # Get user's name
    name = raw_input("Please enter name: ")

    # While name has incorrect characters
    while re.search('[^a-zA-Z\n]',name):

        # Print out an error
        print("illegal name - Please use only letters")

        # Ask for the name again (if it's incorrect, while loop starts again)
        name = raw_input("Please enter name: ")

    # .extend is used for appending lists to other lists
    # details is a class, not a list, so use .append instead
    peopleList.append(details(name))

You could also use a break, or the way I'd prefer is to create a function that returns value... Don't use exceptions if there's not a really good reason to, most of the time they're only on your way. Also, using such variables as i = 1 and while i == 1: is bad coding, instead do while True: and stop the loop by calling break, or do it like I did above.

And as I mentioned, these are just few ways to implement this, hopefully you'll find one that suits you, but please keep it simple when you can.

3. changeAttribute

Your changeAttribute() method seems useless to me. Instead of calling peopleList[-1].changeAttribute(name, None, None) you could just do peopleList[-1].name = name to get the exact same result, and not using an useless method.

4. peopleList[-1]

Using peopleList[-1] to get your object isn't a good way either, instead you should define a new person at the first line of your main function person = details() (I would rename details to Person too, but your call) and inside every for loop, just say person.name = name and replace name with whatever detail you're getting. Now after all the for loops are done, call peopleList.append(person). You could also leave the person definition from the first line of your code away, get user's name, address and number into temporary local variables, and then at last line call peopleList.append(details(name, address, number)), although the first method is recommendable.

5. CamelCaseClassNames

As I already mentioned in the comments, you should use CamelCaseNaming for your classes (instead of class details: do class Details:). This is not an error in any possible way, it's not even a mistake, but it's better to use CamelCasing so other programmers understand your code too. It's just a habit among programmers, globally used way to name classes.

0

Mahi did a good job going through ways you should improve your program, and I think you'll find that you get fewer intractable bugs if you follow his advice and work on writing simpler and more readable code.

But I wanted to answer your specific question:

Your except (Exception) block will execute every time there is an exception within the corresponding try block, not just when you explicitly raise your unnamed exception. To avoid this, you should raise and catch a specific exception.

The only way I could reproduce your infinite loop was by using the Ideone.com online interpreter, which doesn't prompt for input (you have to enter the input ahead of time). That raised an EOFError exception, which got caught by your except, and led to the infinite loop. I suspect you did something similar (or otherwise did something that raised an exception).

PeterBB
  • 343
  • 2
  • 9