0

I can't get my "doLogicForColumn5" function to affect my program. Column 5 of the CSV output should be filled with various values, but instead it's all the same number (12.12).

Lines 14-27 to be specific--they're simply not working!

Any help greatly appreciated!

     # -*- coding: utf-8 -*-
import csv
import string # for capwords
date = "7/5/2015"
monthlybudget = 100000
dailybudget = monthlybudget/30
#campaign variables
levels = [["1"], ["2"], ["3"], ["4"], ["5"], ["6"]]
language = [["english"], ["spanish"]]
variables = [["1"], ["2"]]
nouns = [["wordA1"], ["+wordA2"]]
adjectives1 = [["wordB1"], ["wordB2"]]
adjectives2 = [["wordC1"], ["wordC2"]]
def doLogicForColumn5(self): # budget
    self.column5 = dailybudget/36 
    if self.language == ["spanish"]: 
        self.column5 = self.column5 * .6
        if self.level == ["1"]:
            self.column5 = self.column5*.8
        else:
            self.column5 = self.column5*.1
    else: #if spanish
        self.column5 = self.column5*.4
        if self.level == ["1"]:
            self.column5 = self.column5*.2
        else:
            self.column5 = self.column5*.3
class Row(object):
    column1 = "column1"
    column2 = "column2"
    column3 = "column3"
    column4 = "column4"
    column5 = "budget"
    def __init__(self, level, language, noun, adjective1, adjective2, variable):
        self.level = level
        self.level = str(self.level)
        self.language = language
        self.language = str(self.language)
        self.noun = noun
        self.noun = str(self.noun)
        self.adjective1 = adjective1
        self.adjective1 = str(self.adjective1)
        self.adjective2 = adjective2
        self.adjective2 = str(self.adjective2)
        self.variable = variable
        self.variable = str(self.variable)
    def rowEntry(self, level, language, noun, adjective1, adjective2, variable):
        doLogicForColumn5(self)
        lol = [[self.column1], [self.column2], [self.column3], [self.column4], [self.column5]]
        lol[0] = self.column1
        lol[1] = self.column2
        lol[2] = self.column3
        lol[3] = self.column4
        lol[4] = self.column5
        file_writer.writerow([o for o in lol])
with open("test.csv", "wb") as test_file:
    file_writer = csv.writer(test_file)
    for a in range(0, len(levels)):
        for e in range(0, len(language)):    
            for y in range (0, len(nouns)):
                for x in range (0, len(adjectives1)):
                    for w in range (0, len(adjectives2)):
                        for n in range(0, len(variables)):
                            city = "n/a"
                            stateVersion = "n/a"
                            food = Row(levels[a], language[e], nouns[y], adjectives1[x], adjectives2[w], variables[n])                    
                            food.rowEntry(levels[a], language[e], nouns[y], adjectives1[x], adjectives2[w], variables[n])                    
  • Please use `itertools.product` so I don't have to see you nest your `for` loops any deeper – Cory Kramer Jul 09 '15 at 20:19
  • Also `def doLogicForColumn5(self)` doesn't exist within the context of your `class`.... so it is just a free function that happens to have an argument that you named `self` – Cory Kramer Jul 09 '15 at 20:21
  • Ohh, so I should put the function inside the class? And sorry, what do you mean about the itertools.product? I'm not familiar with it – Bob Willaker Jul 09 '15 at 20:22
  • [Read here](https://stackoverflow.com/questions/20981789/difference-between-methods-and-functions) you must define it as a *method* so it is bound to a variable, and therefore has an instance of the variable to access. – Cory Kramer Jul 09 '15 at 20:23
  • And for the other comment, you can delete your 6 `for` loops and replace it with just 1 loop `for a, e, y, x, w, n in itertools.product(levels, language, nouns, adjectives1, adjectives2, variables)` – Cory Kramer Jul 09 '15 at 20:24
  • Thanks. So instead of calling it like doLogicForColumn5 I will instead do A = doLogicForColumn5 to instantiate the method class? – Bob Willaker Jul 09 '15 at 20:26
  • No, I mean take the entire function definition, and move it within `class Row`, like `__init__` and `rowEntry` are. – Cory Kramer Jul 09 '15 at 20:27
  • Thanks but I still get the same number for every value in column5. Now it's a different number than before, though! it's 11.04. Thank you SO much for your help so far! – Bob Willaker Jul 09 '15 at 20:32

1 Answers1

0

First:

for a in range(0, len(levels)):

so a is a number. Then:

food = Row(levels[a],

and so levels[a] is a list such as ["1"]. Then, when you __init__() a Row:

self.level = level
self.level = str(self.level)

So now self.level is a string. Then, in doLogicForColumn5():

if self.level == ["1"]

Recall that self.level was cast as a string earlier. So self.level will never be equal to a list of ["1"]. It may, however, be equal to a string of "['1']", so it would make more sense to compare to that. Better yet, turn the global levels into a flat list like ["1", "2", "3", "4", "5", "6"]. The best option would be for levels to simply be '123456' and refactor your program to use that simpler structure.

Same goes for self.language and any other variables which have been set to a single-element list within a larger list.

Check your code for other instances of unnecessary complexity, as that sort of thing will eventually bite you (as another example, the doLogicForColumn5() function should really just be a method in Row, as commenters are suggesting).

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • Thanks so much for the response! I'm having trouble with your point about turning variables into Strings. Even if I change if self.level == ["1"] to if self.level == '["1"]' I end up with every row having the same value. As for having levels as a "flat list", isn't it already? – Bob Willaker Jul 09 '15 at 20:38
  • No, it is currently a `list` where each element is itself a `list`. Each of these nested `list`s contains a string. Since all you want to do is iterate over `'1'`, `'2'`, etc., you can just set it to a string `'123456'` and refactor your program to use that simpler structure. – TigerhawkT3 Jul 09 '15 at 20:50
  • I'm not sure how to do that, but I'm really looking for the path of least resistance get my "doLogicForColumn5" function to affect my coumn5 properly. Is there any advice you can give me about that? – Bob Willaker Jul 09 '15 at 20:53
  • The thing is, `'["1"]' != "['1']"`. When Python casts objects to `str`, it tries to make the representation stick with single quotes `'` when it can. That means that you need to tell the program to expect something with the appropriate quotes, as I specified in this answer. – TigerhawkT3 Jul 09 '15 at 21:04