Here's my code, can I do it better/faster?
phoneFound = False
for host in nm.all_hosts():
if 'mac' in nm[host]['addresses']:
if nm[host]['addresses']['mac'] == phone_mac:
phoneFound = True
if phoneFound == False:
print 'sh'
You could break out of the loop as soon as you found one. Alternatively (and better) you could do this in one line using the built-in function any, like so:
phone_found = any(nm[host]['address'].get('mac', None) == phone_mac for host in nm.all_hosts())
Related
So here is the question. I am trying to find if a particular value is part of a value list in a dictionary. when I tried using .values(), it wouldn't work. Here is the code. The part indicated does not go into the if statement.
company_dict = dict()
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
if id_worker in company_dict.values(): # THIS
continue # PART
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
And here is how I have managed to solve it, but it is extremely inefficient:
while True:
flag = 0
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
for i in values:
if id_worker == i and employer == key:
flag = 1
if flag == 1:
continue
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will print 'True' if the key exists in the dictionary. It's basically the same as what you had and it should work fine, check to see if it prints 'True'
company_dict = dict()
while True:
command = input("employer -> worker_id")
if command.lower() == 'end':
break
employer, id_worker = command.split(' -> ')
if id_worker in company_dict.values():
print(True)
continue
else:
if not company_dict.get(employer, false):
company_dict[employer] = [worker_id]
You could break from the for loop if you find a match, and then use an else after the for loop to mean execute some code if the for loop reached the end without break.
while True:
command = input()
if command == 'End':
break
(employer,id_worker) = command.split(' -> ')
for key,values in company_dict.items():
if employer == key and id_worker in values:
break
else:
if employer not in company_dict:
company_dict[employer] = []
company_dict[employer].append(id_worker)
This will be more efficient than what you have, because you stop searching after the first match -- both due to the break from the explicit loop and the fact that the expression id_worker in values will stop iterating on the first match. (Here the use of in for inclusion testing also avoids using an explicit loop for the iteration over values, so may be a bit faster for that reason also.)
So my problem is this: I'm running a while loop that will execute Function1 every time, Function2 and Function3 will only be executed when their respective flags are set to True, and I want to be able to alter those flags while the loop is running.
while brkFlag == False:
Function1.run()
if flag2 == True:
Function2.run()
else:
pass
if flag3 == True:
Function3.run()
else:
pass
if someConditions == True:
brkFlag = True
Currently I want to change those flags with a GUI while the loop is running and am trying to do this with tkinter's Buttons and Checkboxes, but no luck so far.
I also can't use multithreading or multiprocessing as they will considerably slow down the speed of the loop (which is already barely acceptable as it is right now, because there are lots of calculations in each function and I need to show the results in a real-time fashion).
Edit: So it seems that there is no way other than doing multithreading/processing after all.
A simple way is to pass a mutable container containing the flags, for example a list:
flags = [flag2, flag3, someConditions ]
while brkFlag == False:
Function1.run(flags)
if flags[0] == True:
Function2.run(flags)
else:
pass
if flags[1] == True:
Function3.run(flags)
else:
pass
if someConditions == True: # or if flags[2] == True:
brkFlag = True
In the callee you implement more or less:
...
def run(flags):
...
flags[0] = True # set flag2
...
I'm often tasked with asking users for input. I've always just written my prompts "as-needed" in my main execution scripts. This is kind of ugly, and because I often ask for the same types of input across multiple scripts, a ton of my code is just copy/pasted prompt loops. Here's what I've done in the past:
while True:
username = input("Enter New Username: ")
if ldap.search(username):
print " [!] Username already taken."
if not validator.validate_username(username):
print " [!] Invalid Username."
else:
break
I'd like to create something that can be called like:
username = prompt(prompt="Enter New Username: ",
default=None,
rules=["user_does_not_exist",
"valid_username"])
Then the prompt function looks like:
def prompt(prompt, default, rules):
while True:
retval = input(prompt)
if default and retval == "":
break
return default
if not rule_match(retval, rules):
continue
break
return retval
def rule_match(value, rules):
if "user_does_not_exist" in rules:
if not user.user_exists(value):
return False
if "valid_username" in rules:
if not validator.username(value):
return False
if "y_n_or_yes_no" in rules:
if "ignore_case" in rules:
if value.lower() not in ["y", "yes", "n", "no"]:
return False
else:
if value not in ["y", "yes", "n", "no"]:
return False
return True
An alternative I'm considering is to make a Prompt class, which would allow for more flexibility with the results. For example, if I want to convert the "y" or "n" to True or False, the above doesn't really work.
create_another = Prompt(prompt="Create another user? (y/n): ,"
default=False,
rules=["y_n_or_yes_no",
"ignore_case"]).prompt().convert_to_bool()
The other alternative I'm considering is just making individualized prompts and naming them, with each one written similar to my very original code. This doesn't actually change anything. It just serves to get these loops out of my main execution code which makes the main execution code easier to browse:
username = prompt("get_new_username")
def prompt(prompt_name):
if prompt_name == "get_new_username":
while True:
username = input("Enter New Username: ")
if ldap.search(username):
print " [!] Username already taken."
if not validator.validate_username(username):
print " [!] Invalid Username."
else:
break
return username
if prompt_name == "y_n_yes_no_ignore_case":
# do prompt
if prompt_name == "y_n_yes_no":
# do prompt
if prompt_name == "y_n":
# do prompt
if prompt_name == "y_n_ignore_case":
# do prompt
if prompt_name == "yes_no":
# do prompt
if prompt_name == "yes_no_ignore_case":
# do prompt
I realize that it's probably just a good idea to settle on one accepted "y/n" format for all of my programs, and I will. This is just for the sake of showing that, in cases where I would need a very similar but slightly different prompt, it would result in a lot of copy/pasted code (no flexibility with this method at all).
What is a good approach to writing clean, flexible, and easy-to-maintain user prompts?
(I've seen this: Asking the user for input until they give a valid response and some other responses. My question is not about how to get input and validate it, it's about how to make a flexible input system that can be reused with across multiple programs).
I once wrote a function for something similar. The explanation is in the doc-string:
def xory(question = "", setx = ["yes"], sety = ["no"], setz = [], strict = False):
"""xory([question][, setx][, sety][, setz][, strict]) -> string
Asks question. If the answer is equal to one of the elements in setx,
returns True. If the answer is equal to one of the elements in sety,
returns False. If the answer is equal to one of the elements in setz,
returns the element in setz that answer is equal to. If the answer is
not in any of the sets, reasks the question. Strict controls whether
the answer is case-sensitive. If show is True, an indication of the
acceptable answers will be displayed next to the prompt."""
if isinstance(setx, str):
setx = [setx]
if isinstance(sety, str):
sety = [sety]
if isinstance(setz, str):
setz = [setz]
if (setx[0])[0] != (sety[0])[0]:
setx = [(setx[0])[0]] + setx
sety = [(sety[0])[0]] + sety
question = question.strip(" ") + " "
while True:
if show:
shows = "[%s/%s] " % (setx[0], sety[0])
else:
shows = ""
user_input = raw_input(question + shows)
for y in [setx, sety, setz]:
for x in y:
if (user_input == x) or ((not strict) and (user_input.lower() == x.lower())):
if y is setx:
return True
elif y is sety:
return False
else:
return x
question = ""
show = True
Examples:
>>> response = xory("1 or 0?", ["1", "one", "uno"], ["0", "zero", "null"], ["quit", "exit"])
1 or 0? x
[1/0] eante
[1/0] uno
>>> print(response)
True
>>> response = xory("Is that so?")
Is that so? Who knows?
[y/n] no
>>> print(response)
False
>>> response = xory("Will you do it?", setz=["quit", "exit", "restart"])
Will you do it? hm
[y/n] quit
>>> print(response)
quit
I'd advise to write a library that contains a number of very clearly defined building blocks, each one as small and light-weight as possible, without too many assumptions baked in about how you're going to put the pieces together.
That is, I'd include one function that does the loop, but instead of passing in a set of rules, I'd allow for exactly one function to be passed in that either returns a value (if a valid input was given and after converting it in any way necessary) or raises a ValueError if the input wasn't usable. Other building blocks would implement certain checks or transformations (like resolution of 'y' and 'n' into boolean values).
This way, you would leave it completely up to the user to assemble the stuff in a way suitable for the use case.
# library:
def prompt(prompt, default, postprocess):
value = input('{} ({}): '.format(prompt, default)) or default
try:
return postprocess(value)
except ValueError:
continue
def check_lower(value):
if not value.islower():
raise ValueError()
def to_bool(value):
return value in 'yes'
# using the library:
def postprocess(value):
check_lower(value)
return to_bool(value)
prompt('Really?', 'n', postprocess)
I would create a prompt function as such:
def prompt(prompt, default=None, rules=[]):
while True:
response = input(prompt)
if response:
valid = [rule(response) for rule in rules]
if not(False in valid):
return response
else:
print('Invalid input')
else:
return default
You could then create different validation functions such as
def filterValidEmail(string):
if '#' in string:
if '.' in string.split('#')[1]:
return True
else:
return False
else:
return False
And call these functions like so:
prompt('What is your email? ', rules=[filterValidEmail])
You could also tweak this so that you can tell the user what verification they failed or disallow blank inputs.
The following function seems really simple, but I keep getting:
NameError: global name 'this_submit' is not defined.
Ideas?
def sort_nodes():
host_list=Popen(hosts_cmd.split(),stdout=PIPE).communicate()[0].strip()
exec_list=Popen(exec_cmd.split(),stdout=PIPE).communicate()[0].strip()
if submit_cmd == '':
submit_list = [x for x in host_list if x not in exec_list]
else:
submit_list=Popen(submit_cmd.split(),stdout=PIPE).communicate()[0].strip()
for host in host_list:
if host in exec_list:
this_exec == 'Exec'
else:
this_exec == ''
if host in submit_list:
this_submit == 'Submit'
else:
this_submit == ''
output="%s,%s,%s\n" % (host,this_submit,this_exec)
ofile.write(output)
the correct syntax is:
this_submit = 'Submit'
and
this_submit = ''
In python the single = is the assignment operator.
== checks if the value of two operands are equal or not, if yes then condition becomes true.
you wrote == instead of =. fix it and everything will be fine.
i wish to use a statement "True" and "False" for my Python (2.7) command prompt
segmentation_accuracy(reference=REFERENCE, segmented=SEGMENTED, output=OUTPUT, method=METHOD, threshold=THRESHOLD, sep=SEP, header=HEADER)
if header is True print a text file with an header, if header is False print a text file without an header.
in Command Prompt:
REFERENCE = raw_input("Reference (*.shp):")
SEGMENTED = raw_input("Segmented (*.shp):")
METHOD = raw_input("Method (ke, pu, clinton):")
if METHOD != "ke" and METHOD != "pu" and METHOD != "clinton":
raise ValueError("%s is not a valid method" % METHOD)
if METHOD == "ke" or METHOD == "clinton":
THRESHOLD = input("Threshold (0.0 - 1.0):")
if not check_threshold(THRESHOLD):
raise AccuracyException("Threshold of %s is not valid" % THRESHOLD)
else:
THRESHOLD = None
SEP = raw_input("Sep:")
HEADER = raw_input("Header (True/False):")
if HEADER is not True or HEADER is not False:
raise ValueError("%s is not valid" % HEADER)
# output
OUTPUT = raw_input("Output (*.txt):")
when i run the command prompt in windows if i set raw_input("Header (True/False):") True or False, I always get the ValueError
i also used the combination
if HEADER != True or HEADER != False:
raise ValueError("%s is not valid" % HEADER)
with the same problem
The return value from raw_input is a string and not a boolean. Hence your is not True and is not False tests, although they have well-defined meaning, that meaning is not the meaning that you intend. You need to compare HEADER against string values.
So you would need, for example, code like this:
if HEADER.lower() == 'true':
I used tolower() to effect case-insensitive comparison. You may also want to strip off white space:
if HEADER.strip().lower() == 'true':
I'm sure you can fill in the test against false yourself.
Even if you did have a boolean, you should not use code like is not True or is False. You should test for truth with:
if somebool:
or
if not somebool:
because it is much more readable.
HEADER is a string, not a boolean. This will cause the is check to fail. Your comparison runs like this:
>>> "True" is not True
True
>>> "True" is not False
True
Note that a comparison with == will also fail:
>>> "True" == True
False
>>> "True" == False
False
Try comparing the value as a string:
if HEADER.tolower() == 'true':
#do something
elif HEADER.tolower() == 'false:
#do something else