Python swap opening/closing characters (parens, brackets, etc.) - python

Is there simple function to swapping opening/closing (directional) characters, such as (, ], <, etc.? For example:
>>> swap_direction("abcd{1>2(3]")
"abcd}1<2)3["
Alternatively, perhaps there is a method like str.upper() and str.lower() which converts all directional characters to either their opening or closing variant. This might look like:
>>> to_opening("abcd{1>2(3]")
"abcd}1<2)3["
>>> to_closing("abcd{1>2(3]")
"abcd}1>2(3]"
Is there an easier way besides chaining a bunch of str.replace() calls together?

Tl;dr
Based on replies by #jonrsharpe and #juanpa.arrivillaga, I came up with the following functions to be the best answer:
open_chars = "([{<"
close_chars = ")]}>"
swap_direction_table = str.maketrans(open_chars+close_chars, open_chars+close_chars)
def to_opening(text):
for ch_close, ch_open in zip(close_chars, open_chars):
if ch_close in text:
text = text.replace(ch_close, ch_open)
return text
def to_closing(text):
for ch_open, ch_close in zip(open_chars, close_chars):
if ch_open in text:
text = text.replace(ch_open, ch_close)
return text
def swap_direction(text):
return s.translate(swap_direction_table)
Additional Testing
For the sake of thoroughness, I did a few additional tests. Below is the complete list of functions I tried, organized by technique.
# sandbox.py
open_chars = "([{<"
close_chars = ")]}>"
to_open_table = str.maketrans(close_chars, open_chars)
to_close_table = str.maketrans(open_chars, close_chars)
swap_direction_table = str.maketrans(open_chars+close_chars, close_chars+open_chars)
def to_opening_tr(text):
return text.translate(to_open_table)
def to_closing_tr(text):
return text.translate(to_close_table)
def swap_direction_tr(text):
return text.translate(swap_direction_table)
def to_opening_tb(text):
return text.translate(str.maketrans(close_chars, open_chars))
def to_closing_tb(text):
return text.translate(str.maketrans(open_chars, close_chars))
def swap_direction_tb(text):
return text.translate(str.maketrans(open_chars+close_chars, close_chars+open_chars))
def to_opening_r(text):
return text.replace(")", "(").replace("]", "[").replace("}", "{").replace(">", "<")
def to_closing_r(text):
return text.replace("(", ")").replace("[", "]").replace("{", "}").replace("<", ">")
def to_opening_fr(text):
for ch_close, ch_open in zip(close_chars, open_chars):
if ch_close in text:
text = text.replace(ch_close, ch_open)
return text
def to_closing_fr(text):
for ch_open, ch_close in zip(open_chars, close_chars):
if ch_open in text:
text = text.replace(ch_open, ch_close)
return text
def swap_direction_fr(text):
for ch_open, ch_close in zip(open_chars, close_chars):
if ch_open in text and ch_close in text:
text = text.replace(ch_open, '$temp$').replace(ch_close, ch_open).replace('$temp$', ch_close)
elif ch_open in text:
text = text.replace(ch_open, ch_close)
elif ch_close in text:
text = text.replace(ch_close, ch_open)
return text
Here are the results from the timeit library:
to_opening_tr: 500000 loops, best of 5: 622 nsec per loop
to_opening_tb: 500000 loops, best of 5: 784 nsec per loop
to_opening_r: 1000000 loops, best of 5: 293 nsec per loop
to_opening_fr: 500000 loops, best of 5: 600 nsec per loop
to_closing_tr: 500000 loops, best of 5: 622 nsec per loop
to_closing_tb: 500000 loops, best of 5: 800 nsec per loop
to_closing_r: 1000000 loops, best of 5: 328 nsec per loop
to_closing_fr: 500000 loops, best of 5: 582 nsec per loop
swap_direction_tr: 500000 loops, best of 5: 569 nsec per loop
swap_direction_tb: 200000 loops, best of 5: 998 nsec per loop
swap_direction_fr: 500000 loops, best of 5: 937 nsec per loop
I used the following PowerShell script to automate the process a bit:
$test_str = "'abcd{1>2(3]'"
# $test_str = "'abcd{1>2(3]abcd}1>)))3[[[[abasdh[[[[[[[['" # Alternate string to try
Write-Host "to_opening_tr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_opening_tr($test_str)"
Write-Host "to_opening_tb: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_opening_tb($test_str)"
Write-Host "to_opening_r: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_opening_r($test_str)"
Write-Host "to_opening_fr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_opening_fr($test_str)"
Write-Host ""
Write-Host "to_closing_tr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_closing_tr($test_str)"
Write-Host "to_closing_tb: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_closing_tb($test_str)"
Write-Host "to_closing_r: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_closing_r($test_str)"
Write-Host "to_closing_fr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.to_closing_fr($test_str)"
Write-Host ""
Write-Host "swap_direction_tr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.swap_direction_tr($test_str)"
Write-Host "swap_direction_tb: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.swap_direction_tb($test_str)"
Write-Host "swap_direction_fr: " -NoNewline
python -m timeit -s "import sandbox" "sandbox.swap_direction_fr($test_str)"
I don't want to hear about how my PowerShell sucks ;)
The algorithms with the best times in each category are the ones in the Tl;dr above. The results seem to be consistent among a few different sample strings I've tried.

