Error when passing list of float values to function - python

Unsupported operand type(s) for -: 'str' and 'str'
I am passing two lists to a functions to find the starting distance,ending distance ,starting time, ending time using sesnor data. when the list contains only integer values, it doesn't throw any error and works fine but when i tried to convert the list to floating value , its showing an error
x = ["%.2f"%(b*1000) for b in t] # t is a list of time values
y = [c*0.002 for c in values]# values is a list of sensor values
z = ["%.2f"%(d*48.484) for d in y]
p1,t1 = min_distance(z,x)
p2,t2 = max_distance(z,x)
def min_distance(self,z,x):
count = True
i = 0
while count and (i+1) !=len(z):
if abs(z[i] - z[i+1]) >= 1:
count = False
else:
i +=1
min_value = z[i])
min_time = x[i])
return min_value,min_time
def max_distance(self,z,x):
count = 0
j = 1
while count<20:
if abs(z[-j] - z[-j-1]) >=1:
count +=1
else:
j +=1
max_value = z[-j+20]
max_time = x[-j+20]
return max_value,max_time

x, y and z are arrays of strings, not integers or floats. You are creating them using string substitution, which inserts and formats a float value but results in a string.
To ensure you get a float, ensure either that b and c are floats, or force the integer to a float by adding a decimal point. For example, if b is an integer, b*1000 will result in an integer, but b*1000.0 or float(b*1000) will give a float
Try, for example: x = [b*1000 for b in t] and so on then format any resulting string (like you had done) only when you need output visible to the user.

Related

Issue with turning tuple entry variables into an int for a math problem

currently I've been trying to have my tuple variables: tempLentry,windLentry,dewpointLentry, be converted into an integer so I can use them in the math sequence. However I keep getting this error whenever it happens: TypeError: int() argument must be a string, a bytes-like object or a real number, not 'Entry'. I was hoping someone could point in the right direction, Thank you!
The code is below
def calc ():
#Tuple being recieved from askUser
tempLentry,windLentry,dewpointLentry = askUser()
#Converts string input from entries to integers for the calculations to work.
t = int(tempLentry)
ws = int(windLentry)
dp = int(dewpointLentry)
#Checks to see if inputed data for temperature and windspeed is less than 50mph and
greater than 3 mph
if (t < 50 and ws > 3):
windchill = (35.74 + 0.6215 * t - (35.75 * math.pow(ws,0.16)) + (0.4275 * t * math.pow(ws,0.16)))
else:
windchill = 0
You need to first convert the Entry to a string, and then cast it to an int.
You can get the Entry as a string by using .get()
t = int(tempLentry.get())
ws = int(windLentry.get())
dp = int(dewpointLentry.get())

int 111 to binary 111(decimal 7)

Problem:Take a number example 37 is (binary 100101).
Count the binary 1s and create a binary like (111) and print the decimal of that binary(7)
num = bin(int(input()))
st = str(num)
count=0
for i in st:
if i == "1":
count +=1
del st
vt = ""
for i in range(count):
vt = vt + "1"
vt = int(vt)
print(vt)
I am a newbie and stuck here.
I wouldn't recommend your approach, but to show where you went wrong:
num = bin(int(input()))
st = str(num)
count = 0
for i in st:
if i == "1":
count += 1
del st
# start the string representation of the binary value correctly
vt = "0b"
for i in range(count):
vt = vt + "1"
# tell the `int()` function that it should consider the string as a binary number (base 2)
vt = int(vt, 2)
print(vt)
Note that the code below does the exact same thing as yours, but a bit more concisely so:
ones = bin(int(input())).count('1')
vt = int('0b' + '1' * ones, 2)
print(vt)
It uses the standard method count() on the string to get the number of ones in ones and it uses Python's ability to repeat a string a number of times using the multiplication operator *.
Try this once you got the required binary.
def binaryToDecimal(binary):
binary1 = binary
decimal, i, n = 0, 0, 0
while(binary != 0):
dec = binary % 10
decimal = decimal + dec * pow(2, i)
binary = binary//10
i += 1
print(decimal)
In one line:
print(int(format(int(input()), 'b').count('1') * '1', 2))
Let's break it down, inside out:
format(int(input()), 'b')
This built-in function takes an integer number from the input, and returns a formatted string according to the Format Specification Mini-Language. In this case, the argument 'b' gives us a binary format.
Then, we have
.count('1')
This str method returns the total number of occurrences of '1' in the string returned by the format function.
In Python, you can multiply a string times a number to get the same string repeatedly concatenated n times:
x = 'a' * 3
print(x) # prints 'aaa'
Thus, if we take the number returned by the count method and multiply it by the string '1' we get a string that only contains ones and only the same amount of ones as our original input number in binary. Now, we can express this number in binary by casting it in base 2, like this:
int(number_string, 2)
So, we have
int(format(int(input()), 'b').count('1') * '1', 2)
Finally, let's print the whole thing:
print(int(format(int(input()), 'b').count('1') * '1', 2))

