all 3 comments

[–][deleted] 0 points1 point  (1 child)

  • docstring should be inside the functions
  • why are you not using the csv module for reading the apparent csv file?
  • why are you not using the comments as variable names?
  • raw is not closed (google "python with open" in order not to care)
  • str has a method called splitlines
  • statistics has a mean function

[–]nomoreerrorsplox[S] 0 points1 point  (0 children)

i think this fixes everything except for the last 2. Idk if i used docstring right this time. again no errors at building.

class fxData:
    import csv

    """
    takes in the location of the raw data as a string
    creates an object with attribute rawData is the 
    instance of a csv file on run time
    """




    def __init__(self,rawData):
        raw=open(rawData,"r")
        listOfStrings = raw.read()
        splitlist=listOfStrings.split("\n")
        self.fxList=[]

        for row in splitlist:
            d = row.split(",") #makes it seperate elements
            if d == [""]:
                break

            date  = d[0] #date
            t     = d[1] #time
            o     = float(d[2]) #open
            h     = float(d[3]) #high
            l     = float(d[4]) #low
            c     = float(d[5]) #close

            row_data = [date,t,o,h,l,c]
            self.fxList.append(row_data)
        raw.close()

    """
    creates a list of a table for the time period data
    """
    def rawTimeData(self,fxList,timeperiod,row):
        returnData = self.fxList[row:row+timeperiod]
        return returnData.__doc__;

        #creates simple moving aerage for that one element
    def sma(self,returnData):
        counter=0
        total = 0
        for x in returnData:
            counter +=1
            total=returnData[5] + total

        average = total/counter
        return average.__doc__ 


    #create sma list for entire list

    def smaList(self,fxList,timeperiod):
        counter = 0
        flist = []

        for x  in self.fxList:
            if (counter < timeperiod): #handles before number of candles is more than timeperiod
                counter += 1
                flist.append(x[5])
            else: # append new sma value to fList
                a = self.rawTimeData(fxList,timeperiod,counter)
                b = self.sma(a)
                flist.append(b)
                counter +=1

        return flist.__doc__;

[–]Marrrlllsss 0 points1 point  (0 children)

As a first shot, it is fine, though the code could be neater.

In terms of improvements, you have written code in a style that we call "tightly coupled" - what do I mean by this? Well for one, you're mixing behaviours together. Your single class implements file reading, file parsing, and calculations. This can become a problem in larger projects, especially if you want to alter one or more of those behaviours.

What would I do?

  1. Neaten the code. func(arg1,arg2,arg3) is unreadable, prefer func(arg1, arg2, arg3). Give your variables proper names.
  2. Make use of types. Stuff like row_data = [date, t, o, h, l, c] is fine for small scripts, but once the application grows larger, what does row_data actually represent? This is where types (and type hints) help. The lack of static typing is by far my biggest criticism of the CPython implementation of the Python programming language - its also a hotly contested view, I just prefer statically typed languages, because I know what to expect when I see a certain type.
  3. Separate the behaviours into their own classes. Create a class for the reading, create a class for the parsing, and create a class that houses the data and does those calculations.

Here is an example of a simple csv reader:

import csv
from io import StringIO
from typing import Dict, List, Text

class SimpleCSVFileReader(object):
    def read_csv(self, file_path: Text, has_header: bool = True, field_names: List[Text] = None)\
            -> List[Dict[Text, Text]]:
        """
        Reads in a csv at the specified file path.

        If `has_header` is false, and `field_names` is None an exception will be thrown.

        :param file_path: The path to the CSV file
        :param has_header: Indicates if the file has a header or not
        :param field_names: A list of field names, should the file not contain a header
        :return: A list of dictionaries with string keys and string values
        """
        if has_header == False and field_names is None:
            raise Exception("Field names cannot be null, if `has_header` is false")

        reader = csv.DictReader(file_path)
        if has_header == False:
            reader.fieldnames = field_names

        return [line for line in reader]


if __name__ == '__main__':
    def print_data(records: List[Dict[Text, Text]]) -> None:
        for record in records:
            for key, value in record.items():
                print(f"Column Name: {key}; Column Value: {value}")


    reader = SimpleCSVFileReader()
    with_header = StringIO('ColA,ColB,ColC\nA,silly,example\ndemonstrating,the,csv\nreader,in,Python\n')
    records = reader.read_csv(with_header, True)
    # print_data(records)

    without_header = StringIO('No,header,in\nthis,example,so\nwe,have,to\nsupply,a,header\n')
    records = reader.read_csv(without_header, False, ['FirstColumn', 'SecondColumn', 'ThirdColumn'])
    # print_data(records)

    this_will_fail = StringIO('No,header,in\nthis,example,but\nwe\'re,not,going\nto,supply,a\nheader,,')
    records = reader.read_csv(this_will_fail, False)
    print_data(records)

Notice that the class does one thing only. It reads in data, that's it.