MAP1 = {'}': '{', ')': '(', ']': '[', '>': '<'}
MAP2 = dict([(MAP1[k], k) for k in MAP1])
MAP3 = MAP1 + MAP2
def to_opening(s):
res = ''
for i in s:
res += MAP1.get(i, i)
return res
def to_closing(s):
res = ''
for i in s:
res += MAP2.get(i, i)
return res
def swap_direction(s):
res = ''
for i in s:
res += MAP3.get(i, i)
return res

Related

SIM800 HTTP request not sent using AT commands

The SIM800 doesn't send the request with this code:
def getHttp(ser,rawData):
data=json.dumps(rawData)
http_commands = ["AT+SAPBR=3,1,\"Contype\",\"GPRS\"", \
"AT+SAPBR=3,1,\"APN\",\"online\"", \
"AT+SAPBR=1,1", \
"AT+SAPBR=2,1", \
"AT+HTTPINIT","AT+HTTPPARA=\"CID\",1", \
"AT+HTTPPARA=\"URL\",\"http://xxx.xxx.xxx:5000/api\"", \
"AT+HTTPPARA=\"CONTENT\",\"application/json\"", \
"AT+HTTPDATA=700,10000", \
"AT+HTTPDATA=?",data+str(chr(26)), \
"AT+HTTPACTION=1", \
"AT+HTTPREAD", \
"AT+HTTPTERM"] #the xxx.xxx.xxx is my domain
for i in http_commands:
ser.write((i+ '\n').encode('iso-8859-1'))
chars = []
while ser.inWaiting() > 0:
chars.append(ser.read())
print("AT command: "+str(i)+"; Result:"+convert(chars).replace("\n","")) #index 4
time.sleep(1)
In the terminal (with timestamps) I can see this:
1.19 AT command: AT+SAPBR=3,1,"Contype","GPRS"; Result:AT+SAPBR=1,1ERROR
1.68 CSV write error
1.68 Serial port error
2.2 AT command: AT+SAPBR=3,1,"APN","online"; Result:AT+SAPBR=3,1,"Contype","GPRS"OK
3.21 AT command: AT+SAPBR=1,1; Result:AT+SAPBR=3,1,"APN","online"OKAT+SAPBR=1,1ERROR
4.21 AT command: AT+SAPBR=2,1; Result:
5.21 AT command: AT+HTTPINIT; Result:AT+SAPBR=2,1+SAPBR: 1,1,"[ipaddress]"OKAT
6.22 AT command: AT+HTTPPARA="CID",1; Result:+HTTPINITERROR
7.22 AT command: AT+HTTPPARA="URL","http://xxxx.xxxx/api"; Result:AT+HTTPPARA="CID",1OK
8.24 AT command: AT+HTTPPARA="CONTENT","application/json"; Result:AT+HTTPPARA="URL","http://xxxx.xxxx/api"OKAT+HTTPPARA="CONTENT","application/json"OK
9.24 AT command: AT+HTTPDATA=700,10000; Result:
10.24 AT command: AT+HTTPDATA=?; Result:AT+HTTPDATA=700,10000DOWNLOAD
11.24 AT command: {"gps": ["AT+CGNSINF+CGNSINF: 1", "1", "20230210212109.000", "[mypos]", "[mypos]", "183.417", "0.00", "0.0", "2", "", "1.0", "1.3", "0.8", "", "9", "11", "8", "", "41", "", "OKAT+CPMS=\"SM\""], "serials": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}; Result:
12.25 AT command: AT+HTTPACTION=1; Result:
13.25 AT command: AT+HTTPREAD; Result:
14.25 AT command: AT+HTTPTERM; Result:
Before this method, my program correctly gets the position.
I think, the error is in my AT commands, because the serial writer properly sends other information (SMS, gps, etc) to module.

