Python User Input

Learn how to get input from users in Python and handle different types of user input safely.

User Input

Python allows for user input.

That means we are able to ask the user for input.

The method is a bit different in Python 3.6 than Python 2.7.

Python 3.6 uses the input() method.

Python 2.7 uses the raw_input() method.

The following example asks for the username, and when you entered the username, it gets printed on the screen:

Python 3.6

username = input("Enter username:")
print("Username is: " + username)

Python 2.7

username = raw_input("Enter username:")
print("Username is: " + username)

Input Types

The input() function always returns a string. If you need other data types, you must convert them:

Example - Getting different types of input:

# String input (default)
name = input("Enter your name: ")
print(f"Hello, {name}!")

# Integer input
age = int(input("Enter your age: "))
print(f"You are {age} years old")

# Float input
height = float(input("Enter your height in meters: "))
print(f"Your height is {height} meters")

# Boolean input
answer = input("Do you like Python? (yes/no): ").lower()
likes_python = answer in ['yes', 'y', 'true', '1']
print(f"Likes Python: {likes_python}")

Input Validation

Always validate user input to prevent errors and ensure data quality:

Example - Basic input validation:

def get_valid_integer(prompt, min_value=None, max_value=None):
    """Get a valid integer from user input with optional range checking."""
    while True:
        try:
            value = int(input(prompt))
            
            if min_value is not None and value < min_value:
                print(f"Value must be at least {min_value}")
                continue
            
            if max_value is not None and value > max_value:
                print(f"Value must be at most {max_value}")
                continue
            
            return value
        except ValueError:
            print("Please enter a valid integer")

def get_valid_float(prompt, min_value=None, max_value=None):
    """Get a valid float from user input with optional range checking."""
    while True:
        try:
            value = float(input(prompt))
            
            if min_value is not None and value < min_value:
                print(f"Value must be at least {min_value}")
                continue
            
            if max_value is not None and value > max_value:
                print(f"Value must be at most {max_value}")
                continue
            
            return value
        except ValueError:
            print("Please enter a valid number")

# Usage examples
age = get_valid_integer("Enter your age (0-150): ", 0, 150)
score = get_valid_float("Enter your score (0.0-100.0): ", 0.0, 100.0)

print(f"Age: {age}, Score: {score}")

Multiple Choice Input

Handle multiple choice scenarios with validation:

Example - Multiple choice input:

def get_choice(prompt, choices, case_sensitive=False):
    """Get a valid choice from a list of options."""
    if not case_sensitive:
        choices = [choice.lower() for choice in choices]
    
    while True:
        user_input = input(prompt)
        
        if not case_sensitive:
            user_input = user_input.lower()
        
        if user_input in choices:
            return user_input
        
        print(f"Invalid choice. Please choose from: {', '.join(choices)}")

def get_yes_no(prompt):
    """Get a yes/no answer from the user."""
    choice = get_choice(f"{prompt} (yes/no): ", ['yes', 'no', 'y', 'n'])
    return choice in ['yes', 'y']

# Usage examples
color = get_choice("Choose a color (red/green/blue): ", ['red', 'green', 'blue'])
print(f"You chose: {color}")

continue_program = get_yes_no("Do you want to continue?")
print(f"Continue: {continue_program}")

Menu Systems

Create interactive menu systems for user navigation:

Example - Interactive menu system:

class MenuSystem:
    def __init__(self, title="Main Menu"):
        self.title = title
        self.options = {}
        self.running = True
    
    def add_option(self, key, description, function):
        """Add a menu option."""
        self.options[key] = {
            'description': description,
            'function': function
        }
    
    def display_menu(self):
        """Display the menu options."""
        print("\n" + "=" * 40)
        print(f"{self.title:^40}")
        print("=" * 40)
        
        for key, option in self.options.items():
            print(f"{key}. {option['description']}")
        
        print("q. Quit")
        print("-" * 40)
    
    def get_user_choice(self):
        """Get and validate user choice."""
        valid_choices = list(self.options.keys()) + ['q']
        
        while True:
            choice = input("Enter your choice: ").lower().strip()
            
            if choice in valid_choices:
                return choice
            
            print(f"Invalid choice. Please enter: {', '.join(valid_choices)}")
    
    def run(self):
        """Run the menu system."""
        while self.running:
            self.display_menu()
            choice = self.get_user_choice()
            
            if choice == 'q':
                print("Goodbye!")
                self.running = False
            else:
                try:
                    self.options[choice]['function']()
                except Exception as e:
                    print(f"Error executing option: {e}")
                
                input("\nPress Enter to continue...")

