python 使用类打开excelcsv文件,并根据特定列中的最大权重返回值

bogh5gae  于 2023-05-05  发布在  Python
关注(0)|答案(1)|浏览(78)

我得到了这个包含函数的类文件:

import csv
import warnings
from datetime import date

conv_fn = {
    'name': str,
    'country': str,
    'operator': str,
    'users': str,
    'purpose': str,
    'perigee': float,
    'apogee': float,
    'eccentricity': float,
    'launch_mass': float,
    'date_of_launch': date.fromisoformat,
    'expected_lifetime': float
    }

def warn_caller(message: str, category=None, stacklevel=3):
    """Wrapper around UserWarning that has stacklevel of 3"""
    warnings.warn(message, category, stacklevel)

def simple_format(message, category, filename, lineno, line=None):
    if line is None:
        import linecache
        line = linecache.getline(filename, lineno).strip()
        
    return (
        "SatDB Warning:\n"
        f"  File: \"{filename}\", line {lineno}\n    {line}" 
        f"\n{category.__name__}: {message}\n"
    )

warnings.formatwarning = simple_format
# NOTE: For testing, use warnings.simplefilter("ignore")

class SatDB(object):
    """Class to provide interaction with a satellite database.

    Methods
    -------
    get_number_of_satellites
    get_sat_data
    add_field_of_data
    """
    
    def __init__(self, filename):
        """Construct a SatDB object.

        Parameters
        ----------
        filename : string
           A CSV file with data for satellites.
        """
        with open(filename, 'r') as sat_csv_file:
            data_list = list(csv.reader(sat_csv_file, delimiter=','))
        # parse header to get fields in data file
        self._fields = data_list[0].copy()
        self._fields.pop() # remove trailing empty field
        # assemble data as list of dictionaries, each dictionary represents satellite data
        self._data = []
        for row in data_list[1:]:
            self._data.append({})
            for pos, field in enumerate(self._fields):
                self._data[-1][field] = conv_fn[field](row[pos])

    def get_number_satellites(self):
        """Returns the number of satellites in the database."""
        return len(self._data)

    def get_sat_data(self, idx, fields):
        """Returns a selection of data for a given satellite.

        The caller provides a satellite id and list of fields.
        The method returns data associated with those fields for the given satellite.
        If the satellite is not present in database, or a specific field is not available,
        then an empty tuple is returned.
        If even one field is missing, the entire query is returned as empty.
        
        Parameters
        ----------
        idx : int
           Index of satellite in database.
        fields : list[string]
           List of strings; each string is a desired field from database for given satellite

        Returns
        -------
        tuple
           Tuple contains values in order of provided list of fields
           An empty tuple indicates that no data could be found

        
        """
        # Hand back an empty tuple for all early exits
        if not (0 <= idx < self.get_number_satellites()):
            warn_caller(f"Satellite index {idx} out of range")
            return tuple()

        if not isinstance(fields, (tuple, list)):
            warn_caller("Must pass a list or tuple of fields")
            return tuple()

        values = []
        for field in fields:
            if field in self._data[idx]:
                values.append(self._data[idx][field])
            else:
                # We've hit an invalid field, so entire query is invalid
                warn_caller(f"Database does not contain field '{field}'")
                return tuple()
        return tuple(values)

    def add_field_of_data(self, field, data):
        """Adds a new field to satellite database

        The caller provides a field name and an iterable of data (eg. list or numpy array).
        This is added to the database.
        If field name is already present in database, then this method OVERWRITES existing
        data with what is supplied here.
        The amount of data must match number of satellites in database.
        If it does not match, then no action is performed.
        A warning is given and the method returns without altering the database.
        
        Parameters
        ----------
        field : string
           Name of field for additional data
        data : list|tuple|ndarray
           An iterable object containing data for each satellite
        """
        n_sats = self.get_number_satellites()
        if len(data) != n_sats:
            warn_caller(
                "Could not add field data because amount of data is incorrect "
                f"(expected {n_sats}, got {len(data)})"
            )
            return
        if not isinstance(field, str):
            warn_caller("Only a single field of data can be added at a time")
            return 
        for i in range(n_sats):
            self._data[i][field] = data[i]
        return

__all__ = ["SatDB"]
        
if __name__ == '__main__':
    sat_db = SatDB('test.csv')
    n_sats = sat_db.get_number_satellites()
    print(f"number of satellites in database: {n_sats}")
    sat_id = 23
    (operator, launch_mass) = sat_db.get_sat_data(sat_id, ['operator', 'launch-mass'])
    print(f"id: {sat_id}  operator: {operator}  launch-mass: {launch_mass}")

然而,在一个单独的文件中,我打算导入这个类文件并编写一个函数,该函数返回一个包含Excel文档中最大对象的名称,质量等的元组。
我有点迷失在如何使用已经在类文件中找到的信息,并使用它跨越到一个不同的文件,而不创建错误。
我尝试了以下代码:

def find_largest_by_mass(testdb):
    
    idd = []
    Mass = []
    HEADER_ROW = 0
    FIRST_ROW = 1
    for index, row in enumerate(data_list):
        if index == HEADER_ROW:
            data_headers = row[2:]
        elif index >= FIRST_ROW:
            mass = row[7:]
    line_count = index - FIRST_ROW + 1
    data_array = np.array(mass, dtype = float)

但是,错误“名称'data_list'未定义”

testdb = SatDB('test_database.csv')
(max_idx, name, max_mass) = find_largest_by_mass(testdb)
print(f"{max_idx}: {name} has largest launch mass at {max_mass} kg.")

这个任务需要use来使用函数,我认为在第一行中使用SatDB可以使用SatDB类中的data_list。
任何帮助都非常感谢。

xdnvmnnf

xdnvmnnf1#

data_list不在函数的作用域中。您需要访问对象testdb中的数据。数据存储在SatDB._data中。您可以通过testdb._data在函数中访问此成员
但是,下划线是私有类成员的约定。因此,需要使用getter方法get_sat_dat从对象中检索所需的数据。

相关问题