Log in

I don't know how to condense this code

  • 27 Mar

I've been trying to condense this for a while and I can't figure out how to condense it more. It is for the vault when you build it. I'm tying to get is below 200 characters.

def golf(password):
    if len(password) >= 10:
        apart = list(password)
        stuff = ['abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ']
        for item in apart:
            if item in stuff[0]:
                small = True
            elif item in stuff[1]:
                big = True
            else:
                number = True

            try:
                if small and big and number:
                    break
            except UnboundLocalError:
                continue
        else:
            return False

        return True
    else:
        return False
  • 3
  • 29 Mar

Five tips:

  • Relabel variable names to all single-letter ones (perhaps you did this already but left them long for clarity of intent in your post, which is fine.)
  • Use the .lower() method to get the lowercase version of the alphabet rather than typing a second 26-character version of it in a list of strings.
  • Get rid of the try/catch and simplify the control flow for the return statements so you only have the bare minimum 2 cases you need, either return True or return False.
  • Rather than using words "True"/"False" repeatedly, assign them to 1-letter variables once, up-front, and use the 1-letter variables instead.
  • Avoid unneeded indented spaces/lines by setting multiple variables at once (e.g. "a=b=True") separated by semicolons, and put single-line if-clause actions immediately following the colon rather than on a second line.

With those five tricks, I was able to get your approach under 200 chars (see below for spoiler).

To get it under 100 chars, you might need use the re regex module and write it as a lambda.

def golf(p):
 a=list(p);l=b=n=f=False;t=True;s='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
 if len(p)>=10:
  for i in a:
   if i in s:b=t
   elif i in s.lower():l=t
   else:n=t
  if l and b and n:
   return t
 return f
  • 16 Apr

gregw1's answer will help you condense your code quite a bit, but you can add the following to condense it further.

First: use re module to lower your char count and simplify your code:
from re import match as m

Second: turn ['abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] into "[a-zA-Z0-9]+" or "[a-zA-Z\d]+".

Then use m("[a-zA-Z0-9]+",password) to test for alphanumeric strings.

Depending on how you want to implement it you may want to edit my regex example to fit your needs.

Hope this helps some, happy coding.

  • 1
  • 16 Apr

I have implemented the regex library into my code. I am wondering what is the 'm' for in front of your regex search function. I haven't seen anyone use that before. Also, here is my current code.

import re
def golf(p):
 if len(p)>=10:
  if re.search(r'[a-z]+',p)and re.search(r'[A-Z]+',p)and re.search(r'[0-9]+',p):return True
  return False
 return False

It is 13 characters over 100. AARRRGG!!!!!

  • 1
  • 21 Apr

The "from re import match as m" in the prior poster's suggestion (rather than the "import re" shown in your code) allowed them to call just m() rather than re.match() 3 times.

Similarly you could use "from re import search as s" and then call s() rather than re.search(). The import takes more characters but you save some characters overall if you call the function multiple times.

Or stick with the "import re" but create a new one-char function name aliased to the longer function name via "s=re.search" which should behave similarly.

P.S. Also, you probably only need one "return False", right?

  • 22 Apr

I have taken into account all of the information you have given me and have gotten it down to this code. The last character count was a bit under counted and a recount has found that this code is 35 characters over the character limit.

import re
def golf(p):
 if len(p)>=10:
  s=re.search
  if s(r'[a-z]+',p)and s(r'[A-Z]+',p)and s(r'[0-9]+',p):return True
 return False
  • 24 Apr

A couple points to improve (I'm not going to just give the answer):

a) >=10 can be reduced by looking at just greater than (saves 2 chars)
b) s=re.search does not need to be in the function (saves 2 chars)
c) Your if statements can be combined (saves 1 char)
d)

if isValid(p) == True: return True
elif isValid(p) == False: return False

can be reduced to a single return statement. (saves 21 chars)

e) If you can get this function down to a single return statement, you may want to look at lambda functions (saves 6 chars)

This should get you just under 100 chars (97 chars total by my counter. Not sure about the one on here).

Another option is to use a more complex regex. (saves ~10 chars)

  • 24 Apr

1) You have only taken advantage of half my original advice of "To get it under 100 chars, you might need use the re regex module and write it as a lambda." Learn how to write it as a lambda; this will help you get rid of those verbose many-character "return True"/"return False" parts. It might be easier to see how to create the lambda after answering and addressing the two following questions/simplifications.
2) Un-indent any "initialization" logic you can by moving it outside the function or nesting its in. This helps eliminate some or all of the indentation space characters. Is there any logic you can do that with? I see one line you can move!
3) Can you simplify your if clauses? Do you really need two separate if clauses?

Also,
4) I don't think you need either the "r" or the "+" you have in your search/s function calls
5) The expression ">=10" can be shortened, if you think about it

Reply