help with addition of dictionary values

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • cLoque
    New Member
    • Nov 2007
    • 10

    help with addition of dictionary values

    hi,

    i would like to add my two matrices, using __add__


    Code:
    class m:
    
        def __init__(self, mtx={}, m=0, n=0):
            self.matrix = {}
            self.matrix.update(mtx)
            self.row = m
            self.col = n
    
        def __getitem__(self, ij):
            return self.matrix.get(ij,0)
    
        def __setitem__(self, ij, val):
            self.matrix[i,j] = val
    
        def __add__(self, other):
            result = m()
            for i in other:
                self.result[i] = self.matrix.get(i, 0) + other[i]
            return result
    but i always get an error.

    Hope you can help me
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    Use the dictionary method, items(). Like this:[CODE=python]
    >>> dd_1 = {'a':1, 'b':2, 'c':3}
    >>> dd_2 = {'a':3, 'b':4}
    >>> dd_res = {}
    >>> for key, value in dd_1.items():
    ... dd_res[key] = dd_2.get(key, 0) + value
    ...
    >>> dd_res
    {'a': 4, 'c': 3, 'b': 6}
    >>> [/CODE]
    Last edited by bartonc; Nov 10 '07, 09:04 PM.

    Comment

    • cLoque
      New Member
      • Nov 2007
      • 10

      #3
      Originally posted by bartonc
      Use the dictionary method, items. Like this:[CODE=python]
      >>> dd_1 = {'a':1, 'b':2, 'c':3}
      >>> dd_2 = {'a':3, 'b':4}
      >>> dd_res = {}
      >>> for key, value in dd_1.items():
      ... dd_res[key] = dd_2.get(key, 0) + value
      ...
      >>> dd_res
      {'a': 4, 'c': 3, 'b': 6}
      >>> [/CODE]
      for this loop what does value means here? how can i use the one that i have set in __setitem__? does get(key, 0) gives me the value that i have set in __setitem__?

      sorry if i sound confusing, but honestly i'm confused with the passing of tuples, i want to know exactly where does each value goes after using the method. am already fine with __init__ method, i'm just confused what happens to the values after setting them

      for key, value in dd_1.items():
      ... dd_res[key] = dd_2.get(key, 0) + value

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        Originally posted by cLoque
        for this loop what does value means here? how can i use the one that i have set in __setitem__? does get(key, 0) gives me the value that i have set in __setitem__?

        sorry if i sound confusing, but honestly i'm confused with the passing of tuples, i want to know exactly where does each value goes after using the method. am already fine with __init__ method, i'm just confused what happens to the values after setting them

        for key, value in dd_1.items():
        ... dd_res[key] = dd_2.get(key, 0) + value
        OK. Your class is coming along nicely. The on-line help can probably explain these things better that I can (more succinctly, anyway):[CODE=python]
        >>> help(dd_1.get)
        Help on built-in function get:

        get(...)
        D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.

        >>> help(dd_1.items )
        Help on built-in function items:

        items(...)
        D.items() -> list of D's (key, value) pairs, as 2-tuples[/CODE]But probably the best way to learn what a chunk of code (your own or someone else's) is like this:[CODE=python]
        >>> for key, value in dd_1.items():
        ... print key, value
        ... dd_res[key] = dd_2.get(key, 0) + value[/CODE]

        Comment

        • bartonc
          Recognized Expert Expert
          • Sep 2006
          • 6478

          #5
          If the assignment doesn't allow using a subclass, you'll have to use the tricks below to take this apart and create your own class:[CODE=python]
          ...
          >>> class sm(dict):
          ... def __add__(self, other):
          ... res = sm()
          ... for key, value in other.items():
          ... mine = self.get(key, 0)
          ... res[key] = mine + value
          ... return res
          ...
          >>> sm_1 = sm({(0,0):5, (0,1):2})
          >>> sm_2 = sm({(0,0):7, (0,1):1})
          >>> sm_1 + sm_2
          {(0, 1): 3, (0, 0): 12}
          >>> [/CODE]You'll also need to add some additional logic to account for keys in sm_1 that don't exist in sm_2.

          Comment

          • cLoque
            New Member
            • Nov 2007
            • 10

            #6
            hi,

            before i start asking questions again, i really would like to thank this forum, slowly I was able to form my program, (especially bartonc and bvdet for wasting their time reading my pathetic questions lol), im really glad that someone is helping me...

            back to my questions...

            i tried to use the items() but i have error saying:
            Code:
            line 17, in __add__
                for key, value in self.items():
            AttributeError: GeneralSparse instance has no attribute 'items'
            items() is another function right? but can't i just utilize my __setitem__ and __getitem__, because my __setitem__ already sets the value of my matrix (please correct me if i'm wrong), so because i have set
            Code:
            self.matrix[ij] = val
            on my __setitem__ the value know of my self.matrix is equal to val...

            i tried to look back on my __str__ method, and tried to pattern some idea then end up with this:

            Code:
                def __add__(self, other):
                    matrix = m() //i wrote it like this because it will implement my m class
                    for i in range(self.row):// i like my code to check the row one by one 
                        for j in range(self.col)://before jumping to the next row it has to check first each column that my row has and get the value of it
                            self.matrix[i,j] = self[(i,j),0] + other[i,j]
            this one didn't give me any error but it also didn't give me anythng, the output is like this:
            Code:
            [0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  
             0  5  0  0  0  0  0  
             0  0  4  0  0  0  0  
             0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  ]
            
            [0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  
             0  8  0  0  0  0  0  
             0  0  1  0  0  0  0  
             0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  
             0  0  0  0  0  0  0  ]
            
            None
            i don't understand why it is giving me "NONE"

            then i tried this one also:
            Code:
            self.matrix[i,j] = self[.get(i,j),0] + other[i,j]
            python gave me this error:
            Code:
            line 19, in __add__
                self.matrix[i,j] = self.get[(i,j),0] + other[i,j]
            AttributeError: GeneralSparse instance has no attribute 'get'
            i don't know how to interpret the errors python's throwing me..hope you can help me how to figure it out

            Comment

            • bartonc
              Recognized Expert Expert
              • Sep 2006
              • 6478

              #7
              Originally posted by cLoque
              hi,

              i would like to add my two matrices, using __add__


              Code:
              class m:
              
                  def __init__(self, mtx={}, m=0, n=0):
                      self.matrix = {}
                      self.matrix.update(mtx)
                      self.row = m
                      self.col = n
              
                  def __getitem__(self, ij):
                      return self.matrix.get(ij,0)
              
                  def __setitem__(self, ij, val):
                      self.matrix[i,j] = val
              
                  def __add__(self, other):
                      result = m()
                      for i in other:
                          self.result[i] = self.matrix.get(i, 0) + other[i]
                      return result
              but i always get an error.

              Hope you can help me
              [CODE=python]# don't forget that you may want to use print statements with your object
              def __repr__(self):
              return str(self.matrix )

              def __getitem__(sel f, ij): # this is the syntax for calling with a tuple
              return self.matrix.get (ij, 0)

              def __setitem__(sel f, ij, val):
              self.matrix[ij] = val # your version lacked consistance

              sm_1 = sm({(0,0):5, (0,1):2})
              sm_1[(0,2)] = 8
              print sm_1
              print sm_1[(0,2)][/CODE]

              Comment

              • cLoque
                New Member
                • Nov 2007
                • 10

                #8
                [CODE=python]# don't forget that you may want to use print statements with your object
                def __repr__(self):
                return str(self.matrix )

                def __getitem__(sel f, ij): # this is the syntax for calling with a tuple
                return self.matrix.get (ij, 0)

                def __setitem__(sel f, ij, val):
                self.matrix[ij] = val # your version lacked consistance

                sm_1 = sm({(0,0):5, (0,1):2})
                sm_1[(0,2)] = 8
                print sm_1
                print sm_1[(0,2)][/CODE]

                [CODE=python] def __getitem__(sel f, ij): # this is the syntax for calling with a tuple
                return self.matrix.get (ij, 0)

                def __setitem__(sel f, ij, val):
                self.matrix[ij] = val # your version lacked consistance[/CODE]

                what do you mean my version lacked consistence? do i need to add something? because what i understand about getitem and setitem is:

                1. __getitem__ will get the index, if the dictionary that have been passed has no tuple it will assign 0 value but if it has then it will get the index or call the tuple

                2. __setitem__ will take the index that __getitem__ got and assigned the value that the tuples has.

                **please correct me if I am wrong**

                [CODE=python]# don't forget that you may want to use print statements with your object[/CODE]

                this is my __str__()


                [CODE=python] def __str__(self):
                s = "["
                if self.row > 0:
                for i in range(self.row) :
                for j in range(self.col) :
                s += str(self[i,j])
                s += " "
                if i < self.row-1:
                s += "\n "
                s += "]\n"
                return s[/CODE]

                isn't it that __str__() does the job in printing my code? because, for this program all we have to do is to complete the methods (__init__, __getitem__, __setitem__, __add__, __mul__, __str__)

                thanks
                Last edited by bartonc; Nov 11 '07, 12:44 AM. Reason: remove quotes due to site bug: =python in opening tags only!

                Comment

                • bartonc
                  Recognized Expert Expert
                  • Sep 2006
                  • 6478

                  #9
                  isn't it that __str__() does the job in printing my code?
                  Yes. That's correct. If there is not __str__(), then __repr__() gets called, though. It means "representation ".

                  Comment

                  • bartonc
                    Recognized Expert Expert
                    • Sep 2006
                    • 6478

                    #10
                    what do you mean my version lacked consistence?
                    Yours had a comma between i & j. There is no comma in mine (which I tested).

                    Comment

                    • bartonc
                      Recognized Expert Expert
                      • Sep 2006
                      • 6478

                      #11
                      this is my __str__()
                      Very nice .

                      Comment

                      • cLoque
                        New Member
                        • Nov 2007
                        • 10

                        #12
                        this is my whole program
                        Code:
                        class GeneralSparse:
                        
                            def __init__(self, mtx={}, m=0, n=0):
                                self.matrix = {}
                                self.matrix.update(mtx)
                                self.row = m
                                self.col = n
                        
                            def __getitem__(self, ij):
                                return self.matrix.get(ij,0)
                        
                            def __setitem__(self, ij, val):
                                self.matrix[ij] = val
                        
                            def __add__(self, other):
                                matrix = GeneralSparse()
                                for i in range(self.row):
                                    for j in range(self.col):
                                        self.matrix[i,j] = self[(i,j),0] + other[i,j]     
                        
                            def __str__(self):
                                s = "["
                                if self.row > 0:
                                    for i in range(self.row):
                                        for j in range(self.col):
                                            s += str(self[i,j])
                                            s += "  "
                                        if i < self.row-1:
                                            s += "\n "
                                    s += "]\n"
                                    return s
                        
                        
                        if __name__=="__main__":
                            x = GeneralSparse({(3,2):4, (2,1):5}, 7, 7)
                            y = GeneralSparse({(3,2):1, (2,1):8}, 7, 7)
                            print x
                            print y
                            a = x + y
                            print a
                        so far everything works pretty fine. it displays my two matrices but doesn't add them up, and gives me "NONE"

                        i can't still seem to figure out what's wrong or missing in my __add__(). and why it doesn't work

                        [

                        Comment

                        • bartonc
                          Recognized Expert Expert
                          • Sep 2006
                          • 6478

                          #13
                          Originally posted by cLoque
                          this is my whole program
                          Code:
                          class GeneralSparse:
                          
                              def __init__(self, mtx={}, m=0, n=0):
                                  self.matrix = {}
                                  self.matrix.update(mtx)
                                  self.row = m
                                  self.col = n
                          
                              def __getitem__(self, ij):
                                  return self.matrix.get(ij,0)
                          
                              def __setitem__(self, ij, val):
                                  self.matrix[ij] = val
                          
                              def __add__(self, other):
                                  matrix = GeneralSparse()
                                  for i in range(self.row):
                                      for j in range(self.col):
                                          self.matrix[i,j] = self[(i,j),0] + other[i,j]     
                          
                              def __str__(self):
                                  s = "["
                                  if self.row > 0:
                                      for i in range(self.row):
                                          for j in range(self.col):
                                              s += str(self[i,j])
                                              s += "  "
                                          if i < self.row-1:
                                              s += "\n "
                                      s += "]\n"
                                      return s
                          
                          
                          if __name__=="__main__":
                              x = GeneralSparse({(3,2):4, (2,1):5}, 7, 7)
                              y = GeneralSparse({(3,2):1, (2,1):8}, 7, 7)
                              print x
                              print y
                              a = x + y
                              print a
                          so far everything works pretty fine. it displays my two matrices but doesn't add them up, and gives me "NONE"

                          i can't still seem to figure out what's wrong or missing in my __add__(). and why it doesn't work

                          [
                          You get None because you don't return a result. I've crafted an __add__() that may do more than you need, but you may learn a lot from these techniques:[CODE=python]#.....
                          def __add__(self, other):
                          res = sm({}, self.row, self.col)
                          for i in range(self.row) :
                          for j in range(self.col) :
                          try: # does the left hand matrix have this element?
                          mine = self.matrix[(i, j)]
                          # Yes. try to get() from other or use zero
                          res.matrix[(i, j)] = mine + other.matrix.ge t((i, j), 0)
                          except KeyError: # No, does the right hand one?
                          try:
                          # yes. add it to the resulting matrix
                          res.matrix[(i, j)] = other.matrix[(i, j)]
                          except KeyError: # No
                          pass # do nothing
                          return res

                          sm_1 = sm({(3,2):4, (2,1):5}, 7, 7)
                          sm_2 = sm({(3,2):1, (2,1):8}, 7, 7)
                          smSum = sm_1 + sm_2
                          print smSum
                          # this is from my repr() method
                          {(3, 2): 5, (2, 1): 13}[/CODE]Not that =python only go in the opening CODE tag. Thanks for paying attention to the post that you have seen in this regard.

                          Comment

                          • bartonc
                            Recognized Expert Expert
                            • Sep 2006
                            • 6478

                            #14
                            Originally posted by bartonc
                            You get None because you don't return a result. I've crafted an __add__() that may do more than you need, but you may learn a lot from these techniques:[CODE=python]#.....
                            def __add__(self, other):
                            res = sm({}, self.row, self.col)
                            for i in range(self.row) :
                            for j in range(self.col) :
                            try: # does the left hand matrix have this element?
                            mine = self.matrix[(i, j)]
                            # Yes. try to get() from other or use zero
                            res.matrix[(i, j)] = mine + other.matrix.ge t((i, j), 0)
                            except KeyError: # No, does the right hand one?
                            try:
                            # yes. add it to the resulting matrix
                            res.matrix[(i, j)] = other.matrix[(i, j)]
                            except KeyError: # No
                            pass # do nothing
                            return res

                            sm_1 = sm({(3,2):4, (2,1):5}, 7, 7)
                            sm_2 = sm({(3,2):1, (2,1):8}, 7, 7)
                            smSum = sm_1 + sm_2
                            print smSum
                            # this is from my repr() method
                            {(3, 2): 5, (2, 1): 13}[/CODE]Not that =python only go in the opening CODE tag. Thanks for paying attention to the post that you have seen in this regard.
                            Here are some mods:[CODE=python]
                            #
                            def __getitem__(sel f, ij):
                            # Use self.matrix.get () if you really want zero for non-existent elements
                            return self.matrix[ij]
                            # If you don't use self.matrix.get () then you can eliminate matrix below (mostly)
                            # as shown here:

                            def __add__(self, other):
                            res = sm({}, self.row, self.col)
                            for i in range(self.row) :
                            for j in range(self.col) :
                            try: # does the left hand matrix have this element?
                            mine = self[(i, j)]
                            # Yes. try to get() from other or use zero
                            res[(i, j)] = mine + other.matrix.ge t((i, j), 0) # using a subclass avoids the .matrix
                            except KeyError: # No, does the right hand one?
                            try:
                            # yes. add it to the resulting matrix
                            res[(i, j)] = other[(i, j)]
                            except KeyError: # No
                            pass # do nothing
                            return res[/CODE]

                            Comment

                            • bartonc
                              Recognized Expert Expert
                              • Sep 2006
                              • 6478

                              #15
                              Originally posted by bartonc
                              Here are some mods:[CODE=python]
                              #
                              def __getitem__(sel f, ij):
                              # Use self.matrix.get () if you really want zero for non-existent elements
                              return self.matrix[ij]
                              # If you don't use self.matrix.get () then you can eliminate matrix below (mostly)
                              # as shown here:

                              def __add__(self, other):
                              res = sm({}, self.row, self.col)
                              for i in range(self.row) :
                              for j in range(self.col) :
                              try: # does the left hand matrix have this element?
                              mine = self[(i, j)]
                              # Yes. try to get() from other or use zero
                              res[(i, j)] = mine + other.matrix.ge t((i, j), 0) # using a subclass avoids the .matrix
                              except KeyError: # No, does the right hand one?
                              try:
                              # yes. add it to the resulting matrix
                              res[(i, j)] = other[(i, j)]
                              except KeyError: # No
                              pass # do nothing
                              return res[/CODE]
                              And here it is as a subclass of built-in.dict using if and elif instead of nested try blocks:[CODE=python]
                              class smd(dict): # a dictionary like object
                              def __init__(self, mtx={}, m=0, n=0):
                              self.update(mtx )
                              self.row = m
                              self.col = n

                              def __add__(self, other):
                              res = smd({}, self.row, self.col)
                              for i in range(self.row) :
                              for j in range(self.col) :
                              if (i, j) in self: # does the left hand matrix have this element?
                              mine = self[(i, j)]
                              # Yes. try to get() from other or use zero
                              res[(i, j)] = mine + other.get((i, j), 0)
                              elif (i, j) in other: # No, does the right hand one?
                              # yes. add it to the resulting matrix
                              res[(i, j)] = other[(i, j)]
                              return res


                              sm_1 = smd({(3,2):4, (2,1):5, (2,2):6}, 7, 7)
                              sm_2 = smd({(3,2):1, (2,1):8, (4,4):6}, 7, 7)
                              smSum = sm_1 + sm_2
                              print smSum
                              # from dict.__str_()
                              {(3, 2): 5, (4, 4): 6, (2, 1): 13, (2, 2): 6}[/CODE]
                              Last edited by bartonc; Nov 11 '07, 04:09 PM.

                              Comment

                              Working...