# Example menu functions
def calculator():
    """Simple calculator function."""
    try:
        a = float(input("Enter first number: "))
        operator = input("Enter operator (+, -, *, /): ")
        b = float(input("Enter second number: "))
        
        if operator == '+':
            result = a + b
        elif operator == '-':
            result = a - b
        elif operator == '*':
            result = a * b
        elif operator == '/':
            if b == 0:
                print("Error: Division by zero!")
                return
            result = a / b
        else:
            print("Invalid operator!")
            return
        
        print(f"Result: {a} {operator} {b} = {result}")
    except ValueError:
        print("Error: Please enter valid numbers")

def word_counter():
    """Count words in user input."""
    text = input("Enter some text: ")
    word_count = len(text.split())
    char_count = len(text)
    char_count_no_spaces = len(text.replace(' ', ''))
    
    print(f"Words: {word_count}")
    print(f"Characters (with spaces): {char_count}")
    print(f"Characters (without spaces): {char_count_no_spaces}")

def temperature_converter():
    """Convert between Celsius and Fahrenheit."""
    try:
        temp = float(input("Enter temperature: "))
        unit = input("Is this Celsius or Fahrenheit? (C/F): ").upper()
        
        if unit == 'C':
            fahrenheit = (temp * 9/5) + 32
            print(f"{temp}°C = {fahrenheit:.2f}°F")
        elif unit == 'F':
            celsius = (temp - 32) * 5/9
            print(f"{temp}°F = {celsius:.2f}°C")
        else:
            print("Invalid unit! Please enter C or F")
    except ValueError:
        print("Error: Please enter a valid number")

# Create and run the menu
menu = MenuSystem("Python Utilities")
menu.add_option('1', 'Calculator', calculator)
menu.add_option('2', 'Word Counter', word_counter)
menu.add_option('3', 'Temperature Converter', temperature_converter)

# Uncomment to run the menu
# menu.run()

Advanced Input Handling

Password Input

import getpass

def secure_login():
    """Demonstrate secure password input."""
    username = input("Username: ")
    
    # getpass hides the password input
    password = getpass.getpass("Password: ")
    
    # In a real application, you would hash and verify the password
    if username == "admin" and password == "secret123":
        print("Login successful!")
        return True
    else:
        print("Invalid credentials!")
        return False

# Example usage (commented out for demo)
# secure_login()

File Path Input

import os

def get_valid_file_path(prompt, must_exist=True):
    """Get a valid file path from user input."""
    while True:
        file_path = input(prompt).strip()
        
        if not file_path:
            print("Please enter a file path")
            continue
        
        # Expand user home directory
        file_path = os.path.expanduser(file_path)
        
        if must_exist and not os.path.exists(file_path):
            print(f"File does not exist: {file_path}")
            continue
        
        if must_exist and not os.path.isfile(file_path):
            print(f"Path is not a file: {file_path}")
            continue
        
        return file_path

def get_valid_directory_path(prompt, must_exist=True):
    """Get a valid directory path from user input."""
    while True:
        dir_path = input(prompt).strip()
        
        if not dir_path:
            print("Please enter a directory path")
            continue
        
        # Expand user home directory
        dir_path = os.path.expanduser(dir_path)
        
        if must_exist and not os.path.exists(dir_path):
            print(f"Directory does not exist: {dir_path}")
            continue
        
        if must_exist and not os.path.isdir(dir_path):
            print(f"Path is not a directory: {dir_path}")
            continue
        
        return dir_path

