简体   繁体   中英

Python Challenge level 3. Why isn't my code working?

So I know this is very dirty and probably inefficient code, but I was just trying to see if I could get it to work. I just don't understand why it's not working... The text from the file I'm accessing is in the source of http://www.pythonchallenge.com/pc/def/equality.html . Any help?

#! /usr/bin/python

# This program searches a string for a lowercase letter that has 3, and only 3,
# uppercase letters to the left of it, and 3, and only 3, uppercase letters to
# the right of it. It then returns that lowercase letter.

from string import lowercase
from string import uppercase

# Open the text file containing the string and set it to variable str
fileHandle = open ( 'bodyguards.txt', 'r' )
str = fileHandle.read()
fileHandle.close()
#str = 'BIGaBIGaBIGaBIG'

# Search for a lowercase letter.
def isitlower(str):
    for a in str :
        if a in lowercase:
            letterposition = str.index(a) 
            r =threebgright(letterposition)
            l =threebgleft(letterposition)
            if r !=None and l !=None:
                print l,":",a,":", r

def threebgright(letterposition):
    if str[letterposition + 1] in uppercase and str[letterposition +2] in uppercase and         str[letterposition + 3] in uppercase and str[letterposition + 4] not in uppercase:
        return str[letterposition+1], str[letterposition+2], str[letterposition+3]
    else:
        return None

def threebgleft(letterposition):
    if str[letterposition - 1] in uppercase and str[letterposition -2] in uppercase and     str[letterposition - 3] in uppercase and str[letterposition - 4] not in uppercase:
        return str[letterposition-1], str[letterposition-2], str[letterposition-3]
    else:
        return None

isitlower(str)

This will find the index of the first occurrence of a in str:

letterposition = str.index(a)

Probably not what you want. The correct way would be to use enumerate :

def isitlower(my_str):
    for a, letter_position in enumerate(my_str):
        if a in lowercase:
            r =threebgright(letterposition)
            l =threebgleft(letterposition)
            if r !=None and l !=None:
                print l,":",a,":", r

It's a good idea not to use str as a variable name since it's a builtin type / function

One of the many benefits of python is regular expressions. Regex in python can be accessed by importing the re module.Your answer is too complex , tiring and inefficient.It's best to follow KISS (Keep it simple and small). An easier solution would be :

data = " All that huge text "

bodyguarded = re.findall('[^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]')
print "".join(bodyguared)

Explaination :

[^A-Z]

Bear in mind that there should be exactly 3 big letters sourounding the small one. If we removed this, things like 'SJDHjHDG' would come to be correct. What this is basically doing is that it doesn't want any caps before the occurence of the three caps which is defined by [AZ]{3}.

Next is ([az]) . This is how you define the single lowercase letter in the middle. Notice how it doesn't have an {x} next to it.This is because we only want one occurence. For example : 'ABCjjKLM' is not correct since the lowercase chars in the middle are more than one.

We want the lowercase letter to be sourrounded and therefore we want another 3 occurences on the right side ( [AZ]{3} ), but no more , and that's why we add [^AZ] . As i explained earlier cases like 'AJDkKLKM' or 'JHKHjLKKK' are not correct because we want ONLY 3 occurences of capital letters. This is saying that after the 3 caps ( [AZ]{3} ) any character except those in the range of A to Z are valid.

Last of all there is print "".join(bodyguard)

I did this just for the sake of readability.

The findall function of the re module returns its findings in a list. if we did print bodyguard we would get something like this : [x,y,z,r,q,i] Instead we get 'xyzrqi' because all the elements of the list are joined together in a string by "" which is empty.

Hope I helped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM