Cannot convert string due to None Error - python

def draw_constellation_file(file_name):
x = open(file_name)
y = x.read()
y = y.splitlines()
for i in range(0, len(y)):
a = y[i]
b = a.split(',')
aa = str(get_line_for_star_name(b[0]))
cc = get_star_point_from_line(aa)
return aa
get_star_point_from_line looks like this:
def get_star_point_from_line(stardata):
stardata = stardata.split(',')
x = float(stardata[0])
y = float(stardata[1])
return [x, y]
The output:
ValueError: could not convert string to float: None
Here's the thing: the stardata.split doesn't seem to split. I'm sure it has something to do with the None.
Any ideas?

You're passing aa = str(get_line_for_star_name(b[0]))
into get_star_point_from_line(stardata): and that shows you only passing 1 index: b[0].
If b[0] is not a full list and only one string than when you assign x = float(stardata[0])andy = float(stardata[1]) you are trying to assign those variables to indices that dont exist.
If b[0] is a full string it may be splitting up differently than what you thought it would. I would try splitting it using just split() instead of split(',') and then rstrip(',') to get rid of the commas.
Its difficult to pinpoint the problem without knowing what the list looks like when you originally did aa = str(get_line_for_star_name(b[0])). Which by the way is converting that into a string, which you then attempt to reconvert later into a float, which I thought was kind of odd.

It seems there is an error with this code
def get_star_point_from_line(stardata):
stardata = stardata.split(',')
x = float(stardata[0]) //passing string value in float will cause an error
y = float(stardata[1])
return [x, y]
I think the data from the parameter stardata has contained a string value.

in draw_constellation_file, you set b = a.split(',') and pass b[0] to get_line_for_star_name, b[0] will have no ',', so may be you can post the code for get_line_for_star_name to see the reason for the probelm

"None" tends to indicate that nothing is being passed into the function in question. You should make sure that the data you're passing in is what you expect it to be.
In this case, stardata[0] or stardata[1] might not exist. That being said, you need to check the line number to know which one is the problem.

Related

print str and int without "( ' ," in Python with JSON

I am currently working with JSON and Python and I have a problem.
When I write:
x = {}
x['red'] = {'name': "red"}
y = {}
y['red'] = {'p': 1}
z = x['red']['name'], y['red']['p']
print(z)
I get back:
('red', 1)
But I want it like:
red1
Without using
print(x['red']['name'], y['red']['p'])
Thanks for your help :)
When we resolve the variables in the line
z = x['red']['name'], y['red']['p']
we get this:
z = "red", 1
This is, in Python the same as writing:
z = ("red", 1)
This line defines a data-type called a "tuple". It is similar to a list. When you use print to write out the value of this variable, Python formats this as such and adds the parens.
If you want the string "red1" as output, you need to do some minor string processing. In your tuple, your first item is a string, the next is an integer. Those two are not directly concatenable in Python using +. You either need to convert (cast) the number first, or use a string formatting function:
Example 1 - Using str() to cast the number to string
z = x['red']['name'] + str(y['red']['p'])
Example 2 - Using simple string formatting
z = '%s%s' % (x['red']['name'], y['red']['p'])
Example 3 - Using f-strings
z = f"{x['red']['name']}{y['red']['p']}"
Just concatenate the string, easy:
z = y['red']['name'] + str(z['red']['p'])
print(z)
You need to call str() around z['red']['p'] because it's an integer. By converting it to a string, you can then concatenate the two strings into one string
When you type z = x['red']['name'], y['red']['p'] Python automatically takes it as tuple.
But you want this to be treated as string and get concatenated results.
for this you may use,
z = str(x['red']['name']) + str(y['red']['p'])
print(''.join(z)) does the trick.
Cheers
Demo: https://repl.it/repls/MinorRoyalTrace
Edit: use print(''.join(str(element) for element in z)) instead for handle str+ int

get attribute containing a certain string of a named tuple python

is it possible to get the first argument that contain a certain string in a named tuple such has:
import collections
data_line = collections.namedtuple('ex', 'a_1 b_1 a_2')
data = data_line(a_1=10, b_1=11, a_2=10)
getattr(data, 'a_2')
I would like to get the first argument that contain the string 'a', something like:
getattr(data, contains('a'))
any pythonic way to acheive this? thanks!
You can get it done by accessing the fields of the namedtuple and slicing the output to get your desired result:
Either:
[getattr(data, x) for x in data._fields if x.startswith('a')][0]
Or:
getattr(data, [x for x in data._fields if x.startswith('a')][0])
I hope this helps.
Maybe this is not what you want exactly but you can try something like this:
def contains(val):
if val.startswith('a'):
return True
else:
return False
for a in filter(contains, data._fields):
getattr(data, a)
and you may want to have a list of a's:
a_list = list(filter(contains, data._fields))