# Example usage
# file_path = get_valid_file_path("Enter file path: ")
# dir_path = get_valid_directory_path("Enter directory path: ")

Date Input

from datetime import datetime, date

def get_valid_date(prompt, date_format="%Y-%m-%d"):
    """Get a valid date from user input."""
    while True:
        date_str = input(f"{prompt} (format: {date_format}): ")
        
        try:
            parsed_date = datetime.strptime(date_str, date_format).date()
            return parsed_date
        except ValueError:
            print(f"Invalid date format. Please use {date_format}")

def get_date_range():
    """Get a date range from user input."""
    print("Enter date range:")
    start_date = get_valid_date("Start date")
    
    while True:
        end_date = get_valid_date("End date")
        
        if end_date >= start_date:
            return start_date, end_date
        else:
            print("End date must be after start date")

# Example usage
# start, end = get_date_range()
# print(f"Date range: {start} to {end}")
# days_diff = (end - start).days
# print(f"Duration: {days_diff} days")

Input with Timeout

Handle input with timeout for automated systems:

Example - Input with timeout (Unix/Linux/Mac only):

import signal
import sys

class TimeoutError(Exception):
    pass

def timeout_handler(signum, frame):
    raise TimeoutError("Input timeout")

def input_with_timeout(prompt, timeout=30):
    """Get input with a timeout (Unix/Linux/Mac only)."""
    # Set up the timeout
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(timeout)
    
    try:
        result = input(prompt)
        signal.alarm(0)  # Cancel the alarm
        return result
    except TimeoutError:
        print(f"\nTimeout after {timeout} seconds")
        return None

# Cross-platform timeout input using threading
import threading
import queue

def input_with_timeout_cross_platform(prompt, timeout=30):
    """Get input with timeout (cross-platform)."""
    result_queue = queue.Queue()
    
    def get_input():
        try:
            result = input(prompt)
            result_queue.put(result)
        except EOFError:
            result_queue.put(None)
    
    input_thread = threading.Thread(target=get_input)
    input_thread.daemon = True
    input_thread.start()
    
    try:
        result = result_queue.get(timeout=timeout)
        return result
    except queue.Empty:
        print(f"\nTimeout after {timeout} seconds")
        return None

# Example usage
# user_input = input_with_timeout_cross_platform("Enter something (30s timeout): ", 30)
# if user_input is not None:
#     print(f"You entered: {user_input}")
# else:
#     print("No input received")

Form-like Input Collection

Collect multiple pieces of information in a structured way:

Example - User registration form:

import re
from datetime import datetime