Python internal metric unit conversion function

I'm trying to build a function to do internal metric conversion on a wavelength to frequency conversion program and have been having a hard time getting it to behave properly. It is super slow and will not assign the correct labels to the output. If anyone can help with either a different method of computing this or a reason on why this is happening and any fixes that I cond do that would be amazing!
def convert_SI_l(n):
if n in range( int(1e-12),int(9e-11)):
return n/0.000000000001, 'pm'
else:
if n in range(int(1e-10),int(9e-8)):
return n/0.000000001 , 'nm'
else:
if n in range(int(1e-7),int(9e-5)):
return n/0.000001, 'um'
else:
if n in range(int(1e-4),int(9e-3)):
return n/0.001, 'mm'
else:
if n in range(int(0.01), int(0.99)):
return n/0.01, 'cm'
else:
if n in range(1,999):
return n/1000, 'm'
else:
if n in range(1000,299792459):
return n/1000, 'km'
else:
return n , 'm'
def convert_SI_f(n):
if n in range( 1,999):
return n, 'Hz'
else:
if n in range(1000,999999):
return n/1000 , 'kHz'
else:
if n in range(int(1e6),999999999):
return n/1e6, 'MHz'
else:
if n in range(int(1e9),int(1e13)):
return n/1e9, 'GHz'
else:
return n, 'Hz'
c=299792458
i=input("Are we starting with a frequency or a wavelength? ( F / L ): ")
#Error statements
if i.lower() == ("f"):
True
else:
if not i.lower() == ("l"):
print ("Error invalid input")
#Cases
if i.lower() == ("f"):
f = float(input("Please input frequency (in Hz): "))
size_l = c/f
print(convert_SI_l(size_l))
if i.lower() == ("l"):
l = float(input("Please input wavelength (in meters): "))
size_f = ( l/c)
print(convert_SI_f(size_f))
You are using range() in a way that is close to how it is used in natural language, to express a contiguous segment of the real number line, as in in the range 4.5 to 5.25. But range() doesn't mean that in Python. It means a bunch of integers. So your floating-point values, even if they are in the range you specify, will not occur in the bunch of integers that the range() function generates.
Your first test is
if n in range( int(1e-12),int(9e-11)):
and I am guessing you wrote it like this because what you actually wanted was range(1e-12, 9e-11) but you got TypeError: 'float' object cannot be interpreted as an integer.
But if you do this at the interpreter prompt
>>> range(int(1e-12),int(9e-11))
range(0, 0)
>>> list(range(int(1e-12),int(9e-11)))
[]
you will see it means something quite different to what you obviously expect.
To test if a floating-point number falls in a given range do
if lower-bound <= mynumber <= upper-bound:
You don't need ranges and your logic will be more robust if you base it on fixed threshold points that delimit the unit magnitude. This would typically be a unit of one in the given scale.
Here's a generalized approach to all unit scale determination:
SI_Length = [ (1/1000000000000,"pm"),
(1/1000000000, "nm"),
(1/1000000, "um"),
(1/1000, "mm"),
(1/100, "cm"),
(1, "m"),
(1000, "km") ]
SI_Frequency = [ (1, "Hz"), (1000,"kHz"), (1000000,"MHz"), (1000000000,"GHz")]
def convert(n,units):
useFactor,useName = units[0]
for factor,name in units:
if n >= factor : useFactor,useName = factor,name
return (n/useFactor,useName)
print(convert(0.0035,SI_Length)) # 3.5 mm
print(convert(12332.55,SI_Frequency)) # 12.33255 kHz
Each unit array must be in order of smallest to largest multiplier.
EDIT: Actually, range is a function which is generally used in itaration to generate numbers. So, when you write if n in range(min_value, max_value), this function generates all integers until it finds a match or reach the max_value.
The range type represents an immutable sequence of numbers and is commonly used for looping a specific number of times in for loops.
Instead of writing:
if n in range(int(1e-10),int(9e-8)):
return n/0.000000001 , 'nm'
you should write:
if 1e-10 <= n < 9e-8:
return n/0.000000001 , 'nm'
Also keep in mind that range only works on integers, not float.
More EDIT:
For your specific use case, you can define dictionary of *(value, symbol) pairs, like below:
import collections
symbols = collections.OrderedDict(
[(1e-12, u'p'),
(1e-9, u'n'),
(1e-6, u'μ'),
(1e-3, u'm'),
(1e-2, u'c'),
(1e-1, u'd'),
(1e0, u''),
(1e1, u'da'),
(1e2, u'h'),
(1e3, u'k'),
(1e6, u'M'),
(1e9, u'G'),
(1e12, u'T')])
The use the bisect.bisect function to find the "insertion" point of your value in that ordered collection. This insertion point can be used to get the simplified value and the SI symbol to use.
For instance:
import bisect
def convert_to_si(value):
if value < 0:
value, symbol = convert_to_si(-value)
return -value, symbol
elif value > 0:
orders = list(symbols.keys())
order_index = bisect.bisect(orders, value / 10.0)
order = orders[min(order_index, len(orders) - 1)]
return value / order, symbols[order]
else:
return value, u""
Demonstration:
for value in [1e-12, 3.14e-11, 0, 2, 20, 3e+9]:
print(*convert_to_si(value), sep="")
You get:
1.0p
0.0314n
0
2.0
2.0da
3.0G
You can adapt this function to your needs…

