I am attempting to understand; and resolve, why the following happens:
$ python
>>> import struct
>>> list(struct.pack('hh', *(50,50)))
['2', '\x00', '2', '\x00']
>>> exit()
$ python3
>>> import struct
>>> list(struct.pack('hh', *(50, 50)))
[50, 0, 50, 0]
I understand that hh stands for 2 shorts. I understand that struct.pack is converting the two integers (shorts) to a c style struct. But why does the output in 2.7 differ so much from 3.5?
Unfortunately I am stuck with python 2.7 for right now on this project and I need the output to be similar to one from python 3.5
In response to comment from Some Programmer Dude
$ python
>>> import struct
>>> a = list(struct.pack('hh', *(50, 50)))
>>> [int(_) for _ in a]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: ''
in python 2, struct.pack('hh', *(50,50)) returns a str object.
This has changed in python 3, where it returns a bytes object (difference between binary and string is a very important difference between both versions, even if bytes exists in python 2, it is the same as str).
To emulate this behaviour in python 2, you could get ASCII code of the characters by appling ord to each char of the result:
map(ord,struct.pack('hh', *(50,50)))
Related
Actually I have a problem when calling a Matlab script from Python.
import matlab.engine
import os
import random
import numpy as np
a=[str(random.randint(1,3)) for _ in range(3)]
print(a)
eng=matlab.engine.start_matlab()
eng.cd("/Users/dha/Documents/MATLAB/test-matlab/",nargout=0)
sr, state=eng.test_func()
print(sr)
print(state)
In fact I want to return "sr" which is a float and an array of integer "state", e.g. sr = 34.31 and state = [1,2,5]. The function test_func() work well on Matlab, but when I run this in Python from terminal (python test_matlab_engine.py) I received the following error:
Traceback (most recent call last):
File "test_matlab_engine.py", line 10, in <module>
sr, state=eng.mabuc_drl(a)
TypeError: 'float' object is not iterable
Anyone please give me the solution. Thank you so much in advance.
It seems that the result from MATLAB to Python has been cut off. If you have two parameters, you only get one which is the first parameter from the MATLAB. So, the question is how to get two or more parameters.
In a word, you should write this in your Python file:
re = eng.your_function_name(parameter1, parameter2, nargout=2)
where re contains two parameters which come from MATLAB.
You can find more information in the official documentation: Call MATLAB Functions from Python
I have the following piece of code copied from book programming collective intelligence page 118, chapter "Document Filtering". This function breaks up the text into words by dividing the text on any character that isn't a letter. This leaves only actual words,all converted to lower-case.
import re
import math
def getwords(doc):
splitter=re.compile('\\W*')
words=[s.lower() for s in splitter.split(doc)
if len(s)>2 and len(s)<20]
return dict([(w,1) for w in words])
I implemented the function and got the following error:
>>> import docclas
>>> t=docclass.getwords(s)
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
t=docclass.getwords(s)
File "docclass.py", line 6, in getwords
words=[s.lower() for s in splitter.split(doc)
NameError: global name 'splitter' is not defined
It works here
>>> import re
>>>
>>> def getwords(doc):
... splitter=re.compile('\\W*')
... words=[s.lower() for s in splitter.split(doc)
... if len(s)>2 and len(s)<20]
... return dict([(w,1) for w in words])
...
>>> getwords ("He's fallen in the water!");
{'water': 1, 'the': 1, 'fallen': 1}
I'm gueesing you made a typo in your code, but got it right when you pasted it here.
I am experiencing a strange problem that returns the same error, regardless of the encoding I use. The code works well, without the encoding part in Python 2.7.8, but it breaks in 2.7.6 which is the version that I use for all my development.
import MIDI_PY2 as md
import glob
import ast
import os
dir = '/Users/user/Desktop/sample midis/'
os.chdir(dir)
file_list = []
for file in glob.glob('*.mid'):
file_list.append((dir + file))
dir = '/Users/user/Desktop/sample midis/'
os.chdir(dir)
file_list returns this:
[u'/Users/user/Desktop/sample midis/M1.mid',
u'/Users/user/Desktop/sample midis/M2.mid',
u'/Users/user/Desktop/sample midis/M3.mid',
u'/Users/user/Desktop/sample midis/M4.mid']
md.concatenate_midis(file_list,'/Users/luissanchez/Desktop/temp/out.mid') returns this error:
-
TypeError Traceback (most recent call last)
<ipython-input-73-2d7eef92f566> in <module>()
----> 1 md.concatenate_midis(file_list_1,'/Users/user/Desktop/temp/out.mid')
/Users/user/Desktop/sample midis/MIDI_PY2.pyc in concatenate_midis(paths, outPath)
/Users/user/Desktop/sample midis/MIDI_PY2.pyc in midi2score(midi)
/Users/user/Desktop/sample midis/MIDI_PY2.pyc in midi2opus(midi)
TypeError: Struct() argument 1 must be string, not unicode
then I modify the code so the first argument is string, not unicode:
file_list_1 = [str(x) for x in file_list]
which returns:
['/Users/user/Desktop/sample midis/M1.mid',
'/Users/user/Desktop/sample midis/M2.mid',
'/Users/user/Desktop/sample midis/M3.mid',
'/Users/user/Desktop/sample midis/M4.mid']
running the function concatenate_midis with this last list (file_list_1) returns exactly the same error: TypeError: Struct() argument 1 must be string, not unicode.
Does anybody knows what's going on here? concatenate_midi works well in python 2.7.8, but can't figure out why it doesn't work in what I use, Enthought Canopy Python 2.7.6 | 64-bit
Thanks
The error
error: TypeError: Struct() argument 1 must be string, not unicode.
is usually caused by the struct.unpack() function which in older versions of python requires string arguments and not unicode. Check that struct.unpack() arguments are strings and not unicodes.
One possible cause is from __future__ .. statement.
>>> type('a')
<type 'str'>
>>> from __future__ import unicode_literals
>>> type('a')
<type 'unicode'>
Check whether your code contains the statement.
I've got one more novice question:
I've got numerous links to external files and some of the directorate names are quite long (due to original folder structure). I've tried numerous methods for breaking a line, but most of them fails while using it with conjunction with pyodbc module.
So far I've got:
SIMD = xlrd.open_workbook(r'P:\Costing and Income\Projects & Planning\HRG, '\
'IRF, Programme Budgeting\__2008-11\Developments\SIMD\PI_upload (08.05.2012).xls')
Which works OK for xlrd module
Tried some simple stuff directly in the IDLE:
>>> a = 'some text'\
'more stuff'
>>> a
'some textmore stuff'
>>> b = r'some stuff'\
' even more'
>>> b
'some stuff even more'
>>> c = r'one' r'two'
>>> c
'onetwo'
>>>
And now the part that fails me:
PCPath1 = r'Z:\IRF\Data\Primary Care Hospitals\PI\_'\
'2008-11 (final)\2012.08.15 - 2008-11_PCH_v4.mdb'
PCConn1 = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb)}; DBQ='+PCPath1)
I've got following error:
Traceback (most recent call last):
File "Z:/IRF/Python/Production/S3_PC1_0811.py", line 7, in <module>
PCConn1 = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb)}; DBQ='+PCPath1)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x81 in position 100: ordinal not in range(128)
It works OK when PCPath1 is not broken down.
One could ask why I'm trying to do it, well mostly is for the code readibility.
Any help with above would be greatly appreciated!
You need to put an r in front of the second line as well, otherwise the \ will be combined with the 201 to produce the non-ascii character \x81.
In [5]: r'Z:\IRF\Data\Primary Care Hospitals\PI\_'\
'2008-11 (final)\2012.08.15 - 2008-11_PCH_v4.mdb'
Out[5]: 'Z:\\IRF\\Data\\Primary Care Hospitals\\PI\\_2008-11 (final)\x812.08.15 - 2008-11_PCH_v4.mdb'
In [6]: r'Z:\IRF\Data\Primary Care Hospitals\PI\_'\
r'2008-11 (final)\2012.08.15 - 2008-11_PCH_v4.mdb'
Out[6]: 'Z:\\IRF\\Data\\Primary Care Hospitals\\PI\\_2008-11 (final)\\2012.08.15 - 2008-11_PCH_v4.mdb'
Suppose I have the following string.
irb(main):074:0> line = "#!/usr/bin/ruby\n#\n# Gen"
irb(main):078:0> NArray.to_na(line,Float)
=> NArray.float(3):
[ 9.05457e+164, 3.30198e-258, 6.1531e+223 ]
How do I mimic this behavior with Python using numpy.array?
I tried the following, but it did not work.
>>> line = '#!/usr/bin/ruby\n#\n# Gen'
>>> np.array(line,float)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: #!/usr/bin/ruby
#
# Gen
Then I tried to convert it to bytes, but that did not work either.
>>> bytes = bytearray(line, 'utf-8')
>>> np.array(bytes,float)
array([ 35., 33., 47., 117., 115., 114., 47., 98., 105.,
110., 47., 114., 117., 98., 121., 10., 35., 10.,
35., 32., 32., 71., 101., 110.])
How do I resolve this?
You can easily achieve this by using the fromstring method of numpy:
import numpy as np
line = "#!/usr/bin/ruby\n#\n# Gen"
array = np.fromstring(line, dtype=float)
print array
Executing the above code results in
[ 9.05457127e+164 3.30197767e-258 6.15310337e+223]