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[0] :
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 datetime
module.
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.
09:00AM 11:00AM
. You can add several study times like so09:00AM 11:00AM 11:15AM 01:00PM 02:00PM 03:30PM 03:45PM 05:00PM
. Each pair having a start and an end time. Apologies, as I do not think I have made this clear. \$\endgroup\$ideone.com
for sharing code, I trust this is what you mean by ‘providing example usage session’. One limitation is that you cannot create new files, therefore I have provided a working example of the specific section in question; i.e. the user input of ‘studyTime’. I hope it provides you with what you need. Thanks again. ideone.com/GWaCY7 \$\endgroup\$