What is the most efficient way to get a list/set of keys from dictionary in python?

In order to quickly compare the keys of 2 dictionaries, I'm creating sets of the keys using this method:
dict_1 = {"file_1":10, "file_2":20, "file_3":30, "file_4":40}
dict_2 = {"file_1":10, "file_2":20, "file_3":30}
set_1 = {file for file in dict_1}
set_2 = {file for file in dict_2}
Than I use diff_set = set_1 - set_2 to see which keys are missing from set_2.
Is there a faster way? I see that using set(dict.keys()) is less of a workarou, so I'll switch to it - but is it more efficient?
Let's measure more properly (not just measuring a single execution and also not including the setup) and include faster solutions:
300 ns 300 ns 300 ns {*dict_1} - {*dict_2}
388 ns 389 ns 389 ns {file for file in dict_1 if file not in dict_2}
389 ns 390 ns 390 ns dict_1.keys() - dict_2
458 ns 458 ns 458 ns set(dict_1) - set(dict_2)
472 ns 472 ns 472 ns dict_1.keys() - dict_2.keys()
665 ns 665 ns 668 ns set(dict_1.keys()) - set(dict_2.keys())
716 ns 716 ns 716 ns {file for file in dict_1} - {file for file in dict_2}
Benchmark code (Try it online!):
import timeit
setup = '''
dict_1 = {"file_1":10, "file_2":20, "file_3":30, "file_4":40}
dict_2 = {"file_1":10, "file_2":20, "file_3":30}
'''
codes = [
'{file for file in dict_1} - {file for file in dict_2}',
'set(dict_1) - set(dict_2)',
'set(dict_1.keys()) - set(dict_2.keys())',
'dict_1.keys() - dict_2',
'dict_1.keys() - dict_2.keys()',
'{*dict_1} - {*dict_2}',
'{file for file in dict_1 if file not in dict_2}',
]
exec(setup)
for code in codes:
print(eval(code))
tss = [[] for _ in codes]
for _ in range(20):
print()
for code, ts in zip(codes, tss):
number = 10000
t = min(timeit.repeat(code, setup, number=number)) / number
ts.append(t)
for code, ts in sorted(zip(codes, tss), key=lambda cs: sorted(cs[1])):
print(*('%3d ns ' % (t * 1e9) for t in sorted(ts)[:3]), code)
The fastest and most efficient way would be:
diff_set = {*dict_1} - {*dict_2}
Output:
{'file_4'}
Proof(Execution time comparison):
import timeit
dict_1 = {"file_1":10, "file_2":20, "file_3":30, "file_4":40}
dict_2 = {"file_1":10, "file_2":20, "file_3":30}
def method1():
return {file for file in dict_1} - {file for file in dict_2}
def method2():
return set(dict_1) - set(dict_2)
def method3():
return set(dict_1.keys()) - set(dict_2.keys())
def method4():
return dict_1.keys() - dict_2.keys()
def method5():
return {*dict_1} - {*dict_2}
print(method1())
print(method2())
print(method3())
print(method4())
print(method5())
print(timeit.timeit(stmt = method1, number = 10000)/10000)
print(timeit.timeit(stmt = method2, number = 10000)/10000)
print(timeit.timeit(stmt = method3, number = 10000)/10000)
print(timeit.timeit(stmt = method4, number = 10000)/10000)
print(timeit.timeit(stmt = method5, number = 10000)/10000)
Output:
It took 1.6434900000149355e-06 sec for method 1
It took 8.317999999690073e-07 sec for method 2
It took 1.1994899999990594e-06 sec for method 3
It took 9.747700000389159e-07 sec for method 4
It took 8.049199999732082e-07 sec for method 5

