I recently made a post on Code Review entitled Writing lists to .csv file. I found the feedback extremely helpful, and wished to provide a continuation of that particular topic; of working with Python and .csv files.
I therefore set the somewhat more complex challenge of creating and populating a table within a .csv file. In particular, taking on-board previous feedback, I have begun using user-defined functions to separate concerns.
This creates a .csv file from 'scratch', prompting the user for the required input along the way:
#Import modules: import datetime #Declarations: fileName = "" dateList =  date = "" formattedDate = "" revisedDateList =  timeList =  studyTime = "" revisedTimeList =  formattedTime = "" timeRangeList =  listOfTimes =  eachRow =  subject = "" rowDate = "" timeRangesAsString = "" rowTextList =  def createCsvFile() : #Creates and populates a .csv file, with time periods as columns and dates as rows. fileName = input("Please enter a name for your file: ") with open(fileName+".csv","w+") as usersFile : revisedDateList = listOfDates() timeRangeList = inputTimes() timeRangesAsString = ",".join(timeRangeList) usersFile.write(","+timeRangesAsString+"\n") for date in revisedDateList : fileText = rowContent(revisedDateList,timeRangeList,date) usersFile.write(fileText) return def listOfDates() : #Asks user to input dates in specified format and returns a list of strings representing dates. datesAsString = input("Please enter your dates as required (dd/mmm/yy dd/mmm/yy etc.) ") # Example: 17/jan/16 18/jan/16 revisedDateList = formatDate(datesAsString) return revisedDateList def formatDate(datesAsString) : #Converts a list of strings, representing dates, from dd/mmm/yy to dd/mm/yyyy. dateList = datesAsString.split() for date in dateList : structTime = datetime.datetime.strptime(date,"%d/%b/%y") #Example: 17/jan/16 formattedDate = datetime.datetime.strftime(structTime, "%d/%m/%Y") # Example: 17/01/2016 revisedDateList.append(formattedDate) return revisedDateList def inputTimes() : #Asks the user to input times, to be used as column headers, returns a list of strings representing time ranges. studyTime = input("Please enter your study periods throughout the day (hh:mm hh:mm): ") timeList = studyTime.split() for time in timeList : structTime = datetime.datetime.strptime(time, "%I:%M%p") formattedTime = datetime.datetime.strftime(structTime, "%H:%M") revisedTimeList.append(formattedTime) timeRangeList = formatTimes(revisedTimeList) return timeRangeList def formatTimes(revisedTimeList) : #Grouping individual times to create time ranges: listOfTimes = revisedTimeList iteratorList = iter(listOfTimes) for time in iteratorList : timeRange = time + " - " + next(iteratorList) timeRangeList.append(timeRange) return timeRangeList def rowContent(revisedDateList,timeRangeList,date) : #Creates strings ready for writing to .csv file, as individual rows of data: eachRow =  #'eachRow = ' is required to reset the variable and prevent an accumulation of data from the 'for loop'. for timePeriod in timeRangeList : subject = input("Please enter your topic of study between " + timePeriod\ + " on " + date + ": ") if timePeriod == timeRangeList : rowData = date + "," + subject elif timePeriod == timeRangeList[-1] : rowData = subject + "\n" else : rowData = subject eachRow.append(rowData) dataToWrite = ",".join(eachRow) return dataToWrite createCsvFile() print("Writing to file complete! ")
At this stage, please note that I have included the formatting of the dates and times purely for exercise purposes; I wanted practice using the
The code works the way it is intended. However, it does raise a number of questions in my mind. This is why I would very much appreciate the feedback of more experienced programmers.
Firstly, the code seems very long and convoluted. I have tried to separate concerns where possible, by defining my own functions. However, are there any particular lines, or segments of code, that are needlessly convoluted. Are there any sections of code that could be written more succinctly? Am I overlooking some obvious methods, classes or modules that could make this program a lot cleaner/simpler? Or is it the case, that even such simple programs require a significant amount of code?
I suppose the overriding question for me, and one I would guess plagues the mind of many a novice, is; is my code overly long and therefore not very well written, or is it meaningful and of necessary length?
This leads me nicely to my second question, as an 'apprentice' in computer programming, do you consider that I am too overly concerned at this stage with aspects of coding such as readability, efficiency and technique. Would my time be better spent learning languages in depth first, before learning about etiquette, efficiency, succinctness etc.?
Finally, would repeatedly calling the
rowContent() function, within a
for loop, slow processing and/or needlessly take up memory space. If so, can you think of a more eloquent solution to this particular segment of the code; this function creates and returns the strings ready for writing to file.