I am working on the following python code:
import wave
from bitstring import BitArray
w = wave.open('file.wav','rb')
totalFrames = w.getnframes() #Total number of samples
bytesData = w.readframes(totalFrames)
binData = BitArray(bytesData)
bin2Data = (binData.bin)
The file.wav has 88200 samples at a sampling rate of 44.1KHz.
My goal is to be able to get the 2's compliment of the binary data I obtain from file.wav. 'binData.bin' gives me the binary form of the bytes (\x00\x00N\x00n\xff..) obtained through w.readframes but in a string format.
I was using this to obtain 2'scompliment:
2comp = ~(bin2Data) + 0b1
but in vain. It would show the following error:
Traceback (most recent call last):
File "speaker_bin.py", line 16, in <module>
bin2Data = ~((binData.bin)) + 0b1
TypeError: bad operand type for unary ~: 'str'
I tried int(bin2Data) to convert it but it would not work (It would not print anything at all. I guess because of the size of the data.)
What am I doing wrong?
I would really appreciate any feedback. (even a simple nudge in the right direction)
You need to use
int(binData.bin, 2)
To create an int, you can specify the base as a second parameter, otherwise it will just assume the value is in base 10. As you can see from the docs, the default base is 10, which is why you need to specify a different base other than 10
Also do the same with 0b1
Related
I am new to python so I appreciate your help!
I am writing a simple code to read GPS data and print the speed value.
The gps sends serial lines of text like this:
$GNRMC,055945.00,A,3509.40388,N,10642.56412,W,0.080,,060321,,,D*72
$GNVTG,,T,,M,0.080,N,0.148,K,D*3D
$GNGGA,055945.00,3509.40388,N,10642.56412,W,2,12,0.64,1581.1,M,-23.9,M,,0000*4E
$GNGSA,A,3,29,05,18,15,13,20,23,25,51,46,26,16,1.20,0.64,1.02*1E
$GNGSA,A,3,65,87,88,72,66,79,81,,,,,,1.20,0.64,1.02*10
and my code currently looks for the correct line and the correct value using if statements:
import serial
import time
gps = serial.Serial("/dev/serial0", baudrate = 9600)
while True:
line = gps.readline()
data = line.decode().split(",")
if data[0] == "$GNRMC":
if data[2] == "A":
if data[4] == "N":
if data[6] =="W":
knotdata = data[7]
mphdata = knotdata * 1.15
print(mphdata)
however I am getting the following error:
Traceback (most recent call last):
File "txgpsreadconv.py", line 15, in <module>
mphdata = knotdata * 1.15
TypeError: can't multiply sequence by non-int of type 'float'
I have tried many different approaches to rectify the issue with no success. I'm sure the solution is simple and I just don't have enough experience to figure it out, so your help is much appreciated!
The traceback is suggesting that knotdata is a sequence, which is not a data type that can be multiplied by a floating point number.
Essentially you're trying to multiply a string that represents a numeric value instead of the value itself, so you should do a casting before the operation:
knotdata = float(data[7])
Also you can improve the structure of your if statements like this:
if data[0:8:2] == ["$GRNMC", "A", "N", "W"]:
print(float(data[7]) * 1.15)
since your data[7] is a float variable, you can use type casting float
mphdata = float(knotdata) * 1.15
I'm trying to create a GUI for a signal analysis simulation that i'm writing in Python. For that, I use AppJar. However, when I call the function that generates the signal, I get a ValueError like in the title.
I've read every single ValueError post on stackOverflow (i could have missed one maybe, but i did my best) and all of them are about extra spacings, letters that can not be parsed as a floating point number, etc. None of that seems to apply here.
Basically, i'm using this code to call a function to generate my signal:
signal_axes = app.addPlot("signal", *logic.signal(5, 2), 0, 0, 1)
And the relevant part of the function itself (in the file logic.py, which is imported)
def signal(electrodes, length):
velocity = math.sqrt((3.2e-19 * kinetic_energy) / (mass * 1.66e-27))
frequency = velocity / length
This is not the whole function, the variables are all declared and unused variables are used later in the function.
The error specifically points to the line with "frequency = velocity / length", telling me:
TypeError: unsupported operand type(s) for /: 'float' and 'str'
When i try to fix it by using "float(length)" i get the error:
ValueError: could not convert string to float:
In one of the answers on StackExchange someone suggested using .strip() to get rid of invisible spaces. So i tried using:
length.strip()
But that gives me the following error:
AttributeError: 'float' object has no attribute 'strip'
I am slowly descending into madness here. The following code, by the way, stand-alone, works:
import numpy as np
kinetic_energy = 9000
mass = 40
length = 2e-2
velocity = np.sqrt((3.2e-19 * kinetic_energy) / (mass * 1.66e-27))
frequency = float(velocity) / float(length)
print(frequency)
Can anyone see what could be wrong? I've included all the relevant code below, it's not my complete file but this alone should give an output, at least.
run.py
import logic
from appjar import gui
def generate(btn):
app.updatePlot("signal", *logic.signal(app.getEntry("electrodes"), app.getEntry("length")))
showSignalLabels()
def showSignalLabels():
signal_axes.set_xlabel("time (us)")
signal_axes.set_ylabel("amplitude (uV)")
app.refreshPlot("signal")
app = gui()
signal_axes = app.addPlot("signal", *logic.signal(5, 0.02), 0, 0, 1)
app.addLabelEntry("electrodes", 1, 0, 1)
app.addLabelEntry("length", 2, 0, 1)
showSignalLabels()
app.addButton("Generate", generate)
app.go()
logic.py
import numpy as np
import math
import colorednoise as cn
steps = 5000
amplitude = 1
offset_code = 0
kinetic_energy = 9000
mass = 40
centered = 1
def signal(electrodes, length):
velocity = math.sqrt((3.2e-19 * kinetic_energy) / (mass * 1.66e-27))
frequency = velocity / length
time = 2 * (electrodes / frequency)
--- irrelevant code ---
return OutputTime, OutputSignal
edit: here is the full traceback.
Exception in Tkinter callback
Traceback (most recent call last):
File "E:\Internship IOM\WPy64-3720\python-3.7.2.amd64\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "E:\Internship IOM\PythonScripts\appJar\appjar.py", line 3783, in <lambda>
return lambda *args: funcName(param)
File "E:/Internship IOM/PythonScripts/appJar/testrun.py", line 12, in generate
app.updatePlot("signal", *logic.signal(app.getEntry("electrodes"), app.getEntry("length")))
File "E:\Internship IOM\PythonScripts\appJar\logic.py", line 33, in signal
frequency = velocity / length
TypeError: unsupported operand type(s) for /: 'float' and 'str'
You should convert at the calling site, i.e. do:
def generate(btn):
app.updatePlot("signal", *logic.signal(app.getEntry("electrodes"),
float(app.getEntry("length"))))
...
Because otherwise your function logic.signal receives different type (str and float). That's why you receive the other error about float has no strip because somewhere else in your code you do:
signal_axes = app.addPlot("signal", *logic.signal(5, 0.02), 0, 0, 1)
Here you pass it a float.
Since your original error was could not convert string to float with an apparently empty string, you need to take an extra measure to prevent empty values from the app. You can use a try ... except:
def generate(btn):
try:
length = float(app.getEntry("length"))
except ValueError:
# Use some default value here, or re-raise.
length = 0.
app.updatePlot("signal", *logic.signal(app.getEntry("electrodes"), length))
For the code below:
def makePrediction(mytheta, myx):
# -----------------------------------------------------------------
pr = sigmoid(np.dot(myx, mytheta))
pr[pr < 0.5] =0
pr[pr >= 0.5] = 1
return pr
# -----------------------------------------------------------------
# Compute the percentage of samples I got correct:
pos_correct = float(np.sum(makePrediction(theta,pos)))
neg_correct = float(np.sum(np.invert(makePrediction(theta,neg))))
tot = len(pos)+len(neg)
prcnt_correct = float(pos_correct+neg_correct)/tot
print("Fraction of training samples correctly predicted: %f." % prcnt_correct)
I get this error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-f0c91286cd02> in <module>()
13 # Compute the percentage of samples I got correct:
14 pos_correct = float(np.sum(makePrediction(theta,pos)))
---> 15 neg_correct = float(np.sum(np.invert(makePrediction(theta,neg))))
16 tot = len(pos)+len(neg)
17 prcnt_correct = float(pos_correct+neg_correct)/tot
TypeError: ufunc 'invert' not supported for the input types, and the inputs
Why is it happening and how can I fix it?
np.invert requires ints or bools, use the method np.linalg.inv instead.
From the documentation:
Parameters:
x : array_like.
Only integer and boolean types are handled."
Your original array is floating point type (the return value of sigmoid()); setting values in it to 0 and 1 won't change the type. You need to use astype(np.int):
neg_correct = float(np.sum(np.invert(makePrediction(theta,neg).astype(np.int))))
should do it (untested).
Doing that, the float() cast you have also makes more sense. Though I would just remove the cast, and rely on Python doing the right thing.
In case you are still using Python 2 (but please use Python 3), just add
from __future__ import division
to let Python do the right thing (it won't hurt if you do it in Python 3; it just doesn't do anything). With that (or in Python 3 anyway), you can remove numerous other float() casts you have elsewhere in your code, improving readability.
I'm working on a project where the output size is very important. As my outputs are numbers between 0 and 100, I'm trying to write them as bytes (or unsigned chars).
However, I'm getting errors when trying to read them.
Here is a simple example:
test_filename='test.b'
g=(3*ones(shape=[1000])).astype('c')
g.tofile(test_filename)
with open(test_filename, "rb") as f:
bytes = f.read(1)
num = int(bytes.encode('hex'), 1)
print num
Here is the error I get, somehow the bytes.encode thingy excepts a binary string or something of that sort (not sure of course):
ValueError Traceback (most recent call last)
<ipython-input-43-310a447041fe> in <module>()
----> 1 num = int(bytes.encode('hex'), 1)
2 print num
ValueError: int() base must be >= 2 and <= 36
I should state that I would later need to read the output files in C++.
Thanks in advance,
Gil
There is some iffiness to this based on the version of python you are using.
If python2, which I assume you are using because of the print statement, the main problem you have is that you are getting a string from the read, so if the value is say 50 you would get an ascii value of 2 if you print it. You need to tell python that those bits should be in an int type not a str type and a simple cast does not do that.
I personally would use the struct package and do the following:
with open(test_filename, "rb") as f:
bytes = f.read(1)
num = struct.unpack("B", bytes)[0]
print num
Another option would be to encode the string to hex and read it in as a hex string (which looks like is what you are trying):
num = int(bytes.encode("hex_codec"), 16))
print num
One final option would be to put the string in a bytearray and pull the first byte:
num = bytearray(bytes)[0]
print num
If you are actually using python 3 this is simpler because you will get back a bytes object (if so dont name a variable bytes, very confusing). With a bytes object you can just pull the first element out which will be pulled out as an int:
num = bytes[0]
print num
I've a script which reads temperature data:
def get_temp(socket, channels):
data = {}
for ch in channels:
socket.sendall('KRDG? %s\n' % ch)
time.sleep(0.2)
temp = socket.recv(32).rstrip('\r\n')
data[ch] = float(temp)
Sometimes, the script fails on the line which converts the values to float:
File "./projector.py", line 129, in get_temp
data[ch] = float(temp)
ValueError: invalid literal for float(): +135.057E+0
+078.260E+0
+00029
but this is NOT an invalid literal. If I enter this into any python shell,
float(+135.057E+0)
then it correctly returns 135.057.
So what is the problem?
I would all but guarantee that the issue is some sort of non-printing character that's present in the value you pulled off your socket. It looks like you're using Python 2.x, in which case you can check for them with this:
print repr(temp)
You'll likely see something in there that's escaped in the form \x00. These non-printing characters don't show up when you print directly to the console, but their presence is enough to negatively impact the parsing of a string value into a float.
-- Edited for question changes --
It turns this is partly accurate for your issue - the root cause however appears to be that you're reading more information than you expect from your socket or otherwise receiving multiple values. You could do something like
map(float, temp.strip().split('\r\n'))
In order to convert each of the values, but if your function is supposed to return a single float value this is likely to cause confusion. Anyway, the issue certainly revolves around the presence of characters you did not expect to see in the value you retrieved from your socket.
I had a similar issue reading the serial output from a digital scale. I was reading [3:12] out of a 18 characters long output string.
In my case sometimes there is a null character "\x00" (NUL) which magically appears in the scale's reply string and is not printed.
I was getting the error:
> ' 0.00'
> 3 0 fast loop, delta = 10.0 weight = 0.0
> ' 0.00'
> 1 800 fast loop, delta = 10.0 weight = 0.0
> ' 0.00'
> 6 0 fast loop, delta = 10.0 weight = 0.0
> ' 0\x00.0'
> Traceback (most recent call last):
> File "measure_weight_speed.py", line 172, in start
> valueScale = float(answer_string)
> ValueError: invalid literal for float(): 0
After some research I wrote few lines of code that work in my case.
replyScale = scale_port.read(18)
answer = replyScale[3:12]
answer_decode = answer.replace("\x00", "")
answer_strip = str(answer_decode.strip())
print(repr(answer_strip))
valueScale = float(answer_strip)
The answers in these posts helped:
How to get rid of \x00 in my array of bytes?
Invalid literal for float(): 0.000001, how to fix error?
Watch out for possible unintended literals in your argument
for example you can have a space within your argument, rendering it to a string / literal:
float(' 0.33')
After making sure the unintended space did not make it into the argument, I was left with:
float(0.33)
Like this it works like a charm.
Take away is:
Pay Attention for unintended literals (e.g. spaces that you didn't see) within your input.