can't convert string to integer-python - python

I have a string within a tuple like this:
params': {
'rtinseconds': '57.132',
**'charge': '3+'**,
'pepmass': (822.6547241, None),
title': '20130630_006.d, MS/MS of 822.6547241 3+ at 0.9522 mins'
}
I am trying to read and convert the value of charge '3+' to integer value 3.
I tried the following code where I read the first character in the string and stored it in a separate variable, then tried to convert it to int, but does not work. The type of 3 is still str. Does anyone have any suggestions?
temp_z = item['params']['charge']
z = temp_z[0:1]
str(z)
int(z)

In the simple case:
z = int(params['charge'].replace('+',''))
However if it is possible that your item may have a negative charge you may want:
if '+' in params['charge']:
z = int(params['charge'].replace('+',''))
else:
z = -int(params['charge'].replace('-',''))

Related

Python ValueError: could not convert string to float

I have the code below, where the input is h_ply =['0.12, 0.15, 0.2, 0.125']
h_ply = simpledialog.askstring('Laminate Properties','Ply Thickness')
try:
h_layer_list = [int(x) for x in h_ply.split(',')]
h_layer = np.array(h_layer_list) * 0.001
I have also tried
h_ply1 = np.array(h_ply)
h_layer = h_ply1.astype(np.float)
But got the same error.
I am trying to get h_ply list into a np.array of Floats. But a ValueError appears.
I understand this could be because I should have '' every number and not just at the ends? But ideally I want to avoid that to be more user friendly. What is the best way to get rid of this Error message?
Thank you
The way to deal with this is to properly access the string. Look at your data:
h_ply =( # a tuple, containing ...
[ # a single element, a list, containing ...
[ # a single element, a list, containing ...
'0.12, 0.15, 0.2, 0.125' # ... a string that you have to split
]
]
)
You have to peel off all of those layers to get to the string:
h_str = h_ply[0][0][0]
Now you can split the string and convert the elements to numeric values. The code you posted is trying to split the tuple and convert it.

Format French number into English number - Python

I need to convert French formatted numbers extracted from .csv into English formatted numbers so I can use dataframe functions. The .csv gives:
Beta Alpha
2014-07-31 100 100
2014-08-01 99,55 100,01336806
2014-08-04 99,33 100,05348297
2014-08-05 99,63 100,06685818
2014-08-06 98,91 100,08023518
"99,5" & "100,01336806" are actually objects for python.
I need to turn them into floats with the following format "99.5" and "100.01336806"
I tried:
df = df.str.replace(to_replace =',', value = '.', case = False)
Doesn't give my any error for that code line but doesn't switch the ',' into '.' either.
df = pd.to_numeric(df, error = 'coerce')
TypeError: arg must be a list, tuple, 1-d array, or Series
Also tried the regex module without success, and I would rather use built-in function if possible.
Any help welcome!
What is the type of sources objects are "99,5" & "100,01336806", and what type of target objects do you want ?
The following tested with Python 3.8
Case 1: source object is numeric, target is string. Formatting do not allow "French format", only "English". So have to substitute . and ,
Eg. (float) 99.55 -> (string) '99,55'
v1 = float(99.55)
f"{v1:,.2f}"
'99.55'
f"{v1:,.2f}".replace(".",",")
'99,55'
Case 2: source is string with "English" format, target is float. Means the , must be replaced by a . first before converting the string to float
Eg. (string) '99,55' -> (float) 99.55
v2 = "99,55"
float(v2.replace(",","."))
99.55
try using the replace() function.
x = "100,01336806"
y = x.replace(",",".")
print(y)

Comparing string including decimal in Python

I have question here:
How do I compare variable that has string+decimal in Python.
Example :
a = "2.11.22-abc-def-ghi"
if a == (2.11*) :
print "ok"
I want it only compare the first 2 decimal point only and it doesn't care the rest of it value. How can I do that?
Thanks
Here's the most direct answer to your question, I think...a way to code what your pseudocode is getting at:
a = "2.11.22-abc-def-ghi"
if a.startswith("2.11"):
print("ok")
If you want to grab the numeric value off the front, turn it into a true number, and use that in a comparison, no matter what the specific value, you could do this:
import re
a = "2.11.22-abc-def-ghi"
m = re.match(r"(\d+\.\d+).*", a)
if m:
f = float(m.group(1))
if (f == 2.11):
print("ok")
If you want to compare part of a string, you can always slice it with the syntax str[start_index: end_index] and then compare the slice. Please note the start_index is inclusive and end_index is exclusive. For example
name = "Eric Johnson"
name[0:3] #value of the slice is "Eri" no "Eric".
in your case, you can do
if a[0:4] == "2.11":
#stuff next

Iterating a conversion of a string to a float in a scripting file when parsing an old file