Read specific Bits from bitstring.BitArray

I have a Bitarray and want to read from a certain position to another position.
I have the int variable length in a for loop, so for example I have:
length = 2
and my Bitarray looks something like:
msgstr = bitstring.BitArray(0b11110011001111110)
I then want to read the first two bits and convert them into an int, so that I have:
id == 3
And for the next round when length has changed in value it should start from the third bit etc.
id = bitstring.BitArray()
m = 0
while 5 != m:
/////////////
Length changes in value part of Code
/////////////
x = 0
if m == 0:
while length != x:
id.append = msgstr[x] #msgstr is the BitArray that needs to be read
x = x + 1
m = m + 1
What you want here is called slicing.
for i in range(0,len(msgstr),length):
print msgstr[i:i+length].uint
This code will get you what you are asking for. It will take the first two bits and convert them into an int, then will take the third and fourth bits and convert them to an int, etc.

Sound echo function Python

I need to write the function echo, that takes in a filename as and a floating-point value time_delay, which represents a number of seconds.Then, echo should handle the sound, with the original sound being overlaid by a copy of itself shifted forward in time by time_delay.
This is what I have so far:
def add_scale_2(L, M, L_scale, M_scale):
""" add_scale_2 has as intput list L and list M and rertuns a new list LC,
with a linear sum of the two lists times their scale respectively. LC will use the length of the
shortest list
"""
if len(L) >= len (M):
N = len(M)
else:
N = len(L)
LC = [L[i]*L_scale + M[i]*M_scale for i in range(N)]
return LC
And:
def echo(filename, time_delay):
print "Playing filename1 ..."
play(filename)
print "Reading in the sound data..."
samps1, sr = readwav(filename)
samps2 = [0]*float(samps1*time_delay) + samps1
print "Computing new sound..."
newsamps = add_scale_2(samps1, samps2, 0.5, 0.5)
newsr = sr # no change to the sr
writewav( newsamps, newsr, "out.wav" )
print "Playing new sound..."
play( 'out.wav' )
Can someone help me please because I can't figure it out!
samps2 = [0]*int(samps1*time_delay) + samps1
TypeError: can't multiply sequence by non-int of type 'float'
Your line:
[0]*float(samps1*time_delay) + samps1
tries to multiply a sequence [0] by a float. Which lead to error TypeError: can't multiply sequence by non-int of type 'float'
You can cast to an int instead:
[0]*int(len(samps1)*time_delay) + samps1

Categories