Skip to main content

A simple package intended to help write iterables of objects to CSV files

Project description

List2CSV

List2CSV is a simple package that helps with writing lists of objects to CSV files.

Installation

list2csv can be downloaded from pypi or installed using pip:

pip install list2csv

Usage

List2CSV exposes a Writer class that manages CSV columns and writing to a TextIO stream. Columns are first configured on a Writer instance before data is written in CSV format to the stream.

The following examples will use this Student class and list to demonstrate usage.

from dataclasses import dataclass
from statistics import mean


@dataclass
class Student:
    student_id: str
    test_1_mark: float
    test_2_mark: float
    assignment_marks: list[float]
    lab_marks: list[float]
    comments: list[str]

    @property
    def grade(self):
        return (
                60 * mean((self.test_1_mark, self.test_2_mark))
                + 30 * mean(self.assignment_marks)
                + 10 * mean(self.lab_marks)
        ) / 100


students = [
    Student('abcd123',
            78.5, 88,
            [84.5, 96, 87],
            [92.3, 98, 100, 70],
            ['Good', 'Needs work on classes']),
    Student('efgh456',
            62, 74,
            [70.5, 76, 80],
            [98, 68.2, 0, 93.5],
            ['Good', 'Needs work on formatting', 'Needs work on recursion']),
    Student('ijkl789',
            100, 99.5,
            [98.5, 100, 100],
            [100, 100, 98.7, 100],
            ['Excellent']),
]

Adding Columns

The most basic column configuration is to use the add_column method to add a column with a name and a function that returns the value for that column.

Column data can be formatted with an optional format string to specify how data should be formatted as it is written to the CSV file.

import list2csv

with open('grades.csv') as f:
    writer = list2csv.Writer(f)
    writer.add_column('ID', lambda s: s.student_id)

    writer.write_header()
    writer.write_all(students)

Which will produce the following table:

ID
abcd123
efgh456
ijkl789

However, instead of a function, lambda s: s.student_id, you can also use a string of the attribute name of the objects being written:

import list2csv

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_column('ID', 'student_id')

    writer.write_header()
    writer.write_all(students)

Would produce the same table as before.

Several columns can be added with subsequent calls to add_column.

import list2csv

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_column('ID', 'student_id')
    writer.add_column('Test 1', 'test_1_mark', '{:.2f}')
    writer.add_column('Test 2', 'test_2_mark', '{:.2f}')

    writer.write_header()
    writer.write_all(students)

Would produce the following table:

ID Test 1 Test 2
abcd123 78.5 88
efgh456 62 74
ijkl789 100 99.5

Counters

Counter columns can be added which increment by a given step value for each row written to the CSV. Counter columns have a default start value of 1 and a default step value of 1.

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_counter('Student Num')
    writer.add_column('ID', 'student_id')
    writer.add_column('Test 1', 'test_1_mark', '{:.2f}')
    writer.add_column('Test 2', 'test_2_mark', '{:.2f}')

    writer.write_header()
    writer.write_all(students)

Which would produce the following table:

Student Num ID Test 1 Test 2
1 abcd123 78.5 88
2 efgh456 62 74
3 ijkl789 100 99.5

Any number of counters with separate start and step values can be added to the same CSV file.

Multi Columns

It is often desirable to write iterables of data to separate columns of a CSV file. in such cases, a multi_column can be added to the Writer instance.

Multi columns take a headder_formatter as opposed to a header name. Each resulting column will be named header_template.format(i), where i is the one-based index of the column.

Multi columns will also need to be defined with the number of columns that will be added.

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_counter('Student Num')
    writer.add_column('ID', 'student_id')
    writer.add_column('Test 1', 'test_1_mark', '{:.2f}')
    writer.add_column('Test 2', 'test_2_mark', '{:.2f}')
    writer.add_multi('Assignment {}', 'assignment_marks', 3, '{:.2f}')

    writer.write_header()
    writer.write_all(students)

Would produce the following table:

Student Num ID Test 1 Test 2 Assignment 1 Assignment 2 Assignment 3
1 abcd123 78.50 88.00 84.50 96.00 87.00
2 efgh456 62.00 74.00 70.50 76.00 80.00
3 ijkl789 100.00 99.50 98.50 100.00 100.00

Aggregator Columns

