0

I am having trouble with a python class i wrote, the particular problem is in the parseData() function.

at the end of the function i have commented where the problem is. The problem is that when i finish the inner loop of the code towards the bottom of the parseData() function is run the value of self.listOfParsedWeatherData is correct, however once the scope falls out of the second loop the value of each element in self.listOfParsedWeatherData is a copy of the previous last element.

Basically when i check the value of the list within the scope of the second loop it would be something like [0, 1, 2, 3, 4, 5] but when i check the value of the same list outside of the second loop it it comes up as [5, 5, 5, 5, 5, 5].

I am sure it has something to do with scopes or deep and shallow copies but I'm still fairly new to the python language and I'm not sure of some of the intricacies. Though i doubt the problem is something really complex.

Any help would be greatly appreciated the class is shown below and the object I'm inserting is a simple custom class that i wrote.

# imports
import pywapi                            # used to grab weather data from NOAA in a JSON format
import copy
from WeatherData import WeatherData     # import custom weatherdata object

import pprint 
pp = pprint.PrettyPrinter(indent=4)     # set up pretty printer object

##
## Class used for grabing and parsing weather data from 
## NOAA
##
class NOAAParser:
# initliazer for the NOAAParser class
def __init__(self):
    # stores the list of json city data
    self.listOfCityData = []

    # A list of weatherData
    self.listOfParsedWeatherData = []

##
## function to grab the weather and returns a JSON object of the weather data
##
## Parameters: self, dictionary of cities and their codes
##
def retrieveNOAAWeatherJson(self, cityCodes):
    # loop through city codes and append them to a list of 
    cityData = []

    # weather objects returned from pywapi
    for key, value in cityCodes.iteritems():
        cityData.append(pywapi.get_weather_from_noaa(value))

    # set the list of city json data 
    self.listOfCityData = cityData

##
## This function parses the listOfCityData and returns a list 
## of weatherData objects which can be displayed to the user
##
##
def parseData(self):
    # check if the listOfCities has been populated
    if not self.listOfCityData:
        return False

    else:
        # create a new object of weather data
        newWeatherData = WeatherData()

        # loop over list and parse the data
        for index in range(len(self.listOfCityData)):
            # loop over the dictionary values in the list
            for key, value in self.listOfCityData[index].iteritems():
                # grab weather Description key: "weather" (String)
                if key == "weather":
                    # print value
                    newWeatherData.weatherCondition = value

                # grab the location key: "location" (String)
                if key == "location":
                    # print value
                    newWeatherData.location = value

                # grab temp key: "temperature_string" (String)
                if key == "temperature_string":
                    # print value
                    newWeatherData.currentTemp = value

                # grab Humidity key: "relative_humidity" (Int)
                if key == "relative_humidity":
                    # print value
                    newWeatherData.humidity = value

                # grab wind direction key: "wind_dir" (String)
                if key == "wind_dir":
                    # print value
                    newWeatherData.windDirection = value

                # grab last updated time key: "observation_time" (String)
                if key == "observation_time":
                    # print value
                    newWeatherData.lastUpdated = value

            # append the new weather data object to the list
            self.listOfParsedWeatherData.append(newWeatherData)

            ## VALUE OF self.listOrParsedWeatherData is correct

    ## VALUE OF self.listOfParsedWeatherData is only the value of the last element 
    ## of the previous self.listOfParsedWeatherData (incorrect)

    # return success from the function
    return True
Jake Leveroni
  • 102
  • 1
  • 9

1 Answers1

0

This is happening because you only ever create a single instance of the WeatherData class, so you just keep updating that same one over and over again.

You just need to move the line newWeatherData = WeatherData() inside of your first for loop.

Jeremy Rans
  • 211
  • 1
  • 5
  • Oh wow that makes sense, so when i append the WeatherData object to the list it doesnt create a new copy of that object in the list, rather just a link to that existing weatherData object? – Jake Leveroni Jan 05 '16 at 08:13
  • Exactly, You *could* add a copy of the object to your list using `copy.deepcopy` but the given solution is much better IMO. – Jeremy Rans Jan 05 '16 at 08:15