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)    returndef 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 revisedDateListdef 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 revisedDateListdef 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 timeRangeListdef 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 timeRangeListdef 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 dataToWritecreateCsvFile()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.
Creating a table within a .csv file
python;performance;csv
Keep variables localThis part of code is very worrysome:#Declarations:fileName = dateList = []date = formattedDate = revisedDateList = []timeList = []studyTime = revisedTimeList = []formattedTime = timeRangeList = []listOfTimes = []eachRow = []subject = rowDate = timeRangesAsString = rowTextList = []I suggest declaring the variables just before using them inside the function that uses them, not all at once. Like this the reader will have to keep all of them in mind.Give inputs to functionsYour functions for the most part rely on global variables. It means that any global variable may be used and changed from anywhere, a very confusing fact.Smaller and simpler?I wrote a smaller version of this code by myself to get an idea of how much it would take, I did not handle formatting nor of time nor of dates,  just taking input and writing to the .csv and it came out 7 lines long. I think handling your formatting may take 10 more lines so less than 20 lines.Re-use + generators + avoiding reinventing the wheelMuch of your code is overly long, look at this example: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 timeRangeListBecomes:def create_ranges(revisedTimeList) :    for start, end in pairwise(revisedTimeList):        yield {start} - {end}.format(**locals())Where pairwise may be taken from StackOverflow and list may be needed to be called on the result if you want to index on it. Creating a generator using yield is simpler than returning a whole list.Your function was also virtually impossible to test because it relied on modifying the external variable timeRangeList.Mine can easily be run in the interactive shell or in a doctest:>>> list(create_ranges([10:23, 10:45, 11:22, 13:10]))['10:23 - 10:45', '11:22 - 13:10']Another example is formatDate(datesAsString) that applies a (series of) function(s) to all the items of a list, just like map does.To sum up, here is how I write functions, I think this method will help you too.Stop and think about a function before writing it, spend extra time on its name, it is more important than it seems at first glance.Decide the inputs and the outputs, make it interact with the user and the file-system only if strictly necessary.Decompose it into smaller chunks, describe it in English, write an example.Use the chunks from the std-lib or search them on StackOverflow.