0

I am puzzled:

class lin_reg:

     def __init__(self):
    ''' Executes the program '''

    Indep_Array, Dep_Array = self.Prob_Def()
    Total_Array = Indep_Array.append(Dep_Array)
    print Indep_Array, Dep_Array, Total_Array
    NumArray = len(Total_Array)

def Prob_Def(self):

    Analy_Type = raw_input('Type of Regression(linear-n,nonlinear-nl): ')
    Num_IndepVar = eval(raw_input('Number of Independent Variables: '))
    Indep_Array = []
    for IndepVar in range(Num_IndepVar):
        ArrayInput = eval(raw_input('Enter the array: '))
        Indep_Array.append(ArrayInput)
    Dep_Array = eval(raw_input('Enter the dependent array: '))
    return Indep_Array, Dep_Array

When I run this code, I get output as follows:

obs=lin_reg.lin_reg()
Type of Regression(linear-n,nonlinear-nl): nl
Number of Independent Variables: 3
Enter the array: [1,2,3]
Enter the array: [2,3,4]
Enter the array: [3,4,5]
Enter the dependent array: [5,6,7]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [5, 6, 7]] [5, 6, 7] None

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    obs=lin_reg.lin_reg()
  File "C:\Python27\DataAnalysis\lin_reg.py", line 13, in __init__
    NumArray=len(Total_Array)
TypeError: object of type 'NoneType' has no len()

How is the dependent array Dep_Array automatically appended to Indep_Array and why is Total_Array returning None?

I was expecting to see output like this for above input: [[1,2,3],[2,3,4],[3,4,5]] [5,6,7] [[1,2,3],[2,3,4],[3,4,5],[5,6,7]]

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Jack_of_All_Trades
  • 10,942
  • 18
  • 58
  • 88
  • I looked into the duplicate. However, if I had stumbled into your "so-called duplicate" before I had posted this question, I would have still posted it. May be it is just me but I think I would not have been able to solve my problem like here by referring to the "duplicate". – Jack_of_All_Trades Mar 22 '12 at 19:42
  • What you're seeing is that `Total_Array` has a value of `None`. It gets that value from the assignment `Total_Array = Indep_Array.append(Dep_Array)`. The other question's answers explain that, and why, this will result in `Total_Array` ending up with a value of `None`. I don't really see how this could fail to solve the problem. – Karl Knechtel Mar 22 '12 at 20:57

3 Answers3

7

.append modifies the original list and returns None. You want +.

I've taken the liberty of rewriting your code to how Python should look.

class lin_reg(object):
     def __init__(self):
         self.indep, self.dep = self.initialise_from_user()
         self.total = self.indep + self.dep
         print self.indep, self.dep, self.total
         self.n = len(self.total)

def initialise_from_user(self):
    analysis_type = raw_input('Type of Regression(linear-n,nonlinear-nl): ')
    n = int(raw_input('Number of Independent Variables: '))

    indep = [np.matrix(raw_input('Enter the array: ')) for _ in range(self.n)]
    dep =  np.matrix(raw_input('Enter the dependent array: '))

    return indep, dep
Katriel
  • 120,462
  • 19
  • 136
  • 170
  • How many people have been burned by trying to assign the output of a mutating function? It's happened to me too. – Mark Ransom Mar 22 '12 at 19:32
  • @MarkRansom but it's an easy bug to catch, unlike nasty things that happen halfway through a chain of such functions. – Katriel Mar 22 '12 at 19:35
  • @katrielalex: In the code you modified, do you mean to import numpy as np? – Jack_of_All_Trades Mar 22 '12 at 19:48
  • @Jack_of_All_Trades yes. You probably want to make `indep` an `np.array` as well, but you can work out how to do that =) Also edited slightly – Katriel Mar 23 '12 at 00:09
2
  1. The reason that Dep_Array is automatically appended to Indep_Array is because Indep_Array.append(Dep_Array) modifies Indep_Array.

  2. The function append returns None instead of a list. This was done on purpose to prevent people from chaining functions that modify the arguments, such as a.append(b).remove(c).doSomething(d). By preventing this, the code remains clear and easier to understand for someone unfamiliar with those methods.

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
1

It's because list.append() doesn't return anything, it changes the list in place. Therefore,

 Total_Array=Indep_Array.append(Dep_Array)

makes Total_Array equal None.

Also, naming conventions are against capitalized variable names.

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175