class UserRegistration:
    def __init__(self):
        self.user_data = {}
    
    def validate_email(self, email):
        """Validate email format."""
        pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
        return re.match(pattern, email) is not None
    
    def validate_phone(self, phone):
        """Validate phone number format."""
        # Remove common separators
        cleaned = re.sub(r'[^\d]', '', phone)
        return len(cleaned) >= 10
    
    def get_user_info(self):
        """Collect user information with validation."""
        print("=== User Registration ===\n")
        
        # First Name
        while True:
            first_name = input("First Name: ").strip()
            if first_name and first_name.isalpha():
                self.user_data['first_name'] = first_name.title()
                break
            print("Please enter a valid first name (letters only)")
        
        # Last Name
        while True:
            last_name = input("Last Name: ").strip()
            if last_name and last_name.isalpha():
                self.user_data['last_name'] = last_name.title()
                break
            print("Please enter a valid last name (letters only)")
        
        # Email
        while True:
            email = input("Email: ").strip().lower()
            if self.validate_email(email):
                self.user_data['email'] = email
                break
            print("Please enter a valid email address")
        
        # Phone
        while True:
            phone = input("Phone Number: ").strip()
            if self.validate_phone(phone):
                self.user_data['phone'] = phone
                break
            print("Please enter a valid phone number")
        
        # Age
        while True:
            try:
                age = int(input("Age: "))
                if 13 <= age <= 120:
                    self.user_data['age'] = age
                    break
                else:
                    print("Age must be between 13 and 120")
            except ValueError:
                print("Please enter a valid age")
        
        # Country
        countries = ['USA', 'Canada', 'UK', 'Australia', 'Germany', 'France', 'Other']
        print("\nCountries:")
        for i, country in enumerate(countries, 1):
            print(f"{i}. {country}")
        
        while True:
            try:
                choice = int(input("Select country (number): "))
                if 1 <= choice <= len(countries):
                    if countries[choice-1] == 'Other':
                        custom_country = input("Enter your country: ").strip()
                        self.user_data['country'] = custom_country
                    else:
                        self.user_data['country'] = countries[choice-1]
                    break
                else:
                    print(f"Please enter a number between 1 and {len(countries)}")
            except ValueError:
                print("Please enter a valid number")
        
        # Interests (multiple selection)
        interests = ['Programming', 'Sports', 'Music', 'Reading', 'Travel', 'Gaming']
        print("\nInterests (enter numbers separated by commas):")
        for i, interest in enumerate(interests, 1):
            print(f"{i}. {interest}")
        
        while True:
            try:
                choices = input("Select interests: ").strip()
                if not choices:
                    self.user_data['interests'] = []
                    break
                
                selected_numbers = [int(x.strip()) for x in choices.split(',')]
                
                if all(1 <= num <= len(interests) for num in selected_numbers):
                    selected_interests = [interests[num-1] for num in selected_numbers]
                    self.user_data['interests'] = selected_interests
                    break
                else:
                    print(f"Please enter numbers between 1 and {len(interests)}")
            except ValueError:
                print("Please enter valid numbers separated by commas")
        
        # Newsletter subscription
        newsletter = input("Subscribe to newsletter? (y/n): ").lower().strip()
        self.user_data['newsletter'] = newsletter in ['y', 'yes']
        
        # Registration timestamp
        self.user_data['registered_at'] = datetime.now().isoformat()
        
        return self.user_data
    
    def display_summary(self):
        """Display registration summary."""
        print("\n" + "=" * 40)
        print("REGISTRATION SUMMARY")
        print("=" * 40)
        
        print(f"Name: {self.user_data['first_name']} {self.user_data['last_name']}")
        print(f"Email: {self.user_data['email']}")
        print(f"Phone: {self.user_data['phone']}")
        print(f"Age: {self.user_data['age']}")
        print(f"Country: {self.user_data['country']}")
        
        if self.user_data['interests']:
            print(f"Interests: {', '.join(self.user_data['interests'])}")
        else:
            print("Interests: None selected")
        
        newsletter_status = "Yes" if self.user_data['newsletter'] else "No"
        print(f"Newsletter: {newsletter_status}")
        
        print("=" * 40)
        
        # Confirmation
        confirm = input("Is this information correct? (y/n): ").lower().strip()
        return confirm in ['y', 'yes']

# Example usage
def run_registration():
    """Run the registration process."""
    registration = UserRegistration()
    
    while True:
        user_data = registration.get_user_info()
        
        if registration.display_summary():
            print("\nRegistration completed successfully!")
            print("Welcome to our platform!")
            break
        else:
            retry = input("Would you like to re-enter your information? (y/n): ").lower().strip()
            if retry not in ['y', 'yes']:
                print("Registration cancelled.")
                break

# Uncomment to run the registration
# run_registration()

Best Practices for User Input

  • Always validate input - Never trust user input without validation
  • Provide clear prompts - Tell users exactly what format you expect
  • Handle errors gracefully - Use try-except blocks for type conversions
  • Give helpful error messages - Explain what went wrong and how to fix it
  • Use loops for retry logic - Allow users to correct mistakes
  • Sanitize input - Strip whitespace and normalize case when appropriate
  • Set reasonable limits - Validate ranges for numbers, lengths for strings
  • Consider security - Use getpass for passwords, validate file paths
  • Provide defaults - Offer sensible default values when possible
  • Test edge cases - Empty input, very long input, special characters