1

so, my code for a vector class is this:

minimal:

class MyVector:
    def __init__(self, vname_id="pizza", vcolour="pizza", vtype=4, vvalues=np.array([None])):
        if not(isinstance(vname_id,str)):
            raise AttributeError("You did not enter a word. Please do so next time :(")
        self.__name_id = vname_id
        if not(isinstance(vcolour,str)):
            raise AttributeError("You did not enter a word. Please do so next time :(")
        self.__colour = vcolour
        if not(isinstance(vtype,int)):
            raise AttributeError("You did not enter a number. Please do so next time :(")
        self.__type = vtype
        self.__values = vvalues
    def setName_id(self, vname_id):
        if not(isinstance(vname_id,int)):
            raise AttributeError("You did not enter a number. Please do so next time :(")
        self.__name_id = vname_id
    def setColour(self, vcolour):
        if not(isinstance(vcolour,str)):
            raise AttributeError("You did not enter a word. Please do so next time :(")
        check=0
        ColourList=["r",'g','b','y','m']
        for elem in ColourList:
            if vcolour==elem:
                self.__colour=vcolour
                check=1
                break
        if check==0:
            print("\nSorry, forgot to tell you that the colour has to be between:\n\n\t-> red (type `r`)\n\t-> green (type `g`)\n\t-> blue (type `b`)\n\t-> yellow (type `y`)\n\t-> magenta (type `m`)\nPlease try again.")
            time.sleep(2)
            print("I will show you the main menu in a moment.")
            time.sleep(3)
        self.__colour = vcolour
    def setType(self, vtype):
        self.__type = vtype
    def setValues(self, listnumbers):
        for elem in listnumbers:
            if not(isinstance(elem,int)):
                raise ValueError
        self.__vvalues=np.array(listnumbers)
    def GetValues(self):
        return self.__values
    def getName_id(self):
        return self.__name_id
    def getColour(self):
        return self.__colour
    def getType(self):
        return self.__type
    def __str__(self):
        return "Vector with the ID " + str(self.__name_id) + ", of colour " + str(self.__colour) + " and made from type " + str(self.__type) + ", is " + str(self.__vvalues)

Now, that's how the vector is supposed to be. My question is that i need to make a function that reads every id in a list and updates it. My only problem is recognizing the id. I tried multiple ways and got here:

class VectorRepository():
    def __init__(self, l=[]):
        self.__vector_list=l
    def updateIDChoice(self,nameid,v):
        for index, elem in enumerate(self.__vector_list):#vector_list is the list that contains every vector made
            if elem.getName_id()==nameid:#nameid is the id given by the user
                self.__vector_list[index].setName_id(v)#v is the newly created vector

and im using this function:

def updateByID(VectorRepository):
    if len(VectorRepository.getList())==0:
        print("~~~~~~~~~~~~~\n\t The list appears to be empty! :( \n~~~~~~~~~~~~~")
    else:
        try:
            v=MyVector()
            values=[]
            nameid=int(input("\tPlease enter the id: "))
            choiceid=int(input("\tpls enter for id: "))
            if choiceid < 0:
                raise ValueError("Your number needs to be positive. Like Superman!")
            v.setName_id(choiceid)
            choicecolour=str(input("\tpls enter for colour: "))
            check=0
            ColourList=["r",'g','b','y','m']
            for elem in ColourList:
                if choicecolour==elem:
                    v.setColour(choicecolour)
                    check=1
                    break
            if check==0:
                raise ValueError("\nSorry, forgot to tell you that the colour has to be between:\n\n\t-> red (type `r`)\n\t-> green (type `g`)\n\t-> blue (type `g`)\n\t-> yellow (type `y`)\n\t-> magenta (type `m`)\nPlease try again in a moment.")
            v.setColour(choicecolour)
            choicetype=int(input("\tpls enter for type: "))
            v.setType(choicetype)
            if choicetype < 1:
                raise ValueError("Your number needs to be 1 or greater!")
            n=int(input("\tVectors can have many different values. How many values do you want this vector to have?\n\t>>> "))
            for choice in range(0, n):
                print("\tEnter the value for value",choice+1,": ")
                choice = int(input("\t>>>")) 
                values.append(choice)
            v.setValues(values)
            VectorRepository.updateIDChoice(nameid,v)
        except:
            print("\tSorry, you did something wrong and i froze. Please read the rules and try again!")

So, by using the function, the user inputs a id, then creates a new vector. if the id is the same with one already made, it overwrites that one with the newly created one. But again, it doesn't recognize any id saved. Any ideas im missing?

Barmar
  • 741,623
  • 53
  • 500
  • 612
HyperOni
  • 81
  • 5
  • You almost certainly don't want this default value: `vvalues=np.array([])`. All instances created with the default will share the same array `__values` attribute. – Barmar Dec 01 '20 at 01:37
  • Don't put `v` in quotes. And you don't need to use `enumerate()`. You canjust use `elem.setName_id(v)` – Barmar Dec 01 '20 at 01:40
  • Thanks for the heads up on my mistakes! sadly, the problem still persists. It doesn't recognize the id given to be the same with any of the one from the list. – HyperOni Dec 01 '20 at 01:53
  • Please post a [mcve]. – Barmar Dec 01 '20 at 01:53
  • Why does `getName_id()` have a `vname_id` parameter, which it doesn't use? And why aren't you passing that argument when you call it? You should be getting an error from that. – Barmar Dec 01 '20 at 01:56
  • All the `getXxx` methods have an extra parameter that they never use. Why? – Barmar Dec 01 '20 at 01:56
  • Good points! Don't know how i missed that one, to be honest. This code is taken from my old projects. I've updated the original post with a minimal. Hope that helps you. – HyperOni Dec 01 '20 at 02:11
  • Don't use `l=[]` as the default value for `VectorRepository`. See https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument – Barmar Dec 01 '20 at 02:15
  • Ah,yes. I added the wrong one. Kinda tired since it's 4:18 am in my country. Sorry about that. – HyperOni Dec 01 '20 at 02:19
  • Why do you have both `nameid` and `choiceid`? You're putting `choiceid` into the new object, but searching for `nameid` in the repository. – Barmar Dec 01 '20 at 02:24
  • The argument to `setName_id()` is supposed to be an integer, but `v` is a vector. – Barmar Dec 01 '20 at 02:26
  • Why does `VectorRepository` contain a list instead of a dictionary whose keys are the names? – Barmar Dec 01 '20 at 02:27

2 Answers2

1

The argument to setName_id() is supposed to be an integer, but v is a vector. You need to replace the whole element of the list with the new vector, not just set its name.

class VectorRepository():

    def __init__(self, l=None):
        self.__vector_list = [] if l is None else l

    def updateIDChoice(self,nameid,v):
        for index, elem in enumerate(self.__vector_list): that contains every vector made
            if elem.getName_id()==nameid:
                self.__vector_list[index] = v
                break
        else:
            raise ValueError(f"Element {nameid} not found")

I also fixed how you initialize __vector_list with the default value so you don't get the same list in all repositories.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you for your input! Clearly it makes much more sense now, but sadly, it still doesnt work. I think i will go to sleep and have another look in the morning :( – HyperOni Dec 01 '20 at 02:47
  • You still haven't provided a [mcve]. Show how you're adding the element that you want to update. – Barmar Dec 01 '20 at 02:52
  • I'm having trouble installing the necessities to make a minimal example. Do you think this can be taken into private? maybe we can find some other way for me to show you. – HyperOni Dec 01 '20 at 03:31
0

Uh, after some trial and error, this edit made my program work like intended!

def updateIDChoice(self,nameid,v):
        index=0
        for elem in (self.__vector_list):
            if elem.getName_id()==nameid:
                self.__vector_list[index]=v
                break
            index+=1
        else:
            raise ValueError("Element not found")

Thanks, Barmar, for your help!

HyperOni
  • 81
  • 5
  • The only difference between your answer and mine is that you increment `index` yourself, I use the built-in `enumerate()`. The result should be the same. – Barmar Dec 03 '20 at 15:33