how do i verify multiple occourences using threadname.expect with pexpect library - multithreading

self.nanokdp_p.sendline(cmd)
if self.nanokdp_p.expect(match, timeout = timeout)==0:
print ("Device Sleep")
Right now i run a command on an interactive output using self.nanokdp_p.sendline(cmd)
Now i want to expect occourance of "match" string but dont want to stop at first occourence, instead i want expect or some custom function to run for a particular time and count occourances of match.
Also, this thing works if i just look and stop for first occourance.

self.thread = pexpect.spawn(cmd, logfile = my_log_file, maxread = 1)
def expectMultipleOccurrencesOfanExp(thread, expToExpect, count, timeout=120, wait = 5):
count += 1 # to match prints
for i in range(1, count):
if thread.expect(expToExpect, timeout)==0:
if i == count:
return True
elif i < count:
print (expToExpect + " found for " + str(i) + "th time")
time.sleep(wait)
continue
return False

Related

I want to be able to restart my program after a user input error

I am making a program using the python module pypokedex, to make a program that will ask for a pokemon's name, and the generation, and pull up a https://www.serebii.net/ page about it. But, if the user spells a pokemon incorrectly, it just errors and shuts down the program. I want it to restart the program.
I also have it so that if the code succeeded, it will still loop, the problem is when it fails, (again, this is only a problem if the user spells a name wrong)
the reason this:Asking the user for input until they give a valid response doesn't work is because I need to have it be certain words, not a range of numbers.
import pypokedex
import webbrowser
while 1==1:
name = input("What pokemon are you searching for? ")
p = pypokedex.get(name = name)
zero = 3-len(str(p.dex))
if(zero == 2):
num = "00" + str(p.dex)
if(zero == 1):
num = "0" +str(p.dex)
if(zero == 0):
num = str(p.dex)
ngen = input("What generation number are you looking for? ")
if(ngen == str(1)):
gen = "pokedex"
if(ngen == str(2)):
gen ="pokedex-gs"
if(ngen == str(3)):
gen = "pokedex-rs"
if(ngen == str(4)):
gen = "pokedex-dp"
if(ngen == str(5)):
gen = "pokedex-bw"
if(ngen == str(6)):
gen = "pokedex-xy"
if(ngen == str(7)):
gen = "pokedex-sm"
url = "https://www.serebii.net/" + str(gen) + "/" + str(num) + ".shtml"\
webbrowser.open(url , 2)

What is the impact of a function on execution speed?

Fairly new to python and working on an application where speed is critical - essentially in a race to book reservations online as close to 7AM as possible. Was trying to understand the impact on execution speed that a function call has, so i developed a very simple test: count to 1,000,000 and time start and end using both in line and a called function. However, the result i get says that the function takes about 56% of the time that the inline code takes. I must be really be missing something. Can anyone explain this please.
Code:
import time
def timeit():
temp = 0
while temp < 10000000:
temp += 1
return
time1 = time.time()
temp = 0
while temp < 10000000:
temp += 1
time2 = time.time()
timeit()
time3 = time.time()
temp = 0
while temp < 10000000:
temp += 1
time4 = time.time()
timeit()
time5 = time.time()
print("direct took " + "{:.16f}".format(time2 - time1) + " seconds")
print("indirect took " + "{:.16f}".format(time3 - time2) + " seconds")
print("2nd direct took " + "{:.16f}".format(time4 - time3) + " seconds")
print("2nd indirect took " + "{:.16f}".format(time5 - time4) + " seconds")
results:
direct took 1.6094279289245605 seconds
indirect took 0.9220039844512939 seconds
2nd direct took 1.5781939029693604 seconds
2nd indirect took 0.9375154972076416 seconds
I apologize for missing something silly that i must have done?

Python KeyError on second passing of .format()