I am using a new script (a) to extract information from an old script (b) to create a new file (c). I am looking for an equal sign in the old script (b) and want to modify the modification script (a) to make it automated.
The string is
lev1tolev2 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
It is written in python 3.
The current output is fixed at
cam2map from=e119-b3331l1 to=rsmap-x map=enc.Ink.map pixres=mpp defaultrange=MAP res=300 minlat=-71.5 maxlat=90 minlon=220 maxlon=360
Currently, I have the code able to export a string of 0.6 for all of the iterations of lev1tolev2, but each one of these is going to be different.
cam2map = Call("cam2map")
cam2map.kwargs["from"] = old_lev1tolev2.kwargs["from"]
cam2map.kwargs["to"] = "rsmap-x"
cam2map.kwargs["map"] = "enc.Ink.map"
cam2map.kwargs["pixres"] = "mpp"
cam2map.kwargs["defaultrange"] = "MAP"
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
cam2map.kwargs["minlat"] = lat[0]
cam2map.kwargs["maxlat"] = lat[1]
cam2map.kwargs["minlon"] = lon[0]
cam2map.kwargs["maxlon"] = lon[1]
I have two questions, why is this not converting the string to a float? And, why is this not iterating over all of the lev1tolev2 commands as everything else in the code does?
The full code is available here.
https://codeshare.io/G6drmk
The problem occurred at a different location in the code.
def escape_kw_value(value):
if not isinstance(value, str):
return value
elif (value.startswith(('"', "'")) and value.endswith(('"', "'"))):
return value
# TODO escape the quote with \" or \'
#if value.startswith(('"', "'")) or value.endswith(('"', "'")):
# return value
if " " in value:
value = '"{}"'.format(value)
return value
it doesn't seem to clear to me, but from you syntax here :
**cam2map.kwargs["res"] = float((old_lev1tolev2.kwargs["km"]))**
I'd bet that cam2map.kwargs["res"] is a dict, and you thought that it would convert every values in the dict, using the ** syntax. The float built-in should then be called in a loop over the elements of the dict, or possible a list-comprehension as here :
cam2map.kwargs["res"] = dict()
for key, value in old_lev1tolev2.kwars["res"].items():
cam2map.kwargs["res"][key] = float(value)
Edit :
Ok so, it seems you took the string 'from=e119-b3331l1 mappars="simp:180" targ=enceladus.bi.def.3 km=0.6 lat=(-71.5,90) lon=(220,360)'
And then thought that calling youstring.kwargs would give you a dict, but it won't, you can probably parse it to a dict first, using some lib, or, you use mystring.split('=') and then work your way to a dict first, like that:
output = dict()
for one_bit in lev_1_lev2.split(' '):
key, value = one_bit.split('=')
output[key] = value

TypeError: tuple indices must be integers or slices, not str

I need to make a function that updates tuples in a list of tuples. The tuples contain transactions, which are characterised by ammount, day, and type. I made this function that should completely replace a tuple with a new one, but when I try to print the updated list of tuples I get the error:
TypeError: tuple indices must be integers or slices, not str
The code:
def addtransaction(transactions, ammount, day, type):
newtransactions = {
"Ammount": ammount,
"Day": day,
"Type": type
}
transactions.append(newtransaction)
def show_addtransaction(transactions):
Ammount = float(input("Ammount: "))
Day = input("Day: ")
Type = input("Type: ")
addtransaction(transactions, ammount, day, type)
def show_all_transaction(transactions):
print()
for i, transaction in enumerate(transactions):
print("{0}. Transaction with the ammount of {1} on day {2} of type: {3}".format(
i + 1,
transaction['Ammount'], ; Here is where the error occurs.
transaction['Day'],
transaction['Type']))
def update_transaction(transactions): ; "transactions" is the list of tuples
x = input("Pick a transaction by index:")
a = float(input("Choose a new ammount:"))
b = input("Choose a new day:")
c = input("Choose a new type:")
i = x
transactions[int(i)] = (a, b, c)
addtransaction(transactions, 1, 2, service)
show_all_transaction(transactions)
update_transaction(transactions)
show_all_transaction(transactions)
A tuple is basically only a list, with the difference that in a tuple you cannot overwrite a value in it without creating a new tuple.
This means you can only access each value by an index starting at 0, like transactions[0][0].
But as it appears you should actually use a dict in the first place. So you need to rewrite update_transaction to actually create a dict similar to how addtransaction works. But instead of adding the new transaction to the end you just need to overwrite the transaction at the given index.
This is what update_transaction already does, but it overwrites it with a tuple and not a dict. And when you print it out, it cannot handle that and causes this error.
Original answer (Before I knew the other functions)
If you want to use strings as indexes you need to use a dict. Alternatively you can use namedtuple which are like tuples but it also has an attribute for each value with the name you defined before. So in your case it would be something like:
from collections import namedtuple
Transaction = namedtuple("Transaction", "amount day type")
The names given by the string used to create Transaction and separated by spaces or commas (or both). You can create transactions by simply calling that new object. And accessing either by index or name.
new_transaction = Transaction(the_amount, the_day, the_type)
print(new_transaction[0])
print(new_transaction.amount)
Please note that doing new_transaction["amount"] will still not work.
This is not a generic answer, I'll just mention it if someone bumps into the same problem.
As stated before, tuples are addressed by integer e.g. my_tuple[int] or slice my_tuple[int1:int2].
I ran into trouble when I ported code from Python2 to Python3. The original code used somthing like my_tuple[int1/int2], this worked in Python2 since division int/int results in int.
in Python3 int/int results in a floating point number.
I had to fix the code to my_tuple[int1//int2] to get the python2 behavior.

Categories

Resources