I have a script which consumes an API of bus location, I am attempting to parse the lat/lng fields which are float objects. I am repeatedly receiving this error.
row.append(Decimal(items['longitude'].encode('utf-16')))
AttributeError: 'float' object has no attribute 'encode'
# IMPORTS
from decimal import *
#Make Python understand how to read things on the Internet
import urllib2
#Make Python understand the stuff in a page on the Internet is JSON
import simplejson as json
from decimal import Decimal
# Make Python understand csvs
import csv
# Make Python know how to take a break so we don't hammer API and exceed rate limit
from time import sleep
# tell computer where to put CSV
outfile_path='C:\Users\Geoffrey\Desktop\pycharm1.csv'
# open it up, the w means we will write to it
writer = csv.writer(open(outfile_path, 'wb'))
#create a list with headings for our columns
headers = ['latitude', 'longitude']
#write the row of headings to our CSV file
writer.writerow(headers)
# GET JSON AND PARSE IT INTO DICTIONARY
# We need a loop because we have to do this for every JSON file we grab
#set a counter telling us how many times we've gone through the loop, this is the first time, so we'll set it at 1
i=1
#loop through pages of JSON returned, 100 is an arbitrary number
while i<100:
#print out what number loop we are on, which will make it easier to track down problems when they appear
print i
#create the URL of the JSON file we want. We search for 'egypt', want English tweets,
#and set the number of tweets per JSON file to the max of 100, so we have to do as little looping as possible
url = urllib2.Request('http://api.metro.net/agencies/lametro/vehicles' + str(i))
#use the JSON library to turn this file into a Pythonic data structure
parsed_json = json.load(urllib2.urlopen('http://api.metro.net/agencies/lametro/vehicles'))
#now you have a giant dictionary.
#Type in parsed_json here to get a better look at this.
#You'll see the bulk of the content is contained inside the value that goes with the key, or label "results".
#Refer to results as an index. Just like list[1] refers to the second item in a list,
#dict['results'] refers to values associated with the key 'results'.
print parsed_json
#run through each item in results, and jump to an item in that dictionary, ex: the text of the tweet
for items in parsed_json['items']:
#initialize the row
row = []
#add every 'cell' to the row list, identifying the item just like an index in a list
#if latitude is not None:
#latitude = str(latitude)
#if longitude is not None:
#longitude = str(longitude)
row.append(Decimal(items['longitude'].encode('utf-16')))
row.append(Decimal(items['latitude'].encode('utf-16')))
#row.append(bool(services['predictable'].unicode('utf-8')))
#once you have all the cells in there, write the row to your csv
writer.writerow(row)
#increment our loop counter, now we're on the next time through the loop
i = i +1
#tell Python to rest for 5 secs, so we don't exceed our rate limit
sleep(5)
encode is available only for string. In your case item['longitude'] is a float. float doesn't have encode method. You can type case it and then use encode.
You can write like,
str(items['longitude']).encode('utf-16')
str(items['latitude']).encode('utf-16')
I think you can't pass an encoded string to Decimal object.
encode is a method that strings have, not floats.
Change row.append(Decimal(items['longitude'].encode('utf-16'))) to row.append(Decimal(str(items['longitude']).encode('utf-16'))) and similar with the other line.
Related
I'm trying to extract list of names from json file called WW_trend, which contains a dict called trends, with a list of all the trending topics from X period of time
world_trends = set([... for trend in ...])
this code chunk is what im supposed to use (start from basically i dont know what im supposed to add)
world_trends = set([name for trend in WW_trends:
name = trend['name']])
I tried this but I get back invalid syntax.
Correct code would be:
world_trends = set()
for trend in WW_trends:
try:
world_trends.add(trend['name'])
except:
pass
I am pulling 10 tweets from Twitter using tweepy and storing it in a CSV for later displaying it on the front-end webpage. My code refreshes every 60 minutes, and at certain times I get the "IndexError".
Following is the exact error:
return ks[5]
IndexError: List index out of range
Following is the function to retrieve the particular tweet from CSV:
def tweet6(self):
with codecs.open('HELLOTWITTER.csv', 'r', encoding='utf-8', errors='ignore') as f:
reader = csv.reader(f)
d = {}
for i, row in enumerate(reader):
d[row[0]]=row[1:]
if (i>=10):
break
ks=list(d)
return (ks[5])
This error occurs only at times but I am unable to figure out why it happens although the CSV has all the 10 tweets written into it every time the entire code is refreshed.
Also, if I run the code once more, the error disappears and the webpage loads without any issues with the tweets, surprisingly!
What am I missing?
Any help is much appreciated! Thanks!
As Ken White pointed out in the comments above. The error is caused by you trying to access an index that is outside the bounds of the list.
What is going on is that there is a blank row in your CSV file that python cannot process because you are calling index 0 even though it does not exist therefore python throws an exception.
In order to fix this error what you need to do is check if there are enough elements in the list to run your code. By using
if(len(row) < 1):
continue
Another place that could be causing problems is where you are taking the list d and putting it inside another list ks. Then you try to return the 5th object in the new list. However, there is no object because you now have a list that looks like this
ks={{tweet,tweetyouwant,tweet},{list,two,if,present}}
When you were expecting the list to look like this
ks={tweet,tweetyouwant,tweet}
In order to fix this simply get rid of ks=list(d) and call d wherever you would call ks
Your whole snippet should like this.
def tweet6(self):
with codecs.open('HELLOTWITTER.csv', 'r', encoding='utf-8', errors='ignore') as f:
reader = csv.reader(f)
d = {}
for i, row in enumerate(reader):
#Verify row is within range
if(len(row) < 1):
continue
#Get the rows values
d[row[0]]=row[1:]
#If past row 10 then break
if (i>=10):
break
#ks=list(d) #Not needed D is already a list
return (d[5]) #return the row of the 6th tweet
I've been assigned a task to log student scores for a maths quiz
Below is my task:
The teacher wants to use the results from students taking these quizzes to log their performance. The system should store >the last three scores for each student.
every time I run my code I receive the error:
AttributeError: 'str' object has no attribute 'append'
and when I convert into an int I get this error:
int() argument must be a string, a bytes-like object or a number, not 'NoneType'
import csv
import os
name = input("enter your name: ")
classroom_num = input("enter your classroom number: ")
score = 5
print ("%s, you scored %d/10 questions correctly"%(name,score))
status = open ("state.txt","w") #Every time program is run +1 is added, so that column 1-3 are updated
with open ("state.txt","r") as f:
state = f.read()
if os.stat("state.txt").st_size == 0:
status.write ("0")
state_ints = [ int(x) for x in state.split() ] #converts into int
addone = 1
if state_ints == 3: #If program is run more than 3 times the value in text file reset to 0
state_ints = 0
status.write (state_ints)
with open("Classroom {}.csv".format(classroom_num),"a+") as f:
rows = csv.reader(f)
for row in rows:
if row in rows in row[0] != (name) in row: #Checks if name exists in file (if so name isn't appended to column)
state_ints.append(addone) #Adds one everytime program is run so that score can be replaced for row 1-3
status.write (state_ints)
name_row = (row [0])
name_row.append(name)
score_row = (row (state_ints))
score_row.append(score)
else:
state_ints.append(addone)
status.write (state_ints)
score_row = (row [state_ints])
score_row.append(score)
status.close()
Also what other mistakes might I have made? What can I do to make this more efficient and complete this task?
A string is immutable. You can't change it. You need to make a new string or create a list and make a string of the list when you are done. Also int needs a string of a number to convert. A None type object is a variable with value None. int can't convert None to an integer so you get an error.
The line for row in ("Classroom {}.csv".format(classroom_num)): is iterating over a string, not a file. For each iteration, row is a single character string ('C' then 'l' etc).
row[0] is therefore the same as row and name_row.append(... is trying to call append on a string, hence the "'str' object has no attribute 'append'" error.
I can't see the int() call that's failing but the line state_ints = state_ints.append(addone) is setting state_ints to None. append modifies the list in place and returns None. You just want state_ints.append(addone).
There are several other problems as well that suggest you might want to review a tutorial
Putting a single item in brackets does nothing (an_object) is exactly the same as an_object.
row [state_ints] is trying to use a list as an index (assuming you didn't mean to set it to None
)
status.close should be a method call
if state_ints == 3: state_ints is a list at this point. It's never going to equal 3
etc
See what's going on here?
>>> for row in ("Classroom {}.csv".format("2")):
... print row
...
C
l
a
s
s
r
o
o
m
2
.
c
s
v
>>>
You're not actually opening the file called "Classroom[number].csv" but, instead, you're iterating the characters in the file name.
You can normally use append on the rows of a csv since they are typically transformed into lists (either manually via split(",") or via the csv module) but it fails here since your rows are, in fact, not rows/lists but characters/strings.
You can use with open and manually split by comma or use the csv module for parsing the file. The module approach:
>>> import csv
>>>
>>> with open("Classroom {}.csv".format(classroom_num),"r") as f:
... rows = csv.reader(f)
... for row in rows:
... print(row)
You keep re-using the file handle f when opening files. You also use both with open() and f = open (...). This means that you might be trying to open the same file twice, read from a file you've opened in "append"-mode or other confusing/conflicting actions. Simply stick to With open() - that way, you won't have to manually close the files either.
Simple question: i've got this code:
i want to fetch a row with Dictreader from the csv package, every entry i wanto to cast it float and put it in the data array. At the end of the scanning i want to print the first 10 elements of the array. It gives me error of visibility on the array data.
with open(train, "r") as traincsv:
trainreader = csv.DictReader(traincsv)
for row in trainreader:
data = [float(row['Sales'])]
print(data[:10])
If i put the print inside the for like this
with open(train, "r") as traincsv:
trainreader = csv.DictReader(traincsv)
for row in trainreader:
data = [float(row['Sales'])]
print(data[:10])
It prints all the entries not just 10.
You are overwriting data every time in the for loop. This is the source of your problem.
Please upload an example input for me to try and I will, but I believe what is below will fix your problem, by appending to data instead of overwriting it.
Also, it is good practice to leave the with block as soon as possible.
# Open with block and leave immediately
with open(train, "r") as traincsv:
trainreader = csv.DictReader(traincsv)
# Declare data as a blank list before iterations
data =[]
# Iterate through all of trainreader
for row in trainreader:
data.append([float(row['Sales'])])
# Now it should print first 10 results
print(data[:10])
Ways of appending a list:
data = data + [float(row['Sales'])]
data += [float(row['Sales'])]
data.append([float(row['Sales'])]
I was writing a code to find the average household income, and how many families are below poverty line.
this is my code so far
def povertyLevel():
inFile = open('program10.txt', 'r')
outFile = open('program10-out.txt', 'w')
outFile.write(str("%12s %12s %15s\n" % ("Account #", "Income", "Members")))
lineRead = inFile.readline() # Read first record
while lineRead != '': # While there are more records
words = lineRead.split() # Split the records into substrings
acctNum = int(words[0]) # Convert first substring to integer
annualIncome = float(words[1]) # Convert second substring to float
members = int(words[2]) # Convert third substring to integer
outFile.write(str("%10d %15.2f %10d\n" % (acctNum, annualIncome, members)))
lineRead = inFile.readline() # Read next record
# Close the file.
inFile.close() # Close file
Call the main function.
povertyLevel()
I am trying to find the average of annualIncome and what i tried to do was
avgIncome = (sum(annualIncome)/len(annualIncome))
outFile.write(avgIncome)
i did this inside the while lineRead. however it gave me an error saying
avgIncome = (sum(annualIncome)/len(annualIncome))
TypeError: 'float' object is not iterable
currently i am trying to find which household that exceeds the average income.
avgIncome expects a sequence (such as a list) (Thanks for the correction, Magenta Nova.), but its argument annualIncome is a float:
annualIncome = float(words[1])
It seems to me you want to build up a list:
allIncomes = []
while lineRead != '':
...
allIncomes.append(annualIncome)
averageInc = avgIncome(allIncomes)
(Note that I have one less indentation level for the avgIncome call.)
Also, once you get this working, I highly recommend a trip over to https://codereview.stackexchange.com/. You could get a lot of feedback on ways to improve this.
Edit:
In light of your edits, my advice still stands. You need to first compute the average before you can do comparisons. Once you have the average, you will need to loop over the data again to compare each income. Note: I advise saving the data somehow for the second loop, instead of reparsing the file. (You may even wish to separate reading the data from computing the average entirely.) That might best be accomplished with a new object or a namedtuple or a dict.
sum() and len() both take as their arguments an iterable. read the python documentation for more on iterables. you are passing a float into them as an argument. what would it mean to get the sum, or the length, of a floating point number? even thinking outside the world of coding, it's hard to make sense of that.
it seems like you need to review the basics of python types.