duration = inputScriptLine.split(' ', 1)[1]
if type(duration) == str:
print ' Error: Sleep duration "' + duration + '" is not numeric'
given SLEEP 50, I get Error: Sleep duration "50" is not numeric
I am not too concerned as to why, I just want to know how I can code so that SLEEP 50 is valid and SLEEP APNOEA is not.
Use isdigit():
if not duration.isdigit():
print 'Error: Sleep duration "' + duration + '" is not numeric'
It would check whether all characters in duration are digits or not.
If you want to accept more than just ints you should cast to float:
def is_numeric(s):
try:
float(s)
return True
except ValueError:
return False
duration = inputScriptLine.split(' ', 1)[1]
if not is_numeric(duration):
print(' Error: Sleep duration {} is not numeric'.format())
float("1.0"), float("1"), float("1.5") etc.. would all return True but int("1.0"), int("1.5") etc..would also return False which if you are actually looking for numeric input would be wrong.
If you want to make sure you also get a positive number, store the result after you cast and return f > 0:
def is_positive_numeric(s):
try:
f = float(s)
return f > 0
except ValueError:
return False
try:
duration = int(duration)
except:
pass
This will attempt to convert it to an int, if it's not numeric it will fail and stay a string.
DeveloperXY's solution is cleaner, but if you want to use the value as an int later on, my solution is useful.
duration = inputScriptLine.split(' ', 1)[1]
try:
duration = int(duration)
except ValueError:
print ' Error: Sleep duration "' + duration + '" is not numeric'
You are checking if the input is a string. It will be - you've just used the split command on a string.
You need to check if the string contains only numeric characters, with .isdigit().
Note that this won't accept negative inputs, but you don't want those as this is a time.
So your new code is:
duration = inputScriptLine.split(' ', 1)[1]
if not duration.isdigit():
print 'Error: Sleep duration "' + duration + '" is not numeric'
Related
While putting the def clockPrint() function in try-except, try block is working fine but except block is not working (printing the statement as output which is in except block)
import datetime
try:
def clockPrint(sentence):
now = datetime.datetime.now()
date_time = now.strftime("%H:%M:%S")
print(date_time + " : " + sentence)
except TypeError:
print("Error: Invalid sentence")
If I try to call clockPrint(909) then according to the logic, it should display "Error: Invalid sentence" as an output but it is displaying "TypeError: can only concatenate str (not "int") to str" as an output. Any suggestions
You try block just does nothing. Define function outside try block and just call it from this block.
import datetime
def clockPrint(sentence):
now = datetime.datetime.now()
date_time = now.strftime("%H:%M:%S")
print(date_time + " : " + sentence)
try:
...
clockPrint(sentence)
...
except TypeError:
print("Error: Invalid sentence")
import datetime
def clockPrint(sentence):
try:
now = datetime.datetime.now()
date_time = now.strftime("%H:%M:%S")
print(date_time + " : " + sentence)
except TypeError:
print("Error: Invalid sentence")
Try this:
import datetime
def clockPrint(sentence):
now = datetime.datetime.now()
date_time = now.strftime("%H:%M:%S")
try:
print(date_time + " : " + sentence)
except TypeError:
print("Error: Invalid sentence")
I am making a bot that links users to the SCP Wiki (The foundation one). I want my bot to be able to pick up a SCP classification (i.e. SCP-370) and return a message with the link to the scp wiki, with that number (i.e. http://scp-wiki.net/scp-370)
I've tried a few things, such as:
def scp_url(num):
return "http://www.scp-wiki.net/scp-" + num
def scp_link(num):
return "[SCP-" + num + "](" + scp_url(num) + ")"
#client.event
async def on_message(message):
if "SCP" in message.content:
msg = scp_link
await client.send_message(message.channel, msg)
Or:
if int in message.content:
int = num
I just can't find a way to grab the numbers from the message.
Any help is appreciated.
For that, you need to know the format of the input.
From your question I see it's not command because it will check every message for SCP string. But will the string be formatted as SCP-1 or SCP-001 or SCP 1?
You need to take care of all of those cases or just make 1 selected case and deal with that. Here's my fully commented code which deals with all 3 cases:
# Number separator is character between SCP and a number, example with space:
# SCP 1
NUMBER_SEPARATOR = " "
MAXIMUM_SCP_NUMBER = 4999
def get_scp_link(message_content):
word_list = message_content.split(NUMBER_SEPARATOR)
scp_number = _extract_scp_number(word_list)
if scp_number is not None:
try:
# int(scp_number) takes care if users already entered 001
# because it makes it equal to 1
formatted_number = _format_scp_number(int(scp_number))
return _build_scp_url(formatted_number)
except Exception:
return None
# #param word_list a list of strings
# #return integer or None if error
def _extract_scp_number(word_list):
captured_scp_number = None
for index, word in enumerate(word_list):
if word == "SCP":
# We're gonna return the word after the current word (index+1)
# But we have to make sure that the next word exists in the list
# otherwise we will get IndexError exception
if index + 1 < len(word_list):
captured_scp_number = word_list[index + 1]
else:
return None
# If we captured a string in the for loop we have to make sure that that
# string is actually a number and not some random word example "SCP blabla"
if captured_scp_number is not None and captured_scp_number.isdigit():
return captured_scp_number
return None
# Formats number as a string in format 001-MAXIMUM_SCP_NUMBER
# This allows users to enter 1 instead of 001.
#
# #param number a positive integer to be formatted
# #return string in format 001-MAXIMUM_SCP_NUMBER or raise Exception if error
def _format_scp_number(number):
if number == 0:
raise Exception("SCP 0 doesn't exist!")
elif number > MAXIMUM_SCP_NUMBER:
raise Exception("SCP number too high! Entry doesn't exist!")
elif number < 10:
return "00" + str(number)
elif number < 100:
return "0" + str(number)
else:
return str(number)
# #param formatted_scp_number a string in format 001-MAXIMUM_SCP_NUMBER
# #return string representing URL to SCP-number web page
def _build_scp_url(formatted_scp_number):
base_url = "http://www.scp-wiki.net/scp-"
prefix = "[SCP-" + formatted_scp_number + "]"
return prefix + base_url + formatted_scp_number
#client.event
async def on_message(message):
if "SCP" in message.content:
scp_link = get_scp_link(message.content)
if scp_link is not None:
await client.send_message(message.channel, scp_link)
Comment below for any questions or suggestions.
I am making an online game using the sockets module and pygame in python.
def read_pos(str):
if str is not None:
string = str.split(",")
return int(string[0]), int(string[1])
else:
pass
def make_pos(tup):
return str(tup[0]) + "," + str(tup[1])
def redrawWindow(win,player, player2):
win.fill((255,255,255))
player.draw(win)
player2.draw(win)
pygame.display.update()
def main():
run = True
n = Network()
startPos = read_pos(n.getPos())
p = Player(startPos[0],startPos[1],100,100,(0,255,0))
p2 = Player(0,0,100,100,(255,0,0))
clock = pygame.time.Clock()
while run:
clock.tick(60)
p2Pos = read_pos(n.send(make_pos((p.x, p.y))))
p2.x = p2Pos[0]
p2.y = p2Pos[1]
p2.update()
This is the code I'm using in my client. in my server, the code is as follows
def convertPos(str):
if str is not None:
str = str.split(",")
return int(str[0]), int(str[1])
else:
pass
def make_pos(tup):
return str(tup[0]) + "," + str(tup[1])
pos = [(0,0),(100,100)]
def threaded_client(conn,player):
conn.send(str.encode(make_pos(pos[player])))
reply = " "
while True:
try:
data = conn.recv(2048).decode()
pos[player] = data
if not data:
print("Disconnected")
break
else:
if player == 1:
reply = (pos[0])
else:
reply = (pos[1])
print("Received: ", data)
print("Sending : ", reply)
conn.sendall(str.encode(make_pos(reply)))
except:
break
print("Lost connection")
conn.close()
I am getting the error of ValueError: invalid literal for int() with base 10: ' '.
Can someone tell me why this is happening? The value of str in the function of convertPos() is coming in as a tuple which I am converting into a string and after that into an integer.
As you have converted it to string, the format you have is (x,y), you need to remove the brackets. You need to rewrite your convertPos function as:
def convertPos(str):
if str is not None:
str=str.strip("()")
str = str.split(",")
return int(str[0]), int(str[1])
EDIT You are not using the else part, so you can remove it.
And as #Azat Ibrakov says, you should not convert the tuple to an string, but if you need to do it, you can use ast.literal_eval like this:
import ast
def convertPos(str):
return ast.literal_eval(str)
or use it directly in place of the convertPos function.
Obviously - as others have pointed out, the returned error is because you're trying to convert an empty string (or spaces) to an integer.
But the real issue is that the incoming co-ordinate is malformed. The code is not catching this error. You can write lots of code to determine what the error is, and report an accurate error. Or just plough-on as if everything is fine, but also catch any exception with a reasonable error message.
def convertPos(str):
coord = None
try:
parts = str.split( ',', 2 )
x = int( parts[0] )
y = int( parts[1] )
coord = ( x, y )
except:
raise ValueError( 'Malformed co-ordinate string [' + str.strip() + ']' )
return coord
I suspect the socket code is not buffering a full packet, and maybe what's being processed is something like 122,, whereas the socket buffering needs to keep reading until a full co-ordinate has arrived.
So you could space-pad your co-ordinates to say a block of 11 characters - that way you know you must have received 11 characters to have a valid co-ordinate string. Alternatively use and end-of-coord marker, like a |, and then the socket code keeps buffing the input co-ordinate until that | arrives.
I'm working on a very simple temperature converter in Python (just for practice), and am struggling with some of the UX components. I'd like to have checks in place to continue prompting for variable input when invalid entries are made. My full code is below:
o_temp = ''
def temp_input(o_temp):
o_temp = raw_input('Enter a temperature (round to nearest integer): ')
return o_temp
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
temp_input(o_temp)
else:
break
def converter(o_temp):
unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
unit = unit.upper()
if unit == 'F' or unit == 'f':
n_temp = (9.0/5.0) * int(o_temp) + 32
print '%d C = %d F' % (o_temp, n_temp)
quit()
elif unit == 'C' or unit == 'c':
n_temp = (5.0/9.0) * (int(o_temp) - 32)
print '%d F = %d C' % (o_temp, n_temp)
quit()
else: #check for valid entry
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
unit_input()
def temp_converter():
#title, call sub-functions
print ''
print 'Temperature Converter'
print ''
temp_input(o_temp)
temp_input_check(o_temp)
converter(o_temp)
temp_converter()
However, when I enter an invalid entry (say, a letter or a combination of letters and numbers) into the o_temp prompt, the code does not seem to recognize that this is invalid and continues with the unit prompt. Am I not correctly returning the variable? What's the issue here? I tried removing the initial o_temp declaration but then I got "NameError: global name 'o_temp' is not defined"
EDIT
I came up with this solution, any further suggestions to refine the code at all?
def converter():
print 'Temperature Converter'
while 1:
temp = raw_input('Starting temperature? ')
try:
temp = float(temp)
except ValueError:
print 'Invalid entry. Please enter only the numerical temperature measurement.'
else:
break
while 1:
unit = raw_input('Convert to Fahrenheit or Celsius? ')
if unit.upper().startswith('F') == True:
print "%f C = %f F" % (temp, temp*9./5+32)
return False
elif unit.upper().startswith('C') == True:
print "%f F = %f C" % (temp, (temp-32)*5./9)
return False
else:
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
converter()
You define some functions, then call temp_coverter(). This function calls temp_input(otemp), sending it an empty string for no reason that I can see, other than the possibility that you're unaware that you can define a function with no parameters. This function then returns a value, which you don't save.
After that, temp_input_check(otemp) is called, which attempts to validate the same empty string. This function's returned value isn't saved, which isn't a big loss, because None isn't a particularly useful value to save.
Then converter(otemp) sends the same old empty string to the actual converter. Mayhem results.
I recommend spending some quality time with the tutorial.
When you're done, the code should look more like this:
def converter():
print 'Temperature Converter'
unit = raw_input('Convert to Fahrenheit or Celsius? ')
while 1:
temp = raw_input('Starting temperature? ')
try:
temp = float(temp)
except ValueError:
print 'Not a valid temperature.'
else:
break
if unit.lower().startswith('f'):
print "%f C = %f F" % (temp, temp*9./5+32)
else:
print "%f F = %f C" % (temp, (temp-32)*5./9)
converter()
Your for loop isn't implemented correctly.
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
temp_input(o_temp)
else:
break
You check every character for an invalid entry. If you typed in multiple invalid characters, it'll keep hitting the trigger after you have already determined that the string is invalid!
Also, if your first character is valid, you're telling it to break from the for loop (in your code 1fdsdfdsf would be a valid temperature, because it would skip every character after hitting that else statement and breakout from the loop).
Also, your temp_input doesn't need to accept an argument in the function (you're just gonna return the user's input). You actually want to assign it after you call the function instead of having it as an argument
Also, you're calling temp_input again to get the user input, but not capturing that anywhere with a return - so it's ultimately not doing anything. You should have your function return a True or False, and then catch that on the outside of the checker if you want to have the user try and enter a better temperature:
def temp_input_check(o_temp):
o_temp = list(o_temp)
for i in o_temp:
if i not in '1234567890':
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
return False
else:
pass # nothing is wrong with this character, keep checking
return True # if we hit this line, there were no problem characters
Then, when you call the stuff:
while(1):
o_temp = temp_input()
if temp_input_check(o_temp):
break # this means our o_temp is allllright.
# otherwise, go back to the start of the loop and ask for another temp
converter(o_temp)
because you mentioned 'o_temp' as the function parameter in the end but mentioned it as a empty string at Start. Don't give same names for global & function variables (just to avoid confusion). the function took the o_temp you mentioned above as parameter and neglects the one inside them.
Also the raw_input won't consider the input as string. Try input instead to avoid the sensibility of not using str to correct the loop.
This will do:
def converter():
o_temp = float(raw_input('Enter a temperature (round to nearest integer): '))
for i in str(o_temp):
if i not in ['1','2','3','4','5','6','7','8','9','0','.']:
print 'Invalid entry. Please enter only the numerical temperature measurement in integer format.'
unit = raw_input('Convert to (F)ahrenheit or (C)elsius? ')
if unit in ['f','F']:
n_temp = (9.0/5.0) * float(o_temp) + 32
print '%f C = %f F' % (o_temp, n_temp)
elif unit in ['c','C']:
n_temp = (5.0/9.0) * (float(o_temp) - 32)
print '%f F = %f C' % (o_temp, n_temp)
else: #check for valid entry
print 'Invalid entry. Please enter F for Fahrenheit or C for Celsius'
unit_input()
def temp_converter():
#title, call sub-functions
print ''
print 'Temperature Converter'
print ''
converter()
print temp_converter()
I have the following code:
#gets the filename from the user
b= input("Please enter a file name to be opened: ")
a = (b+".txt")
#main data storage and other boolean options
data =[]
result1 =[]
on = True
#File reading in main body with try and except functionality.
try:
check = open(a, 'r')
line =check.readlines()
for items in line:
breakup= items.split()
number, salary, position, first, oname1, oname2, last = breakup
data.append(tuple([last, first + ' ' + oname1 + ' ' + oname2, number, position, salary]))
except IOError as e :
print("Failed to open", fileName)
#Employee creation function, takes the line and stores it in the correct position.
def employee_creation():
result = [((item[0] +", "+ item[1]).ljust(30), int(item[2]), item[3].ljust(15), int(item[4])) for item in data]
for items in result:
result1.append((items[0][0:30], format(items[1], "^5d"), items[2][0:15], "£"+format((items[3]),"<8d")))
return(result)
employee_creation()
print(result)
while on == True:
print("Please select what option you would like to use to search for employees:")
option = int(input("""
1 - Salary (X to X)
2 - Job Titlle
3 - Name, Payroll Number
:"""))
if option == 1:
start = input("What range would you like to start from: ")
end = input("What is the maximum range you would like :")
for items in result:
print(items[3])
if items[3]>start and items[3]<end:
print(items)
else:
print("No employees with this information can be found")
on= False
else:
on= False
However my def employee_creation() doesn't actually return result. I need it to make it a global variable so that I can use it to launch personal querys against the data.
Can anyone see why its not working?
No need to use the evil global variables. You forgot to store the result of your function to another variable.
def employee_creation():
result = [((item[0] +", "+ item[1]).ljust(30), int(item[2]), item[3].ljust(15), int(item[4])) for item in data]
for items in result:
result1.append((items[0][0:30], format(items[1], "^5d"), items[2][0:15], "£"+format((items[3]),"<8d")))
return result # no need for () here
result = employee_creation() # store the return value of your function
print(result)