1

Here is an exercise: Define a function postalValidate(S) which first checks if S represents a postal code which is valid:

  • first, delete all spaces;
  • the remainder must be of the form L#L#L# where L are letters (in either lower or upper case) and # are numbers.
  • If S is not a valid postal code, return the boolean False.
  • If S is valid, return a version of the same postal code in the nice format L#L#L# where each L is capital.

And here is one of the numerous trials:

def postalValidate(S):
    for x in S:
        if x == " ":
            S = S.remove(x)
            if x.isalpha():
                x = x.upper()
                if x.isalpha() or ix.isdigit():
                    if ((S.index(x) % 2 == 0) and x.isalpha()) or ((S.index(x) % 2 != 0) and x.isdigit()):
                        pass
                    else:
                        print(False)
                        break
                        return(False)
                else:
                    print(False)
                    break
                    return(False)
            elif x.isdigit:
                pass
            else:
                print(False)
                break
                return(False)

        elif x.isalpha():
            if S.index(x) % 2:
                pass
            else:
                break
                return(False)
        elif x.isdigit():
            if S.index(x) % 2 == 1:
                pass
            else:
                break
                return(False)
        else:
            break
            return(False)
            pass
    print(S)
    return(S)

What is my error?

kouty
  • 320
  • 8
  • 17

5 Answers5

1

I can tell you that it would be more efficient to simply split the string into an array, and then just check the type of each individual character. You could do it with a single for loop, and simply have a modulus conditional to determine whether it is in an odd or even index. You could also simply have 6 if statements.

Overall it would look like split string for (i is less that 6) check if even or odd. If even - letter, check to see if this index is a char If odd - number, check to see if this index is a number

Let me know if this helps.

mattegener
  • 159
  • 1
  • 3
  • 11
1

Mike's suggestion re: regular expressions is a good one; I unfortunately have a couple of problems with his answer which didn't format well as a comment:

  1. You still need to remove spaces (and it's not clear but not ruled out that these spaces can exist inside the letters (so e.g. A1 B2 C3 would be valid)
  2. You're supposed to, if it's valid, returned a cleaned up version.

May I suggest:

vals = re.findall(r'([a-zA-Z]\d)', string) # this returns an array of all the pairs of letter + number.
if len(vals) != 3: # if there aren't exactly 3 pairs, this isn't valid
  return false
return "".join([v[0].upper+v[1] for v in vals] #uppercase the letter, and combine the 3 pairs as a string
Foon
  • 6,148
  • 11
  • 40
  • 42
  • Also, one big issue with your intended approach is that you loop through the string and change the string in place. That's a big no-no in most languages that use iterators. – Foon Mar 11 '15 at 23:54
  • I don't understand. But I'm sure that is one of the error's root in my trials. One of the trials was to create one function for each stepp and to call one after another each functhon but I don't know how to be sure that the upper transformed string falls as argument to the next method.Can you explain or give a reference? – kouty Mar 12 '15 at 22:32
1

Your program is way more complicated than it needs to be.

You already have listed the steps that you want to perform, let's translate them to Python code:

def postalValidate(S):
    # first, delete all spaces
    S = ''.join(S.split())

    # the remainder must be of the form L#L#L# where L are letters (in either lower or upper case) and # are numbers.
    # If S is not a valid postal code, return the boolean False.
    if len(S) != 6:
        return False
    if not (all(S[i].isalpha() for i in [0, 2, 4]) and
            all(S[i].isdigit() for i in [1, 3, 5])):
        return False

    # If S is valid, return a version of the same postal code in the nice format L#L#L# where each L is capital.
    return S.upper()

There are ways to do the same thing with less code, but I wanted to keep it simple.

Edit: used method to remove all spaces from a string shown in answers to this question.

Community
  • 1
  • 1
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 1
    `S = S.replace(" ", '').upper()` is probably a bit clearer no? – aychedee Mar 12 '15 at 00:07
  • I agree that `replace` is clearer, however it doesn't handle tabs and linebreaks. Also I wanted to do `upper` in the last step to follow OP's algorithm. – mkrieger1 Mar 12 '15 at 00:09
  • mkrieger1 your solution is very concise and good. Next I ask myself if instead a len(S) preevaluated as for i %(I mean shat it's not necessary to assert i % 2 == 0 and the same for (i + 1) % 2 for the digit. – kouty Mar 12 '15 at 22:14
0
import string

# Create translation table:
#   convert lowercase to uppercase, and remove spaces
TRANS = str.maketrans(string.ascii_lowercase, string.ascii_uppercase, " ")

# char identity tests
TESTS = [str.isalpha, str.isdigit] * 3

def postal_validate(s):
    # clean string
    s = s.translate(TRANS)
    # test whether it is a valid postal code
    if len(s) == 6 and all(test(ch) for ch,test in zip(s, TESTS)):
        # if so, return it
        return s
    else:
        # otherwise return False
        return False
Hugh Bothwell
  • 55,315
  • 8
  • 84
  • 99
0
"""this is my code:"""

    def simplifier(S):
    S = str(S)
    x = " "
    S = S.replace(x, "")
    return(S)
def majusculiser(S):
    S = str(S)
    for x in S:
        if str(x).isalpha():
            S = (S.replace(x, x.upper()))
    return(S)
def purifier(S):
    S = str(S)
    for x in S:

        if (not x.isdigit()) and (not x.isalpha()):
            return(False)
    else:
        return(S)
def verifier_les_impairs(S):
    S = str(S)
    l = len(S)
    for x in range (0, l, 2):
        if not str(x).isalpha:
            return(False)
        else:
            return(S)
def verifier_les_pairs(S):
    S = str(S)
    l = len(S)
    for x in range (1, l, 2):
        if not str(S[x]).isdigit():
            return(False)
        else:
            return(S)
def postalValidate(S):
    S = simplifier(S)
    if True:
        S = purifier(S)
        S = majusculiser(S)
        if (len(S) + 1) % 2 == 0:
            return(False)
        if True:
            S = verifier_les_impairs(S)
            if True:
                S = verifier_les_pairs(S)
                if True:

                    return(S)
                else:
                    return(False)
            else:
                return(False)
        else:
            return(False)
print(postalValidate('n2l 3g1z'),
postalValidate('postal'),
postalValidate('H0H0H0H0'),
postalValidate(' e3g 7k 0 l5G 6'),
postalValidate('5/ B?7t8'))

Very length but very easy.
kouty
  • 320
  • 8
  • 17