omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    dialogs.form_dialog - I am having a problem with the result

    Pythonista
    dialogs
    4
    11
    6338
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by Phuket2

      @omz, I am just playing with the dialogs.form_dialog. Just putting a wrapper around it. But the result returned from the function is only the last field filled in. I am really not sure if I am using it wrong or if there is a bug. I am trying to be a little smarter than I normally am, and that maybe what is making it go wrong. But at least from what I can see, it should work.

      import dialogs
      from collections import namedtuple
      
      _form_fields = ['type', 'title', 'value', 'key', 'tint_color',
      				'icon', 'placeholder', 'autocorrection', 'autocapitalization']
      				
      DlgFld = namedtuple('DlgFld', _form_fields)
      DlgFld.__new__.__defaults__ = ('text', '', '', None, '', None, '', False, False)
      
      
      class UIFormSection(object):
      	def __init__(self, section='General', footer=None,  *args, **kwargs):
      		self.section = section
      		self.footer = footer
      		self.flds = []
      	
      	def add_field(self, **kwargs):
      		self.flds.append(DlgFld(**kwargs))
      	
      	def get_section(self):
      		return (self.section, [f._asdict() for f in self.flds], self.footer)
      		
      		
      class UIFormDialog(object):
      	def __init__(self, title='My Dialog', *args, **kwargs):
      		self.sections = []
      		self.title = title
      	
      	def add_section(self, sec_obj):
      		self.sections.append(sec_obj)
      		
      	def show(self):
      		section_lst = [s.get_section() for s in self.sections]
      		x = dialogs.form_dialog(title=self.title, sections=section_lst)
      		return x
      		
      				
      if __name__ == '__main__':
      	# create a my dialog object
      	dlg = UIFormDialog('Users Toops')
      	
      	# create a section for the dialog and add fields to it...
      	sec_user = UIFormSection('User Details')
      	
      	sec_user.add_field(type='text',
      						title='First Name',
      						placeholder='Enter First Name',
      						autocapitalization=True)
      					
      	sec_user.add_field(type='text',
      						title='Last Name',
      						placeholder='Enter Last Name',
      						autocapitalization=True)
      	sec_user.add_field(type='number',
      						title='Age',
      						placeholder='Enter Age')
      					
      	sec_user.add_field(type='password',
      						title='password',
      						placeholder='Users Password')
      					
      	sec_user.add_field(type='switch', title='Related')
      	
      	# create another section and fields
      	sec_troops = UIFormSection('Troops')
      	
      	sec_troops.add_field(type='number',
      							title='Infantry',
      							placeholder='Enter the number of Infantry troops')
      	sec_troops.add_field(type='number',
      							title='Ranged',
      							placeholder='Enter the number of Ranged troops')
      	sec_troops.add_field(type='number',
      							title='Cavalry',
      							placeholder='Enter the number of Cav troops')
      	
      	dlg.add_section(sec_user)
      	dlg.add_section(sec_troops)
      	
      	result = dlg.show()
      	print(result)
      
      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @Phuket2 last edited by cvp

        @Phuket2 Perhaps because all fields have the same key named "None"
        If you give a different key name to each field, it's ok

        Phuket2 1 Reply Last reply Reply Quote 1
        • Phuket2
          Phuket2 @cvp last edited by

          @cvp , thanks you are right. It's a little tricky. I removed the 'key' param from the namedtuple to get it to work. I am sure there is another way also. If key is not defined at all then the title is used as the key. If key is None, then the condition is not met for it to use the title.
          I will see if I can make it smarter so I can include the key param.
          Thanks again

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @Phuket2 last edited by

            @Phuket2 I just did the same...

            Phuket2 1 Reply Last reply Reply Quote 0
            • Phuket2
              Phuket2 @cvp last edited by

              @cvp , maybe this is a very easy problem to overcome if you are a python expert. I am not sure. But it seems that relying on attrs existence to set a another attr can limit pythons language abilities. I am not sure that is a correct statement or not. But would have been nice if it just workeked with key set to None

              cvp 1 Reply Last reply Reply Quote 0
              • cvp
                cvp @Phuket2 last edited by

                @Phuket2 In dialogs.py, if key parameter does not exist, it uses title, but nothing is foreseen if key is none...

                Phuket2 1 Reply Last reply Reply Quote 0
                • Phuket2
                  Phuket2 @cvp last edited by

                  @cvp , yes. That was my meaning. Just makes me think that if I have a API the same way, then it could limit how ppl use it. In this case seems hard to use nametuples as an intermediary data type to pass to the API. I am not trying to split hairs here, just trying to learn something. Eg. Is it a good pattern to check for the existence of a param to make decisions or maybe to do both check for the existence and None. It's tricky.

                  cvp 1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @Phuket2 last edited by cvp

                    @Phuket2 Sorry, I can't help, I never used nametuples...

                    1 Reply Last reply Reply Quote 0
                    • enceladus
                      enceladus last edited by enceladus

                      You have already identified the problem and may be you have solutions. Anyway here are some suggestions.

                      1. Use a wrapper function on _asdict to remove key if its value is None

                      2. The documented way to process default values is to use _replace function.

                      import dialogs
                      from collections import namedtuple
                      
                      _form_fields = ['type', 'title', 'value', 'key', 'tint_color',
                                      'icon', 'placeholder', 'autocorrection', 'autocapitalization']
                                      
                      DlgFld = namedtuple('DlgFld', _form_fields)
                      #DlgFld.__new__.__defaults__ = ('text', '', '', None, '', None, '', False, False)
                      default_dlgfld = DlgFld('text', '', '', None, '', None, '', False, False)
                      
                      def as_dict_removekeyifnone(f):
                          f1 = f._asdict()
                          if f1['key'] is None:
                              del f1['key']
                          return f1
                      
                      
                      class UIFormSection(object):
                          def __init__(self, section='General', footer=None,  *args, **kwargs):
                              self.section = section
                              self.footer = footer
                              self.flds = []
                          
                          def add_field(self, **kwargs):
                              self.flds.append(default_dlgfld._replace(**kwargs))
                          
                          def get_section(self):
                              return (self.section, [as_dict_removekeyifnone(f) for f in self.flds], self.footer)
                              
                              
                      class UIFormDialog(object):
                          def __init__(self, title='My Dialog', *args, **kwargs):
                              self.sections = []
                              self.title = title
                          
                          def add_section(self, sec_obj):
                              self.sections.append(sec_obj)
                              
                          def show(self):
                              section_lst = [s.get_section() for s in self.sections]
                              x = dialogs.form_dialog(title=self.title, sections=section_lst)
                              return x
                              
                                      
                      if __name__ == '__main__':
                          # create a my dialog object
                          dlg = UIFormDialog('Users Toops')
                          
                          # create a section for the dialog and add fields to it...
                          sec_user = UIFormSection('User Details')
                          
                          sec_user.add_field(type='text',
                                              title='First Name',
                                              key='First Name',
                                              placeholder='Enter First Name',
                                              autocapitalization=True)
                                          
                          sec_user.add_field(type='text',
                                              title='Last Name',
                                              key='Last Name',
                                              placeholder='Enter Last Name',
                                              autocapitalization=True)
                          sec_user.add_field(type='number',
                                              title='Age',
                                              placeholder='Enter Age')
                                          
                          sec_user.add_field(type='password',
                                              title='password',
                                              placeholder='Users Password')
                                          
                          sec_user.add_field(type='switch', title='Related')
                          
                          # create another section and fields
                          sec_troops = UIFormSection('Troops')
                          
                          sec_troops.add_field(type='number',
                                                  title='Infantry',
                                                  placeholder='Enter the number of Infantry troops')
                          sec_troops.add_field(type='number',
                                                  title='Ranged',
                                                  placeholder='Enter the number of Ranged troops')
                          sec_troops.add_field(type='number',
                                                  title='Cavalry',
                                                  placeholder='Enter the number of Cav troops')
                          
                          dlg.add_section(sec_user)
                          dlg.add_section(sec_troops)
                          
                          result = dlg.show()
                          print(result)
                      
                      Phuket2 1 Reply Last reply Reply Quote 1
                      • Phuket2
                        Phuket2 @enceladus last edited by

                        @enceladus , thanks for taking the time to explain. The defaults look at lot better the way you have done them (I think I seen the way I used in stackflow one time and have used that way, goes to show you should look at multiple sources). I understand your dict attr del, I just question @omz reasoning behind this approach. Not to be a smart ass. Just to learn. I do all sort of weird things at times (well all the time). It just really points out to me how important it is to think about inferences/rules made with Params. Look, maybe what @omz has done is actually very Pythonetic, I am certainly in no position to correct him.
                        Anyway, thanks again. I am just playing with this wrapper around dialogs.form_dialog. I am going to try to add some persistence to it using shelve I think. Sure I will run into more troubles, so I will be back :)

                        1 Reply Last reply Reply Quote 0
                        • ccc
                          ccc last edited by

                          This post is deleted!
                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Powered by NodeBB Forums | Contributors