1

I've hit a problem calling a function inside a class. The code fragment is:

    class CharacterGenerator(GridLayout):

        def printcharacter(self,my_sb,my_cr,my_scm,my_scb):
            printable_stats = print_stats(my_sb)
            printable_rolls = print_rolls(my_cr)
            printable_scm = print_scm(my_scm)
            printable_scb = print_scb(my_scb)

    #       self.clear_widgets()
            layout=BoxLayout(orientation='vertical')
            stat_box=(Label(text_size=(300, None),
                    text='Stats\n' + str(printable_stats)))
            rolls_box=(Label(text_size=(300, None),
                    text='Rolls\n' + str(printable_rolls)))
            scm_box=(Label(text_size=(300, None),
                    text='SCM\n' + str(printable_scm)))
            scb_box=(Label(text_size=(300, None),
                    text='SCB\n' + str(printable_scb)))

            layout.add_widget(stat_box)
            layout.add_widget(rolls_box)
            layout.add_widget(scm_box)
            layout.add_widget(scb_box)
            wayout = Button(text='Way Out')
            layout.add_widget(wayout)

        def human(self,a,b):
            if b==True: 
                self.Status="human"
                race=self.Status
                statblock = human()
                characteristic_rolls = rolls(statblock)
                skill_category_modifiers = scm(statblock)
                skill_category_bonuses = scb(statblock)
                CharacterGenerator.printcharacter         (self,     statblock, characteristic_rolls, skill_category_modifiers, skill_category_bonuses)

It errors with:

       File "./charactergenerator.kv", line 36, in <module>
         on_press: root.printcharacter()
     TypeError: printcharacter() missing 4 required positional arguments: 'my_sb', 'my_cr', 'my_scm', and 'my_scb'

As far as I can tell, I am sending the right parameters to the printcharacter function. The same function and call work with printcharacter in a separate python module.

I've tried all combinations of the calling parameters, added and removed some from the list. Without the CharacterGenerator.printcharacter call, all I get is the message that CharacterGenerator has no object printcharacter and I'm back to square one.

Can anyone see where I'm going wrong?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Colin Brett
  • 47
  • 2
  • 6
  • Here is the kv file. I really can't get the formatting correct on this site :( `: cols: 2 canvas: Color: rgb: .2,.2,.2 Rectangle: pos: self.pos size: self.size Label: text: 'Human' CheckBox: group: 'race_group' on_active: root.human(*args) Button: text: 'Next' on_press: root.printcharacter()` – Colin Brett Jul 17 '16 at 09:47
  • you should put it in your question. paste it, then highlight it all, and press ctrl+k – el3ien Jul 17 '16 at 09:48
  • what shall `my_sb,my_cr,my_scm,my_scb` be, when called from your .kv file. (When you press the "Next" Button)? – el3ien Jul 17 '16 at 10:11

2 Answers2

0

Your error seems to be in your charactergenerator.kv on line 36.

There you call the function, "on_press: root.printcharacter()" without parameters.

So call the function with parameters.

And change this line

def printcharacter(self,my_sb,my_cr,my_scm,my_scb):

to

def printcharacter(self,my_sb,my_cr,my_scm,my_scb,*args):

el3ien
  • 5,362
  • 1
  • 17
  • 33
  • I've changed line 36 to: `on_press: root.printcharacter(statblock,characteristic_rolls,skill_category_modifiers,skill_category_bonuses)` but now get the error ` TypeError: printcharacter() takes 4 positional arguments but 5 were given` – Colin Brett Jul 17 '16 at 09:53
  • I changed KV line 36 back to `on_press: root.printcharacter()` and the definition to `def printcharacter(my_sb,my_cr,my_scm,my_scb,*args):` . Now I get the error " File "brp_chargen.py", line 26, in printcharacter printable_stats = print_stats(my_sb) File "/home/colin/PROJECTS/programming/pythondev/learn_python/kivy/brp_chargen_02/brp_stats.py", line 50, in print_stats s = s + stat + " [" + str(mystats[stat]) + "] " TypeError: 'CharacterGenerator' object is not subscriptable" .(PS I didn't downgrade your first answer). – Colin Brett Jul 17 '16 at 10:01
  • @ColinBrett I did not say it was you. Anyways. dont change the line in the .kv file back. only the one with *args. BTW are my_sb,my_cr,my_scm,my_scb accesable in your kv file. ? – el3ien Jul 17 '16 at 10:03
  • The KV file looks like this now `on_press: root.printcharacter(statblock,characteristic_rolls,skill_category_modifiers,skill_category_bonuses)` . The function def looks like `def printcharacter(my_sb,my_cr,my_scm,my_scb):` . I get the error: ` File "./charactergenerator.kv", line 36, in on_press: root.printcharacter(statblock,characteristic_rolls,skill_category_modifiers,skill_category_bonuses) NameError: name 'statblock' is not defined` . None of the variables (statblock, my_sb and so on) are "visible" to the KV file. How do I do this? – Colin Brett Jul 17 '16 at 11:02
  • @ColinBrett the answer says, `def printcharacter(self,my_sb,my_cr,my_scm,my_scb,*args):` – el3ien Jul 17 '16 at 11:15
  • I changed the definition to `def printcharacter(self,my_sb,my_cr,my_scm,my_scb,*args):` . Now the error reads `TypeError: printcharacter() missing 1 required positional argument: 'my_scb'` . So some of the positional arguments are being recognised, just one is "missing". The KV file reads `on_press: root.printcharacter()` – Colin Brett Jul 17 '16 at 11:24
  • @ColinBrett Can you plz show your whole .kv file in your question. Not in the comment section. – el3ien Jul 17 '16 at 11:26
  • Can I post the kv file elsewhere? – Colin Brett Jul 17 '16 at 11:29
  • @ColinBrett yes `dpaste.com` – el3ien Jul 17 '16 at 11:32
-1

Use self to call function, in code CharacterGenerator.printcharacter(self, ...- you aren't passing self as first argument, so proper printcharacter call suppose to be:

self.printcharacter(statblock, characteristic_rolls, skill_category_modifiers, skill_category_bonuses)

You can read more about self on What is the purpose of self?.

Shortly: if you defined method within class definition without staticmethod or staticclass decorator it would accept class instance method was called on as first argument ( by convention that first argument called self), that argument shouldn't be passed directly as it would be passed automatically when instance method would be called.

I've noticed that printcharacter method doesn'y operate with self, so you can define it as staticmethod:

class CharacterGenerator(GridLayout):

    @staticmethod
    def printcharacter(my_sb,my_cr,my_scm,my_scb):
        # method body

And call it next way:

# within execution of instance method
self.printcharacter(statblock, characteristic_rolls, skill_category_modifiers, skill_category_bonuses)
# Anywhere outside class method 
CharacterGenerator.printcharacter(statblock, characteristic_rolls, skill_category_modifiers, skill_category_bonuses)
Community
  • 1
  • 1
Andriy Ivaneyko
  • 20,639
  • 6
  • 60
  • 82
  • I used your code and changed the function def to `def printcharacter(my_sb,my_cr,my_scm,my_scb):` . Now I get the error: ` TypeError: printcharacter() takes 4 positional arguments but 5 were given` – Colin Brett Jul 17 '16 at 09:50
  • @ColinBrett Add @staticmethod decorator if that function shouldn't operate with `self` attribute, i've updated answer.. – Andriy Ivaneyko Jul 17 '16 at 09:51
  • I've never used static methods. I tried ` def @printcharacter(my_sb,my_cr,my_scm,my_scb):` but this gave an "invalid syntax" error. – Colin Brett Jul 17 '16 at 09:56
  • @ColinBrett yeah, there are syntax error, see part of my answer to get proper way of adding staticmethod decorator – Andriy Ivaneyko Jul 17 '16 at 09:59
  • This is not answering his question or solving the error. Its more like a tutorial on static methods – el3ien Jul 17 '16 at 10:01
  • I've tried Andriy's suggestions. `@staticmethod def printcharacter(my_sb,my_cr,my_scm,my_scb):` and call with ` CharacterGenerator.printcharacter(statblock,characteristic_rolls,skill_category_modifiers,skill_category_bonuses)` which gives the error: " File "./charactergenerator.kv", line 36, in on_press: root.printcharacter() TypeError: printcharacter() missing 4 required positional arguments: 'my_sb', 'my_cr', 'my_scm', and 'my_scb'". So I guess the kv file needs to be updated to include the parameters but how do I reference them from the py file? – Colin Brett Jul 17 '16 at 10:07
  • @AndriyIvaneyko. There is no charactergenerator.py file. The only way I can reference the printcharacter routine is by prefixing the CharacterGenerator class. – Colin Brett Jul 17 '16 at 10:57
  • @EL3PHANTEN you are right, answer giving answer of how to use static method decorator. However fact that suggestion to use decorator needs more text to explain than suggestion for properly passing argument which is suppose to fix OP problem doesn't make that answer tutorial... Have a good day ) – Andriy Ivaneyko Jul 17 '16 at 11:53
  • Thank you. Good day to you too :) – el3ien Jul 17 '16 at 11:59
  • @ColinBrett the problem there is obviously, that thos variables are not accessible in your kv file. What are those? where do you expect to get the values from? – el3ien Jul 17 '16 at 12:08
  • The variables are created by the call at the end of def human, the line reading `CharacterGenerator.printcharacter(statblock,characteristic_rolls,skill_category_modifiers,skill_category_bonuses)` . The whole function is posted at the start of this thread. How do I make the variables visible to the kv file? – Colin Brett Jul 17 '16 at 12:11
  • @ColinBrett `from kivy.properties import StringProperty` then in the beginning of your class you instantiate them as so `my_sb = StringProperty()` then in your .kv file you acces by `root.my_sb` – el3ien Jul 17 '16 at 12:16
  • @ColinBrett and in human you do `self.my_sb = characteristic_rolls` and remove that CharacterGenerator.printcharacter call – el3ien Jul 17 '16 at 12:18
  • @ColinBrett as the matter of fact your approach to this app is kind of wrong. Take a look at the pong game tutorial https://kivy.org/docs/tutorials/pong.html – el3ien Jul 17 '16 at 12:25
  • @EL3PHANTEN . Thanks for the assist. Looks like I'll have to rewrite some of my code in line with the Pong tutorial. Colin. – Colin Brett Jul 17 '16 at 12:48