user1543452
user1543452

Reputation: 29

Unindent does not match any outer indentation level

On line 51/52, I get the error:

Unindent does not match any outer indentation level.

I understand this has something to do with tabs and spaces.

Note I did not write this code, I found it online and plan to modify it.

Full code (also at http://pastebin.com/n7ML6Rpz)

import os
import re
import socket
import sys
import time
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create socket
server_socket.bind(("", 9020)) #Bind server to this socket
server_socket.listen(4) #Max number of queued connections
# Welcome message
print ("TCP chat server now awaiting client connection on port 9020...")
chat_log = [] #Contains chat log
time = time.strftime('%l:%M %p %Z on %b %d, %Y') #Server start time formatted nicely
start_time = str(time) #Convert server start time to string
username = "ChatUser" #Default server username if user does not provide one
# Support ~2^x client connections, where x is the number of process forks
os.fork()
os.fork()
os.fork()
# This variable contains the help documentation for the "help" command
chatHelp = ("The chat server accepts the following commands:\n"
+ "adios Closes the program\n"
+ "connection Shows client connection info (IP, port)\n"
+ "get Returns complete chat log\n"
+ "getrange <#> <#> Get chat log entries from <#> to <#> (starts at 1)\n"
+ "help Lists valid commands\n"
+ "name: <text> Sets your username to <text>\n"
+ "test: <text> Echo data back to you <text>\n"
+ "time Shows time when server was initiated\n"
+ "push: <text> Add <text> to chat log\n"
+ "save Save chat log to file\n")
while 1:
 # Accept connection
 client_socket, address = server_socket.accept()

 # Print connection info from client for server log
 print ("Received connection from client at"), address
# Used in the connection command function (client request) below
 connection = str(address)
# Send welcome string to client
 client_socket.send("Welcome to Nigel's chat room! You are logged in as ChatUser.\n Type help for a list of valid commands.\n")
# Loop indefinitely while server running
 while 1:
    data = client_socket.recv(2048) #Receive client data into buffer
 process_data = data.lower() #Lowercase received data for processing
 print ("Data received from client>>"), process_data #Print data received from client for log reference

 # Functions for the received commands (I use the find library to reduce compatibility errors with other languages)
 # ---"adios" command function---
if (process_data.find("adios") == 0):
     client_socket.close() #Close socket connection
 print ("<Ctrl+C to exit.>>")
 break;

 # ---"connection:" command function---
elif(process_data.find("connection") == 0):
 client_socket.send("Client connection info: " + connection + "\n")
 print "User requested connection information"

 # ---"getrange" command function w/ regular expression filtering (must be BEFORE "get" command function)---
 elif(re.match(r'getrange\s+(\d+)\s+(\d+)',process_data)): # Regex to find correct match with dynamic numbers input
 match = re.match(r'getrange\s+(\d+)\s+(\d+)',process_data)
 getValue = "Chat log from range "+ match.group(1) + " and " + match.group(2) + ":\n" # Grab first and second range number provided by client
 if(len(chat_log) >= int(match.group(1)) and len(chat_log) >= int(match.group(2))): # Check to see if chat log extends to given range
 count = int(match.group(1)) - 1
 while(count < int(match.group(2))):
 getValue += chat_log[count] + "\n"
 count += 1
 else:
 getValue += "<>\n" #No data in range provided by client
 client_socket.send(getValue) #Send results to client
# ---"get" command function---
 elif(process_data.find("get") == 0):
 log = "Chat log: \n"
 for item in chat_log:
 log += item+" \n"
 client_socket.send(log)

 # ---"help:" command function---
 elif(process_data.find("help") == 0):
 client_socket.send(chatHelp + "\n")
 print "User requested help"

 # ---"name:" command function---
 elif(process_data.find("name:") == 0):
 username = data[5:].strip() #Only grab the value client set (not "name:")
 client_socket.send("Username set to: " + data[5:] + "\n")

 # ---"test:" command function---
 elif(process_data.find("test:") == 0):
 client_socket.send(data[5:]+"\n") #Echo last 5 elements to client
 print data

 # ---"time" command function---
 elif(process_data.find("time") == 0):
 client_socket.send("Chat server was started at: " + start_time + "\n")
 print "User requested server start time"

 # ---"save" command function---
 elif(process_data.find("save") == 0):
 print "(Saving chat log to file)"
 client_socket.send("Saving chat log to file..." + "\n")
 filename = "chat.log"
 file = open(filename,"w") #Create file
 for item in chat_log: #Loop through elements in chat_log
 file.write("%s\n" % item) #Write elements one by one on a new line
 file.close() #Close/write file

 # ---"push" command function---
 elif(process_data.find("push:") == 0):
 print "(Pushing data to chat log)"
 if(username != ""):
 chat_log.append(username + ": " + data[5:].strip()) #Save actual chat text to log (not "push:")
 else:
 chat_log.append(data[5:].strip())
 client_socket.send("OK\n")
 else:
 print "<<Unknown Data Received>>",data #Server log
 try:
 client_socket.send("Unrecognized command: " + data + "") #Advise client of invalid command
 except socket.error, e:
 print "<<Ctrl+C to exit>>" #Server log
 break;

Upvotes: 2

Views: 5216

Answers (2)

Levon
Levon

Reputation: 143022

The code presently reads:

if (process_data.find("adios") == 0):
     client_socket.close() #Close socket connection
 print ("<Ctrl+C to exit.>>")
 break;

The first statement in the body of the if is indented 6 spaces, while the last two statements are only indented by 1 space. The indentation level ought to be same and consistent throughout the program, something like this:

if (process_data.find("adios") == 0):
   client_socket.close() #Close socket connection
   print ("<Ctrl+C to exit.>>")
   break;

The indentation in the code doesn't seem very standard (or consistent). For instance the body of the while loop in 41/42 is indented more than other bodies of similar statements, e.g., lines 31-33, that's trouble in a language like Python where whitespace matters.

Finally, note it's not a good idea to mix tabs and spaces. PEP 8 -- Style Guide for Python Code recommends the use of spaces over tabs and an indentation of 4 spaces per level.

Upvotes: 4

Greg Hewgill
Greg Hewgill

Reputation: 993163

Python code is sensitive to the indent level you use. Your code reads:

if (process_data.find("adios") == 0):
     client_socket.close() #Close socket connection
 print ("<Ctrl+C to exit.>>")
 break;

Inside the if block, the statements must all line up. Notice how client_socket.close() and the following print statement have different indent levels. You need to change this so that they both have the same indent, like this:

if (process_data.find("adios") == 0):
 client_socket.close() #Close socket connection
 print ("<Ctrl+C to exit.>>")
 break;

Upvotes: 4

Related Questions