I'm using .format() to autogenerate a menu. But I also need to format it as users run more tests to indicate those tests are already done.
Example test dict:
menuDict = {
"1":
{"testDataDict": "testDataDict1",
"testName": "testName1",
"testGroupName":"testGroupName1"},
"2":
{"testDataDict": "testDataDict2",
"testName": "testName2",
"testGroupName":"testGroupName2"
},
"3":
{"testDataDict": "testDataDict3",
"testName": "testName3",
"testGroupName":"testGroupName3"
},
"4":
{"testDataDict": "testDataDict4",
"testName": "testName4",
"testGroupName":"testGroupName3"
}
}
Actual code:
def menuAutoCreate(menuDict):
testGroupDict = {}
for testNum in menuDict.keys():
try:
testGroupDict[menuDict[testNum]["testGroupName"]].append(testNum)
except:
testGroupDict[menuDict[testNum]["testGroupName"]] = [testNum]
#Groups the tests under the group names
from natsort import natsorted as nt
testGroupNamesList = nt(testGroupDict.keys(), key=lambda y: y.lower())
#Naturally sorts group names so they look orderly
textDump = " "
i = 0
while i < len(testGroupNamesList):
howManyLinesEven = 0
evenList = []
howManyLinesOdd = 0
oddList = []
testGroupNameEven = testGroupNamesList[i]
textDump += "|{:44} |".format(testGroupNameEven)
howManyLinesEven = len(testGroupDict[testGroupNameEven])
evenList = nt(testGroupDict[testGroupNameEven], key=lambda y: y.lower())
#If it's an even number, it puts the menu template on the left side of the screen
if i != len(testGroupNamesList)-1:
testGroupNameOdd = testGroupNamesList[i+1]
textDump += "{:45} |".format(testGroupNameOdd) + "\n"
howManyLinesOdd = len(testGroupDict[testGroupNameOdd])
oddList = nt(testGroupDict[testGroupNameOdd], key=lambda y: y.lower())
#If it's odd, on the right side.
if i == len(testGroupNamesList)-1:
textDump += "{:45} |".format("") + "\n"
#Ensures everything is correctly whitespaced
howManyLines = max(howManyLinesEven, howManyLinesOdd)
#Checks how many lines there are, so if a group has less tests, it will have extra whitespaces
for line in range(howManyLines):
if line < howManyLinesEven:
data = {"testNum": evenList[line], "testName": menuDict[evenList[line]]["testName"]}
textDump += "|({d[testNum]}) {d[testName]:40} {{doneTests[{d[testNum]!r}]:^8}} |".format(d=data)
else:
textDump += "|{:44} |".format("")
if line < howManyLinesOdd:
data = {"testNum": oddList[line], "testName": menuDict[oddList[line]]["testName"]}
textDump += "({d[testNum]}) {d[testName]:41} {{doneTests[{d[testNum]!r}]:^8}} |".format(d=data) + "\n"
else:
textDump += "{:45} |".format("") + "\n"
#Automatically creates a menu
i += 2
print(textDump)
print("\n")
Output of this, as expected:
|testGroupName1 |testGroupName2 |
|(1) testName1 {doneTests['1']:^8} |(2) testName2 {doneTests['2']:^8} |
|testGroupName3 | |
|(3) testName3 {doneTests['3']:^8} | |
|(4) testName4 {doneTests['4']:^8} | | |
This last step will be done elsewhere, but put here for demonstration:
doneTests = {}
for testNum in menuDict.keys():
doneTests[testNum] = "(-)"
print(doneTests)
#textDump.format(**doneTests)
#This doesn't work for some reason?
textDump.format(doneTests = doneTests)
#This step will be repeated as the user does more tests, as an indicator of
which tests are completed.
The expected output would be this:
|testGroupName1 |testGroupName2 |
|(1) testName1 (-) |(2) testName2 (-) |
|testGroupName3 | |
|(3) testName3 (-) | |
|(4) testName4 (-) | | |
But here it throws a:
KeyError: "'1'"
If you remove !r from:
{{doneTests[{d[testNum]!r}]:^8}}
It throws a
KeyError: 1
instead.
I tried formatting with !s. Using lists/tuples. Adding and removing brackets. Out of ideas at this point...
Just tried your example.
I used the function sorted() instead of natsorted() and added the line
textDump = ''
to initialize the textDump variable before the line
i = 0
As a result I got no errors and got the expected output.
EDIT
Now I reproduced your error. I removed !r from {{doneTests[{d[testNum]!r}]:^8}} and used integer keys in doneTests variable
doneTests[int(testNum)] = "(-)"
to solve the problem. I guess the origin of the problem is how format() method works.

Python 3: How to exit loop without stopping function