How to use attributeselectedclassifier on pyweka?

Im translating a model done on weka to python-weka-wrapper3 and i dont know how to an evaluator and search options on attributeselectedclassifier.
This is the model on weka:
weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.CfsSubsetEval -P 1 -E 1" -S "weka.attributeSelection.GreedyStepwise -B -T -1.7976931348623157E308 -N -1 -num-slots 1" -W weka.classifiers.meta.MultiSearch -- -E FM -search "weka.core.setupgenerator.MathParameter -property classifier.classifier.classifier.numOfBoostingIterations -min 5.0 -max 50.0 -step 1.0 -base 10.0 -expression I" -class-label 1 -algorithm "weka.classifiers.meta.multisearch.DefaultSearch -sample-size 100.0 -initial-folds 2 -subsequent-folds 10 -initial-test-set . -subsequent-test-set . -num-slots 1" -log-file /Applications/weka-3-8-3 -S 1 -W weka.classifiers.meta.Bagging -- -P 100 -S 1 -num-slots 1 -I 100 -W weka.classifiers.meta.FilteredClassifier -- -F "weka.filters.supervised.instance.SMOTE -C 0 -K 3 -P 250.0 -S 1" -S 1 -W weka.classifiers.meta.CostSensitiveClassifier -- -cost-matrix "[0.0 1.0; 1.0 0.0]" -S 1 -W weka.classifiers.trees.ADTree -- -B 10 -E -3 -S 1
and I have this right now:
base = Classifier(classname="weka.classifiers.trees.ADTree", options=["-B", "10", "-E", "-3", "-S", "1"])
cls = SingleClassifierEnhancer(classname="weka.classifiers.meta.CostSensitiveClassifier",
options =["-cost-matrix", "[0.0 1.0; 1.0 0.0]", "-S", "1"])
cls.classifier = base
smote = Filter(classname="weka.filters.supervised.instance.SMOTE", options=["-C", "0", "-K", "3", "-P", "250.0", "-S", "1"])
fc = FilteredClassifier()
fc.filter = smote
fc.classifier = cls
bagging_cls = Classifier(classname="weka.classifiers.meta.Bagging",
options=["-P", "100", "-S", "1", "-num-slots", "1", "-I", "100"])
bagging_cls.classifier = fc
multisearch_cls = MultiSearch(
options = ["-S", "1"])
multisearch_cls.evaluation = "FM"
multisearch_cls.log_file = "/home/pablo/Escritorio/TFG/OUTPUT.txt"
multisearch_cls.search = ["-sample-size", "100", "-initial-folds", "2", "-subsequent-folds", "10",
"-initial-test-set", ".", "-subsequent-test-set", ".", "-num-slots", "1"]
mparam = MathParameter()
mparam.prop = "numOfBoostingIterations"
mparam.minimum = 5.0
mparam.maximum = 50.0
mparam.step = 1.0
mparam.base = 10.0
mparam.expression = "I"
multisearch_cls.parameters = [mparam]
multisearch_cls.classifier = bagging_cls
AttS_cls = AttributeSelectedClassifier()
AttS_cls.evaluator = "weka.attributeSelection.CfsSubsetEval -P 1 -E 1"
AttS_cls.search = "weka.attributeSelection.GreedyStepwise -B -T -1.7976931348623157E308 -N -1 -num-slots 1"
AttS_cls.classifier = multisearch_cls
train, test = data_modelos_1_2.train_test_split(70.0, Random(1))
AttS_cls.build_classifier(train)
evl = Evaluation(train)
evl.crossvalidate_model(AttS_cls, test, 10, Random(1))
print(AttS_cls)
#graph.plot_dot_graph(AttS_cls.graph)
print("")
print("=== Setup ===")
print("Classifier: " + AttS_cls.to_commandline())
print("Dataset: ")
print(test.relationname)
print("")
print(evl.summary("=== " + str(10) + " -fold Cross-Validation ==="))
print(evl.class_details())
plcls.plot_roc(evl, class_index=[0, 1], wait=True)
but when I do
AttS_cls.evaluator = "weka.attributeSelection.CfsSubsetEval -P 1 -E 1"
AttS_cls.search = "weka.attributeSelection.GreedyStepwise -B -T -1.7976931348623157E308 -N -1 -num-slots 1"
it reach me this error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_40724/2750622902.py in <module>
30
31 AttS_cls = AttributeSelectedClassifier()
---> 32 AttS_cls.search = "weka.attributeSelection.GreedyStepwise"
33 AttS_cls.classifier = multisearch_cls
34
/usr/local/lib/python3.8/dist-packages/weka/classifiers.py in search(self, search)
435 :type search: ASSearch
436 """
--> 437 javabridge.call(self.jobject, "setSearch", "(Lweka/attributeSelection/ASSearch;)V", search.jobject)
438
439
AttributeError: 'str' object has no attribute 'jobject'
I understand that I have to set them as objects because it raise this error because i try to set them as strings but I dont know how.
You need to instantiate ASSearch and ASEvaluation objects. If you have command-lines, you can use the from_commandline helper method like this:
from weka.core.classes import from_commandline, get_classname
from weka.attribute_selection import ASSearch
from weka.attribute_selection import ASEvaluation
search = from_commandline('weka.attributeSelection.GreedyStepwise -B -T -1.7976931348623157E308 -N -1 -num-slots 1', classname=get_classname(ASSearch))
evaluation = from_commandline('weka.attributeSelection.CfsSubsetEval -P 1 -E 1', classname=get_classname(ASEvaluation))
The second argument of the from_commandline method is the classname of the wrapper that you want to use instead of OptionHandler. For simplicity, I import the correct wrappers and then use the get_classname method to return the dot notation of the wrapper's class. That way I can avoid accidental typos in the classname strings.
Also, by using single quotes, you won't have to worry about Weka's quotes in the command-lines and you can just use the Weka command-line string verbatim.
You can also use the same approach for instantiating the AttributeSelectedClassifier wrapper itself, without having to go through instantiating search and evaluation separately:
from weka.core.classes import from_commandline, get_classname
from weka.classifiers import AttributeSelectedClassifier
cls = from_commandline('weka.classifiers.meta.AttributeSelectedClassifier -E "weka.attributeSelection.CfsSubsetEval -P 1 -E 1" -S "weka.attributeSelection.GreedyStepwise -B -T -1.7976931348623157E308 -N -1 -num-slots 1" -W weka.classifiers.meta.MultiSearch -- -E FM -search "weka.core.setupgenerator.MathParameter -property classifier.classifier.classifier.numOfBoostingIterations -min 5.0 -max 50.0 -step 1.0 -base 10.0 -expression I" -class-label 1 -algorithm "weka.classifiers.meta.multisearch.DefaultSearch -sample-size 100.0 -initial-folds 2 -subsequent-folds 10 -initial-test-set . -subsequent-test-set . -num-slots 1" -log-file /Applications/weka-3-8-3 -S 1 -W weka.classifiers.meta.Bagging -- -P 100 -S 1 -num-slots 1 -I 100 -W weka.classifiers.meta.FilteredClassifier -- -F "weka.filters.supervised.instance.SMOTE -C 0 -K 3 -P 250.0 -S 1" -S 1 -W weka.classifiers.meta.CostSensitiveClassifier -- -cost-matrix "[0.0 1.0; 1.0 0.0]" -S 1 -W weka.classifiers.trees.ADTree -- -B 10 -E -3 -S 1', get_classname(AttributeSelectedClassifier))

How to redirect printed value of python script to the linux terminal as a command

from itertools import permutations
from itertools import combinations
import itertools
import random
import os
def split(arr, size):
arrs = []
while len(arr) > size:
pice = arr[:size]
arrs.append(pice)
arr = arr[size:]
arrs.append(arr)
return arrs
print("Enter the GCAP utility command:")
N=raw_input()
A= [N]
A1=[]
S7=[]
S6=[]
X=[]
X1=[]
m1=[]
G=0
A1=0
G1=[]
g1=[]
u=[]
def HELP():
print('SYNTAX : ABC')
def comp():
for x11, y11 in zip(Y, m1[G-1]):
if x11 == y11:
X1 = sorted(m1[G-1])
A1= X1
return A1
def my_containsAll(str1, Y):
for c in Y:
if c not in str1: return 0;
return 1;
def mysplit(s):
head = s.rstrip('0123456789')
tail = s[len(head):]
return head, tail
def imcon(u,U3):
U1= ['imconfig','-i']
U2=U1+u+U3
return U2
if N == 'GCOA.01': ## for first GCOA.01 command
print("Enter the command in this format ")
S=raw_input()
print ("Enter the user interface for example : ")
U= raw_input()
for s in ['GCOA.01']:
g = mysplit(s)
g1.append('-c')
g1.append(g[1])
u.append(U)
#print(g1)
if S == "GCOA.01": ## if no other parameter typed
U4= imcon(u,g1)
ss= ' '.join(U4)
#print(ss)
else:
S=S.split()
S1 =[i.split('\t', 1)[0] for i in S] ## spliting the command into list
#print(S1)
G1= S1[0]
#print(G1)
for s in ['GCOA.01']:
g = mysplit(s)
#print(g[1])
S11=S1[0]
S5=[S11]
del S1[0]
for x in S1: ## separate the parameters from the whole command
print(x)
X.append(x[:2])
Y=list(X)
S2=['-c','-a','-h']
S12 =sorted(S2)
str1 = ''.join(S12)
#print(str1)
A2= my_containsAll(str1, Y)
if A2 == 1:
#print(S2)
S3=[]
for i in range(1, len(S2)+1): ## creating the permutation and combinations of the parameters
S3.extend(itertools.combinations(S2, i))
if i >= 1:
for k in S3:
for c in permutations(k):
S6.append(c)
for l in S6:
if l not in S7:
S7.append(l)
# print(S7)
for m in S7: ## creating the list of the different possible combination of P&C
m=list(m)
m1.append(m)
#print (m1)
for i1 in m1: ## for finding the index of the parameters given by the user from the P&C list of parameters
G=G+1
if Y == i1:
#print (G)
break;
g1=g1+S1
#print(g1)
if Y == m1[0]:
R=imcon(u,g1)
ss=' '.join(R)
print(ss) ## this print are basically command which is to direct on terminal window
elif Y == m1[1]:
R=imcon(u,g1)
ss=' '.join(R)
print(ss)
else:
HELP()
Output :
imconfig -i th0 -c 01 -h -a
example: (in command prompt)
c:/python34> python ssm9.py
imconfig -i th0 -c 01 - h -a
c:/python34> imconfig -i th0 -c 01 -h -a
/// i want something like that means the above printed value redirect here. but in linux terminal window
I wrote a sample code like this
vivek#vivekUbuntu:~$ cat sample.py
#! /usr/bin/python
import socket
hostname = socket.gethostname()
def getPingCommand(host):
return "ping %s" %host
print getPingCommand(hostname)
And then executed like this:
vivek#vivekUbuntu:~$ `python sample.py`
PING vivekUbuntu (127.0.1.1) 56(84) bytes of data.
64 bytes from vivekUbuntu (127.0.1.1): icmp_seq=1 ttl=64 time=0.020 ms
64 bytes from vivekUbuntu (127.0.1.1): icmp_seq=2 ttl=64 time=0.027 ms
64 bytes from vivekUbuntu (127.0.1.1): icmp_seq=3 ttl=64 time=0.050 ms
64 bytes from vivekUbuntu (127.0.1.1): icmp_seq=4 ttl=64 time=0.050 ms
64 bytes from vivekUbuntu (127.0.1.1): icmp_seq=5 ttl=64 time=0.049 ms
^C
--- vivekUbuntu ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4007ms
rtt min/avg/max/mdev = 0.020/0.039/0.050/0.013 ms
vivek#vivekUbuntu:~$
Even the option mentioned by S0III0s is also correct. It works for me.
`python ssm9.py`
or
$(python ssm9.py)
or
eval `python ssm9.py`
or
eval $(python ssm9.py)
Should all work.
(You can try it like this:)
> $(echo "echo test")
test

Python pexpect sendline contents being buffered?

I have the following code in Python using the pexpect module to run a perl script which asks a series of questions. I have used this for quite some time and works well until now.
pexpect python
index = child.expect(['Question 1:'])
os.system('sleep 2')
print 'Question 1:' + 'answer1'
child.sendline('answer1')
index = child.expect(['Question 2:'])
os.system('sleep 2')
print 'Question 1:' + 'answer2'
child.sendline('answer2')
index = child.expect(['Question 3:'])
os.system('sleep 2')
print 'Question 1:' + 'answer2'
child.sendline('answer2')
At this point, i have some code that checks if error will output when Question 2 & Question 3 does not match. I checked the pexpect log and the statements being sent are exactly what i want (number of bytes and string).
However when I check what gets accepted by the perl code its getting the following:
Question 1: 'answer 1' <-- CORRECT
Question 2: 'answer 1' <-- INCORRECT
Question 3: 'answer 2answer 2' <-- its being combined into one for some reason
Any ideas out there? I'm not using anything special when spawning my pexpect object: child=pexpect.spawn(cmd,timeout=140)
Edit: Added the perl code function that asks for Question 2 & 3
sub getpw
sub getpw
{ my ($name, $var, $encoding) = #_;
my $pw = $$var;
PWD: while(1) {
system("/bin/stty -echo");
getvar($name, \$pw, 1);
print "\n";
system("/bin/stty echo");
return if $pw eq $$var && length($pw) == 80;
if (length($pw) > 32) {
print STDERR "ERROR: Password cannot exceed 32 characters, please reenter.\n";
next PWD;
}
return if $pw eq $$var;
my $pw2;
system("/bin/stty -echo");
getvar("Repeat password", \$pw2, 1);
print "\n";
system("/bin/stty echo");
print "#1: ";
print $pw;
print "\n";
print "#2: ";
print $pw2;
if ($pw2 ne $pw) {
print STDERR "ERROR: Passwords do not match, please reenter.\n";
next PWD;
}
last;
}
# Escape dangerous shell characters
$pw =~ s/([ ;\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g;
my $correctlength=80;
my $encoded=`$AVTAR --quiet --encodepass=$pw`;
chomp($encoded);
if($? == 0 && length($encoded) == $correctlength) {
$$var = $encoded;
} else {
print "Warning: Password could not be encoded.\n";
$$var = $pw;
}
}
sub getvar
sub getvar
{ my ($name, $var, $hide) = #_;
my $default = $$var;
while(1) {
if($default) {
$default = "*****" if $hide;
print "$name [$default]: ";
} else {
print "$name: ";
}
my $val = <STDIN>;
chomp $val;
### $val =~ s/ //g; # do not mess with the password
$$var = $val if $val;
last if $$var;
print "ERROR: You must enter a value\n";
}
}
There is nothing wrong with your code on the python side. Check your perl side of the code. To demonstrate I have created below a python questions and answers scripts that call each other. When you execute answers.py it will produce the expected output as below. Also you don't need to do the sleep statements child.expect will block until the expected output has been received.
questions.py
answers = {}
for i in range(1, 4):
answers[i] = raw_input('Question %s:' % i)
print 'resuls:'
print answers
answers.py
import pexpect
child=pexpect.spawn('./questions.py', timeout=140)
for i in range(1, 4):
index = child.expect('Question %s:' % i)
child.sendline('answer%s' % i)
child.expect('resuls:')
print child.read()
output
{1: 'answer1', 2: 'answer2', 3: 'answer3'}

Categories

Resources