Accessing dictionary from function in Python

So I'm trying to take variables from one function, and continue to use them in another. I'm getting a KeyError when I try to run this. Any ideas? Cheers!
def find_pos():
x = 1
y = 12
z = 3
return { 'x':x, 'y':y, 'z':z }
def create(x, y, z):
blah = x + y + z
print 'blah'
testReturn = find_pos()
create(testReturn[x], testReturn[y], testReturn[z])
You are trying to access your dictionary by referring to your keys by a variable name that you have not defined. This is incorrect. Your dictionary keys were created using strings 'x', 'y' and 'z'. Therefore, you must access your data in your dictionary as such.
You want to do this:
create(testReturn['x'], testReturn['y'], testReturn['z'])
Better yet, since you seem to be doing some math operations on it, you can even use get instead, which will return None by default if it can't find the key. So, in your case, you can change this default, and set it to 0 instead:
create(testReturn.get('x', 0), testReturn.get('y', 0), testReturn.get('z', 0))

How to add two odd lists into one list in python?

I am very new to Python, and I'm trying to combine elements from two lists and produce a string from the combination.
My variables are:
fro = ['USD']
to = ['AUD', 'CAD', 'EUR']
I want output like this in a string:
pairs = "USDAUD,USDCAD,USDEUR"
Thanks a ton in advance for your help.
Why not use a generator expression like this:
fro = ['USD']
to = ['AUD', 'CAD', 'EUR']
pairs = ','.join(fro[0] + x for x in to)
Note that from is a reserved keyword and is thus not a valid variable name.
Output:
>>>pairs
'USDAUD,USDCAD,USDEUR'
If you were ever curious as to whether something you wish to use as a variable name is a keyword (and thus an illegal variable name) or not, you can always check with something like this:
>>> import keyword
>>> keyword.iskeyword("from")
True
Elizion's answer is nice and succinct, but as a beginner you may want to approach it without using an intermediate/advanced structure like a generator:
fro = ['USD']
to = ['AUD', 'CAD', 'EUR']
pairs = ""
for word in to:
pairs += fro[0] + word + ","
Removing the trailing comma:
pairs = pairs[:-1]
Elizion is absolutely correct.
If you have list elements varies dynamically, you can use this line:
absolutely pythonic way!!
pair_elem = ','.join('%s%s' % (x, y) for y in to for x in fro)
And conventional way is like, iterate list elems:
for multiple in to:
for single in fro:
pairs = ",".join(single + multiple)

Checking an input in python

Basically, I'm asking for an input, which is going to be split(',') however, if the person doesn't input it properly, for example they accidentally input just 5, or don't include a comma at all, it comes up with an error that something is undefined.
Does anyone have any idea of how to check that the input is in the right sort of format?
Edit: Here's the code in question...it's to do with coordinates
def EnterCoords():
coordinates = input("Enter coordinates in the following format x,y").split(',')
x, y = Coordinates[0], Coordinates[1]
I then use the x and y values in a calculation elsewhere, which brings up the error IndexError: list index out of range So, if the user enters them wrong, is there a way of calling the function again, for them to try again
Given your updated question, then the best way is to use a try/except.
def enter_coords():
while True:
try:
# Use `raw_input` for Python 2.x
x, y = input('Enter coordinates ...: ').split(',')
return int(x), int(y) # maybe use `float` here?
except ValueError as e:
pass
Keep looping until a successful return. By using x, y = - you're requesting that only two values should be unpacked (less or more will raise a ValueError), if that succeeds, then you try to return the int equivalent of those values, again, if they're not suitables ints, then you get a ValueError... you then ignore that error and the loop repeats until a successful return executes.
More general approaches and the principles of using this approach are detailed in the excellent: Asking the user for input until they give a valid response
Edit: Just realized you're not looking for alpha only string.
To check for commas use any of the following:
There are multiple ways of solving this problem:
Using in operator
Check for a comma in the string using the in operator:
if "," in str:
<code on true condition>
Example:
In [8]: if "," in "Hello World!":
...: print "Contains Comma"
...:
In [9]: if "," in "Hello,World":
...: print "Contains Comma"
...:
Contains Comma
-OR-
Exception Handling
You could use try ... except block to check for error when ',' is not present in string as suggested by James Taylor.
See documentation for handling exceptions:
https://docs.python.org/2/tutorial/errors.html#handling-exceptions
-OR-
RegEx
As suggested by Malik Brahimi in the comments - "Instead of checking for a specific format, try searching for a specific values":
data = raw_input('Enter a few values: ') # let's say 1, 3, 4.5, 5,
nums = []
for entry in re.findall('[0-9.]+', data):
nums.append(float(entry))
print nums # now just numbers regardless of commas

Categories