-1

apologies to posting the question, as has been answered in other questions as well. However, couldn't figure out what's wrong with this solution. The question requires to find the lower-cased characters bordered by 3 upper-cased characters on each side. The code i've writting:

q = ''
for i in range(4,len(x)-4):
    if x[i].islower() and x[i-4].islower() and x[i+4].islower() and x[i-3:i].isupper() and x[i+1:i+4].isupper()  :
        q+=x[i]


print(q)

The string i'm getting is

'lgvcaaginbkvsoezhtlnldslyitlooqfgiksudtm' vs 'linkedlist'

Thanks for the help.

Edit: for some reason the following code seems to work:

q = ''
for i in range(4,len(x)-4):
    if x[i].islower() and x[i-4].islower() and  x[i-3:i].isupper() and x[i+1:i+4].isupper() and x[i+4].islower():
        q+=x[i]

print(q)
novice2020
  • 115
  • 1
  • 2
  • 7
  • your test string has no uppers in it ... kindof a bad test case - isn't it? – Patrick Artner Jan 26 '19 at 10:59
  • have the upper cases in the end, that what you meant? Also removed the 'True' – novice2020 Jan 26 '19 at 11:00
  • you only have lower case characters: `'lgvcaaginbkvsoezhtlnldslyitlooqfgiksudtm' vs 'linkedlist'` - not a single `'UPPER CASE CHARACTER'` in it ... – Patrick Artner Jan 26 '19 at 11:01
  • Regex solution could be more appropriate? – chamoda Jan 26 '19 at 11:01
  • @Austin : `'THISwOULD qualify'` - although it is not correct spelled – Patrick Artner Jan 26 '19 at 11:01
  • not sure about the etiquettes here, but if you check the source code for http://www.pythonchallenge.com/pc/def/equality.html, it has a massive string at the end from which this has to be dug up. – novice2020 Jan 26 '19 at 11:02
  • @chamoda am trying to get it working without re. – novice2020 Jan 26 '19 at 11:03
  • One caveat here is `.isupper()` can return `True` for just spaces too. – Austin Jan 26 '19 at 11:13
  • the given string doesn't have space, only chars in lower and upper – novice2020 Jan 26 '19 at 11:15
  • @pythonnewbie so input `'THISwOULD qualify'` should give output `w`. and what about `'THIswouldaLSO qualify'` and `'THIswOULdaLSO qualify'` ? – Partho63 Jan 26 '19 at 11:43
  • @Partho63 none of these would qualify, apologies if the question wasn't clear. 'THIsWOU' would return 's' and 'ABCDeFGH' would not return anything – novice2020 Jan 26 '19 at 11:53
  • @pythonnewbie so only one lower_case character surrounded by same numbered upper_case characters in both side would be the output. and what about multiple occurrence `THISwOULDqUALIfy`. sorry for asking so many questions. – Partho63 Jan 26 '19 at 11:58
  • @Partho63 one lower case surrounded by exactly 3 uppercase chars on both the side, if its 4 upper case it should not consider that particular char – novice2020 Jan 26 '19 at 12:07

3 Answers3

1

This would be a slicing solution:

t = "This is some TEXtTHAt will result in one true result"

def notupper(x): 
    return not x.isupper()

yep = []
# lookup function to execute inside all()
terms = {0:notupper, 8:notupper, 4:notupper}

for part in (t[i:i+9] for i in range(len(t)-7)):
    if len(part)<9:  # fix for XXXxXXX at end of string
      part = (part+"  ")[:9]
    if all(terms.get(index,str.isupper)(ch) for index,ch in enumerate(part)):
        print("Statisfies all terms: ", part)

It slices the text into parts of 9 characters (you need 9 to assure not to have XXXXyXXXX - you need exactly three uppers around your lowers.

It checks the sliced text for notupper on positions 0,8 and 4:

XXXXxXXXX
012345678
lUUUlUUUl   # must statisfy: l=notupper and U=isupper

by pulling this function from the terms-dictionary. All indexes of part that have no matching key in terms are tested with str.isupper using the default param of terms.get(index,str.isupper)

all() makes sure all tests need to evaluate to true to enter the if-condition.

Spaces evaluate to False for isupper and islower().

Readup:


You can replace the dict/all part by:

# the ( .. ) are needed to enable line breaking - you could use \ as well
if notupper(part[0]) and notupper(part[8]) and notupper(part[4]) and (
    part[1].isupper() and part[2].isupper() and part[3].isupper() and
    part[5].isupper() and part[6].isupper() and part[7].isupper()):
    print("Statisfies all terms: ", part)

if that is too complicated for your current level of python.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
1

What you are trying to do is match a pattern : Not Upper, Upper, Upper, Upper, Not Upper, Upper, Upper, Upper, Not Upper. This is easier to catch if you use a signature for your string:

>>> t = "This is some TEXtTHAt will result in one true result"
>>> sig = "".join("U" if c.isupper() else "l" for c in t)
>>> sig
'UllllllllllllUUUlUUUllllllllllllllllllllllllllllllll'

You are looking for the lUUUlUUUl substrings in the sig string. Python has no builtin for findall, but you can to iterate over the results of find:

>>> result = ""
>>> i = sig.find("lUUUlUUUl")
>>> while i != -1: # find != -1 means that the substring wasn't found
...     result += t[i+4] # the center `l` 
...     i = sig.find("lUUUlUUUl", i+4) # we can start the next search at the center `l`
... 
>>> print( result )
t

You may also use re.finditer with a regex pattern, but is more complicated.

jferard
  • 7,835
  • 2
  • 22
  • 35
-1

The text has the new line character "\n" at the end of each line. You need to replace all the "\n" characters with an empty string. This can be done using the RegEx (Regular Expression) module. Add these lines of code and it will work:

import re

x = re.sub(r"\n","", x)
Frank
  • 1,151
  • 10
  • 22