Aggregator columns can collate the data from several columns into a single column. Each column can be added with a set of aggregator IDs. When aggregator columns are added with an ID, all columns with a matching ID will be aggregated into a single column using an aggregator function. For example:

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_counter('Student Num')
    writer.add_column('ID', 'student_id')
    writer.add_column('Test 1', 'test_1_mark', '{:.2f}', {'test'})
    writer.add_column('Test 2', 'test_2_mark', '{:.2f}', {'test'})
    writer.add_aggregator('test', 'Av Test Mark', mean, '{:.2f}')
    writer.add_multi(
        'Assignment {}', 'assignment_marks', 3, '{:.2f}', {'assignment'}
    )
    writer.add_aggregator('assignment', 'Av Assignment Mark', mean, '{:.2f}')

    writer.write_header()
    writer.write_all(students)

Would produce the following table:

Student Num ID Test 1 Test 2 Av Test Mark Assignment 1 Assignment 2 Assignment 3 Av Assignment Mark
1 abcd123 78.50 88.00 83.25 84.50 96.00 87.00 89.17
2 efgh456 62.00 74.00 68.00 70.50 76.00 80.00 75.50
3 ijkl789 100.00 99.50 99.75 98.50 100.00 100.00 99.50

While aggregator columns may be useful for aggregating data from multiple attributes, in the case of aggregating multi columns it may just be more useful to add a single column with an aggregating function. For example:

    ...
    writer.add_multi('Assignment {}', 'assignment_marks', 3, '{:.2f}')
    writer.add_column(
        'Av Assignment Mark', lambda s: mean(s.assignment_marks), '{:.2f}'
    )
    ...

Extended Example

with open('grades.csv', 'w', newline='') as f:
    writer = list2csv.Writer(f)
    writer.add_counter('Student Num')
    writer.add_column('ID', 'student_id')
    writer.add_column('Test 1', 'test_1_mark', '{:.2f}', {'test'})
    writer.add_column('Test 2', 'test_2_mark', '{:.2f}', {'test'})
    writer.add_aggregator('test', 'Av Test Mark', mean, '{:.2f}')
    writer.add_multi(
        'Assignment {}', 'assignment_marks', 3, '{:.2f}', {'assignment'}
    )
    writer.add_aggregator('assignment', 'Av Assignment Mark', mean, '{:.2f}')
    writer.add_multi('Lab {}', 'lab_marks', 4, '{:.2f}', {'lab'})
    writer.add_aggregator('lab', 'Av. Lab Mark', mean, '{:.2f}')
    writer.add_column('Grade', 'grade', '{:.2f}')
    writer.add_column('Comments', lambda s: '\n'.join(s.comments))

    writer.write_header()
    writer.write_all(students)
Student Num ID Test 1 Test 2 Av Test Mark Assignment 1 Assignment 2 Assignment 3 Av Assignment Mark Lab 1 Lab 2 Lab 3 Lab 4 Av. Lab Mark Grade Comments
1 abcd123 78.50 88.00 83.25 84.50 96.00 87.00 89.17 92.30 98.00 100.00 70.00 90.08 85.71 Good
Needs work on classes
2 efgh456 62.00 74.00 68.00 70.50 76.00 80.00 75.50 98.00 68.20 0.00 93.50 64.92 69.94 Good
Needs work on formatting
Needs work on recursion
3 ijkl789 100.00 99.50 99.75 98.50 100.00 100.00 99.50 100.00 100.00 98.70 100.00 99.67 99.67 Excellent

Note

Files should be opened with newline='' to allow for universal newline support.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

list2csv-1.3.6.tar.gz (8.3 kB view details)

Uploaded Source

Built Distribution

list2csv-1.3.6-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file list2csv-1.3.6.tar.gz.

File metadata

  • Download URL: list2csv-1.3.6.tar.gz
  • Upload date:
  • Size: 8.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for list2csv-1.3.6.tar.gz
Algorithm Hash digest
SHA256 fd11c76778ce6a9ab88a68794dd08dc828c4ab8a762ad49af47483855c22cab7
MD5 e03535009467ecd02a8ebb93c2504757
BLAKE2b-256 6a3e16a660e7152a1441c26b84f8e1a9eefa13ae04527f282a9cebfb3fcbf1f5

See more details on using hashes here.

File details

Details for the file list2csv-1.3.6-py3-none-any.whl.

File metadata

  • Download URL: list2csv-1.3.6-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.0

File hashes

Hashes for list2csv-1.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 d5c8fc710ce9de645559be277d0b6b70fdbebb0e2914c94abd4b026de3bba711
MD5 b580eb57cb9a78138b5bd1f3213fe45d
BLAKE2b-256 7e3ac21a65d03ce52f0f03b17fe5c8b49af513a0f8131324bc320822c4243c45

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page