I am a complete newbie and have tried solving this problem (with my own head and with online research) for the last 5 hours.
Below is a snippet of a function we have written to simulate a game. We want to offer the ooportunity to start a new round - meaning if a player hits "b", the game should start again at the beginning of the range (0, players). But right now it just goes onto the next player in the range (if player 1 enters "b", the program calls player 2)
players = input(4)
if players in range(3, 9):
for player in range(0, players):
sum_points = 0
throw_per_player_counter = 0
print("\nIt is player no.", player+1, "'s turn!\n")
print("\nPress 'return' to roll the dice.\n"
"To start a new round press 'b'.\n"
"Player", player+1)
roll_dice = input(">>> ")
if roll_dice == "b":
player = 0
throw_per_player_counter = 0
sum_points = 0
print("\n * A new round was started. * \n")
I have tried return and break, also tried to put it all in another while-loop... failed. Break and return just ended the function.
Any hints highly appreciated!
you could change the for loop to a while loop. instead of using a range, make player a counter
players = 4
if 3 <= players < 9:
player = 0 # here's where you make your counter
while player < players:
sum_points = 0
throw_per_player_counter = 0
print("\nIt is player no.", player+1, "'s turn!\n")
print("\nPress 'return' to roll the dice.\n"
"To start a new round press 'b'.\n"
"Player", player+1)
roll_dice = input(">>> ")
player += 1 # increment it
if roll_dice == "b":
player = 0 # now your reset should work
throw_per_player_counter = 0
sum_points = 0
print("\n * A new round was started. * \n")

Python while/if statements not working

I am currently learning Python and I am trying to get this game to work. Basically I assigned a word to be guessed and then sliced the word and assigned it to several other variables. Basically, each variable assigned as "letterx" is a letter which makes up part of the string variable word. The problem is getting the while statement with nested if statements to work. For some reason I can't get the guess input to equal letterx. All I get when I run the code is "No." and then the amount of turns left. However, I can't get the elif statement to work. Pretty much everything else works. I'm used to programming in Java and I am fairly new to Python so any tips or help would be greatly appreciated. Thank you for your time and help! Here's the code:
#Guess The Word
word = "action"
letter1 = ""
letter2 = ""
letter3 = ""
letter4 = ""
letter5 = ""
letter6 = ""
position1 = 0
position2 = 1
position3 = 2
position4 = 3
position5 = 4
position6 = 5
letter1 += word[position1]
letter2 += word[position2]
letter3 += word[position3]
letter4 += word[position4]
letter5 += word[position5]
letter6 += word[position6]
print("Welcome to Guess the Word!\n")
count = 6
while(count != 0):
guess = input("Take a guess: \n")
if(guess != letter1 or guess != letter2 or guess != letter3 or guess !=
letter4 or guess != letter5 or guess != letter6):
count -= 1
print("No.\n")
print("Turns left: \n", count)
elif(guess == letter1 or guess == letter2 or guess == letter3
or guess == letter4 or guess == letter5 or guess == letter6):
count -= 1
print("Yes.\n")
if(count == 0):
print("Your turns are up, what do you think the word is?")
guess = input("The word is...: \n")
if(guess == word):
print("You win! That's the word")
elif(guess != word):
print("Sorry, you lose.")
Here's the program running in the Python shell:
Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
Welcome to Guess the Word!
Take a guess:
a
No.
Turns left:
5
Take a guess:
c
No.
Turns left:
4
Take a guess:
t
No.
Turns left:
3
Take a guess:
i
No.
Turns left:
2
Take a guess:
o
No.
Turns left:
1
Take a guess:
n
No.
Turns left:
0
Your turns are up, what do you think the word is?
The word is...:
action
You win! That's the word
Let's say guess equals letter1. Then even though
guess == letter1, the first condition is still True since guess != letter2. And similarly, no matter what guess is, there is some letter (amongst letter1, letter2, etc.) which it is not equal.
So the first if condition is always True.
Instead, you could use
while(count != 0):
guess = input("Take a guess: \n")
if not guess in word:
count -= 1
print("No.\nTurns left: \n", count)
else:
count -= 1
print("Yes.\n")
By the way, it should be entirely possible to code the game without defining letter1, letter2, etc. All this code should be deleted:
letter1 = ""
letter2 = ""
letter3 = ""
letter4 = ""
letter5 = ""
letter6 = ""
position1 = 0
position2 = 1
position3 = 2
position4 = 3
position5 = 4
position6 = 5
letter1 += word[position1]
letter2 += word[position2]
letter3 += word[position3]
letter4 += word[position4]
letter5 += word[position5]
letter6 += word[position6]
Just use word[0] in place of letter1, and word[1] in place of letter2, etc.
And note you may not even need word[0], word[1]. For example,
with Python you can use
guess in word
instead of
guess in (word[0], word[1], word[2], word[3], word[4], word[5])
It's not only a lot less typing, it is more general, since guess in word does the right thing with words of any length.

Resources