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.


    True / False Variables in python

    Pythonista
    6
    12
    3502
    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.
    • mikael
      mikael @Seb last edited by mikael

      @Seb, please surround your code with three back ticks (```) to make it readable.

      Meanwhile, of course, there already is a function for the grouping. The following gives you a list of tuples, where the first item is the key pressed, and the second is how many times it was pressed.

      import itertools
      
      digits = [
          (key, len(list(grouper)))
          for key, grouper
          in itertools.groupby('4433555555666')
      ]
      
      print(digits)
      
      stephen 1 Reply Last reply Reply Quote 1
      • stephen
        stephen @mikael last edited by

        @mikael said:

        @Seb, please surround your code with three back ticks (```) to make it readable.

        I think it's would be like this..

        
        keys = '1223333'
        keylist = list(keys)
        global sameletter
        sameletter = True
        
        def splitter(keylist):
            split_letters = []
            buffer = []
            previousdigit = ''
            
            for digit in keylist:
                check_previous(digit, previousdigit)
                check_buffer_len(buffer, previousdigit)
                
            if sameletter == True:
                buffer.append(digit)
                previousdigit = digit
            else:
                split_letters.append(buffer)
                buffer.clear
                buffer.append(digit)
                previousdigit = digit
        
        print(split_letters) 
              
        def check_previous(digit, previousdigit):
            if digit != previousdigit:
                sameletter = False
        
        def check_buffer_len(buffer, previousdigit):
            if len(buffer) == 3:
                if previousdigit in {'7','9'}:
                    sameletter = True
                else:
                    sameletter = False
        
        splitter(keys)
        
        

        but i get

        NameError: name 'split_letters' is not defined

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

          @mikael said:

          @Seb, please surround your code with three back ticks (```) to make it readable.

          Meanwhile, of course, there already is a function for the grouping. The following gives you a list of tuples, where the first item is the key pressed, and the second is how many times it was pressed.

          import itertools
          
          digits = [
              (key, len(list(grouper)))
              for key, grouper
              in itertools.groupby('4433555555666')
          ]
          
          print(digits)
          

          Thanks! now edited.

          groupby is interesting, thanks for that suggestion. My original reasoning for splitting the digits up though, is if the string has ‘333333’ it would end up being ‘333’, ‘333’ and translate to ‘f’,’f’ eventually. However if it was ‘777777’ you can press 7 four times not three, so the grouping would end up ‘7777’, ‘77’.

          I am trying to find an elegant solution to splitting the numbers either when they change or when they’ve reached the repeat limit (and cycle to the next letter)

          If i run the groupby solution I would end up with (‘3’, 6), (‘7’, 6) which could be useful but would then still need splitting again, if you see what I mean?

          mikael 1 Reply Last reply Reply Quote 0
          • Seb
            Seb @stephen last edited by Seb

            @stephen said:

            but i get

            NameError: name 'split_letters' is not defined

            Thanks, have edited it now. Do you still get ‘split_letters’ is not defined? The code runs for me but I just get a blank output ‘[ ]’

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

              This post is deleted!
              1 Reply Last reply Reply Quote 0
              • 7upser
                7upser last edited by 7upser

                Some thoughts from my Side:

                You can iterate your Str keys, no need for keylist.
                In your Function you create a local variable sameletter. You dont change your global Variable.

                Add: global sameletter
                at the start of your functions
                or work with return

                And i dont like the Idea that there are two functions, called directly one after one, and both change the same variable. I think one function is better.

                1 Reply Last reply Reply Quote 0
                • mikael
                  mikael @Seb last edited by mikael

                  @Seb, others have given you good advice on progressing with your code. Especially good to understand that global is not something you declare at the top of the file, but something you use within a function to ”pull” a global variable into the function scope.

                  See below how I would complete the groupby approach. Note the convenience of a defined ”keypad” where I later added some Nordic letters without changing any code. Also please note the ”effect” test case I added to demonstrate the use of ”1” as a disambiguator.

                  (You can run the doctests by long-pressing on the play button in Pythonista.)

                  
                  import itertools
                  
                  
                  keypad = {
                      '1': '', '2': 'abcä', '3': 'def',
                      '4': 'ghi', '5': 'jkl', '6': 'mnoö',
                      '7': 'pqrs', '8': 'tuv', '9': 'wxyz',
                      '0': ' ',
                  }
                  
                  
                  def keypad_string(as_entered):
                      """
                          >>> keypad_string('12345')
                          'adgj'
                          >>> keypad_string('4433555555666')
                          'hello'
                          >>> keypad_string('2022')
                          'a b'
                          >>> keypad_string('')
                          ''
                          >>> keypad_string('111')
                          ''
                          >>> keypad_string('331333333332228')
                          'effect'
                          >>> keypad_string('21222266616666')
                          'aäoö'
                      """        
                      groups = [
                          [digit, len(list(grouper))]
                          for digit, grouper in itertools.groupby(as_entered)
                          if digit != '1'
                      ]
                      
                  
                      result = ''
                      for digit, count in groups:
                          letters = keypad[digit]
                          result += letters[-1] * (count // len(letters))
                          result += letters[:count % len(letters)][-1:]
                              
                      return result
                  
                  Seb 1 Reply Last reply Reply Quote 0
                  • Seb
                    Seb @mikael last edited by

                    @mikael
                    @7upser

                    Thank you both for your help. I am going to do some lessons on using return in functions as I’ve realised I don’t fully understand it.

                    7upser, I didn’t realise you could iterate without it being in a list so have removed that, and also simplified it so there isn’t two functions directly after each other changing the same variable. Is that something thats just ‘best practise?’ (Although just a fledgling hobby at the moment I don’t want to pick up bad habits)

                    Mikael that is a frustratingly short solution! I have a lot to learn. Thanks for your help.

                    Here is the code now it works :) I just need to convert to letters which i’ll look at shortly.

                    keys = '12233333333337777777777'
                    sameletter = True			
                    
                    def splitter(keys):
                    	global sameletter
                    	split_letters = []
                    	buffer = []
                    	previousdigit = ''
                    	for digit in keys:
                    		if digit in {previousdigit, "''"}:
                    			check_buffer_len(buffer, previousdigit)
                    		else: 
                    			sameletter = False
                    				
                    		if sameletter == True:
                    			buffer.append(digit)
                    			previousdigit = digit
                    		else:
                    			split_letters.append(buffer)
                    			buffer = []
                    			buffer.append(digit)
                    			previousdigit = digit
                    			
                    	split_letters.append(buffer)
                    			
                    	print(split_letters)		
                    			
                    	
                    def check_buffer_len(buffer, previousdigit):	
                    	global sameletter
                    	if len(buffer) < 3:
                    		sameletter = True
                    		return
                    	if len(buffer) < 4 and previousdigit in {'7','9'}:
                    		sameletter = True
                    	else:
                    		sameletter = False
                    mikael 1 Reply Last reply Reply Quote 0
                    • mikael
                      mikael @Seb last edited by

                      @Seb, thanks.

                      If we really focused on lines of code instead of readability, we could have:

                      
                      def keypad_string(as_entered):
                          return ''.join((
                              letters[-1] * (count // len(letters)) + 
                              letters[:count % len(letters)][-1:]
                              for digit, count, letters
                              in (
                                  (digit, len(list(grouper)), keypad[digit])
                                  for digit, grouper
                                  in itertools.groupby(as_entered)
                                  if digit != '1'
                              )
                          ))
                      
                      1 Reply Last reply Reply Quote 0
                      • 7upser
                        7upser last edited by 7upser

                        @mikael: jesus and wtf and a lot more... :)

                        @Seb,
                        I come from Basic (ZX81) and be sure i know nothing about best practice. I have only some experience.
                        Changing the same variable within 2 defs at the same section of code is a good error source.

                        And for Return, its easy you just return a value (or more).

                        def function1():
                        	variable1 = 'Hallo World'
                        	return variable1
                        
                        def function2(str1):
                        	return 'Hello ' + str1
                        
                        
                        print(function1())
                        print(function2('World')) 
                        
                        1 Reply Last reply Reply Quote 0
                        • lpoloyas
                          lpoloyas last edited by

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