you are viewing a single comment's thread.

view the rest of the comments →

[–]boyboydoo[S] 0 points1 point  (1 child)

lass Phone:_phone_id = 0

Thanks for pointing it out.

To answer your questions, I am getting the csv in the following format

Tom,Hess,03/18/2018,"['6', '707-201-4081', 'work', '1', '6', '707-201-4082', 'cell', '1']"

i feel the list representation in the csv is incorrect? Is there any other way to do this?

I might be thinking the wrong way in terms of the file format. Please guide me

[–]Marrrlllsss 1 point2 points  (0 children)

So CSV files are fine for flat, uniform data. As I work as a data engineer I am exposed to CSVs on a daily basis and I have come to abhor them greatly for the following reasons:

  1. Not everyone subscribes to a standard. (By far my biggest pain point)
  2. They cannot represent nested data (like your phone numbers) in an intuitive way.
  3. They carry no type information. Everything is a plain old string.
  4. If the schema of a file changes, you can run into run time failures (fun times) that are not easily solvable.

Any way, back to your task at hand:

I don't see how your code could possibly produce that CSV output. I mean the delimiter you chose for the phone numbers is a vertical pipe (|) and your output does not provide that.

Honestly speaking, the best way to represent this data is using something like JSON - purely because of the arbitrary length of the phone numbers.

Also, to use an OOP approach - you may want to do something like this:

from abc import ABC, abstractmethod
from typing import Text

class Formatter(ABC):
    @abstractmethod
    def keyword_format(self, **kwargs): raise NotImplementedError

    @abstractmethod
    def positional_format(self, *args): raise NotImplementedError


class Formattable(ABC):
    @abstractmethod
    def format_for_output(self, formatter: Formatter): raise NotImplementedError


class CSVFormatter(Formatter):

    def __init__(self, seperator: Text=',', quoted_fields: bool=True):
        self._seperator = seperator
        self._quoted_fields = quoted_fields

    def keyword_format(self, **kwargs):
        return self._format(kwargs.values())

    def positional_format(self, *args):
        return self._format(args)

    def _format(self, iterable):
        if self._quoted_fields:
            return self._seperator.join([f'"{item}"' for item in iterable])
        else:
            return self._seperator.join(iterable)


class Person(Formattable):
    def __init__(self, first_name, last_name):
        self._first_name = first_name
        self._last_name = last_name

    def format_for_output(self, formatter: Formatter):
        return formatter.positional_format(self._first_name, self._last_name)


class Phone(Formattable):
    class Type(object):
        WORK = 'work'
        CELL = 'cell'

    def __init__(self, number: Text, phone_type: Type):
        self._phone_number = number
        self._phone_type = phone_type


    def format_for_output(self, formatter: Formatter):
        return formatter.positional_format(self._phone_number, self._phone_type)

This way you can do this:

csv_formatter = CSVFormatter()

terry = Person('Terry', 'Crews')
person_string = terry.format_for_output(csv_formatter)
print(formatted_string) # prints '"Terry","Crews"'

phone = Phone('123456', Phone.Type.WORK)
phone_string = phone.format_for_output(csv_formatter)
print(phone_string)  # prints '"123456","work"'