I'm simply trying to modify a string and return the modified string, however, I'm getting "None" returned when print the variable.
def AddToListTwo(self,IndexPosition):
filename = RemoveLeadingNums(self, str(self.listbox1.get(IndexPosition))) #get the filename, remove the leading numbers if there are any
print filename #this prints None
List2Contents = self.listbox2.get(0, END)
if(filename not in List2Contents): #make sure the file isn't already in list 2
self.listbox2.insert(0, filename)
def RemoveLeadingNums(self, words):
if(isinstance(words,str)):
match = re.search(r'^[0-9]*[.]',words)
if match: #if there is a match, remove it, send it through to make sure there aren't repeating numbers
RemoveLeadingNums(self, re.sub(r'^[0-9]*[.]',"",str(words)).lstrip())
else:
print words #this prints the value correctly
return words
if(isinstance(words,list)):
print "list"
edit - multiple people have commented saying I'm not returning the value if there is match. I don't want to return it if there is. It could be repeating (ex: 1.2. itema). So, I wanted to essentially use recursion to remove it, and THEN return the value
There are multiple conditions where RemoveLeadingNums returns None. e.g. if the if match: branch is taken. Perhaps that should be:
if match:
return RemoveLeadingNums(...
You also return None if you have any datatype that isn't a string passed in.
You're not returning anything in the case of a match. It should be:
return RemoveLeadingNums( ... )
Related
I am trying to figure out the following function situation from my python class. I've gotten the code to remove the three letters but from exactly where they don't want me to. IE removing WGU from the first line where it's supposed to stay but not from WGUJohn.
# Complete the function to remove the word WGU from the given string
# ONLY if it's not the first word and return the new string
def removeWGU(mystring):
#if mystring[0]!= ('WGU'):
#return mystring.strip('WGU')
#if mystring([0]!= 'WGU')
#return mystring.split('WGU')
# Student code goes here
# expected output: WGU Rocks
print(removeWGU('WGU Rocks'))
# expected output: Hello, John
print(removeWGU('Hello, WGUJohn'))
Check this one:
def removeWGU(mystring):
s = mystring.split()
if s[0] == "WGU":
return mystring
else:
return mystring.replace("WGU","")
print(removeWGU('WGU Rocks'))
print(removeWGU('Hello, WGUJohn'))
def removeWGU(mystring):
return mystring[0] + mystring[1:].replace("WGU","")
Other responses I seen wouldn't work on a edgy case where there is multiple "WGU" in the text and one at the beginning, such as
print(removeWGU("WGU, something else, another WGU..."))
class Cleaner:
def __init__(self, forbidden_word = "frack"):
""" Set the forbidden word """
self.word = forbidden_word
def clean_line(self, line):
"""Clean up a single string, replacing the forbidden word by *beep!*"""
found = line.find(self.word)
if found != -1 :
return line[:found] + "*beep!*" + line[found+len(self.word):]
return line
def clean(self, text):
for i in range(len(text)):
text[i] = self.clean_line(text[i])
example_text = [
"What the frack! I am not going",
"to honour that question with a response.",
"In fact, I think you should",
"get the fracking frack out of here!",
"Frack you!"
]
Hi everyone, the issue with the following code, is the fact that when i run it, i get the following result:
What the *beep!*! I am not going
to honour that question with a response.
In fact, I think you should
get the *beep!*ing frack out of here!
Frack you!
On the second last line, one of the "frack" are not being changed.
I have tried using the if In line method but this doesn't work with variables. So how do i use an if statement that tracks a variable instead of a string? but also changes every word that needs changed?
PS. its exam practice i didn't make the code myself.
The expected outcome should be:
What the *beep!*! I am not going
to honour that question with a response.
In fact, I think you should
get the *beep!*ing *beep!* out of here!
Frack you!
That's because line.find(...) will only return the first result, which you then replace with "*beep!*" and then return, thus missing other matches.
Either use find iteratively, passing in the appropriate start index each time until the start index exceeds the length of the line, or use Python's replace method to do all of that for you.
I'd recommend replacing:
found = line.find(self.word)
if found != -1 :
return line[:found] + "*beep!*" + line[found+len(self.word):]
return line
with
return line.replace(self.word, "*beep!*")
Which will automatically find all matches and do the replacement.
I'm using Python to match against a list (array), but I'm sure the problem lies on the regex itself.
Assuming I have the following:
foo.html
bar.html
teep.html
And I use the following regex: .*(?=.html)
where .* will match anything and (?=.html) requires the string be present, but does not include it in the results
Thus, I should just be left with what's before .html
When I check, it only matches the first item in the array (in this case foo), but why not the others
my_regex = re.compile('.html$')
r2 = re.compile('.*(?=.html)')
start = '/path/to/folder'
os.chdir(start)
a = os.listdir(start)
for item in a:
if my_regex.search(item) != None and os.path.isdir(item):
print 'FOLDER MATCH: '+ item # this is a folder and not a file
starterPath = os.path.abspath(item)
outer_file = starterPath + '/index.html'
outer_js = starterPath + '/outliner.js'
if r2.match(item) != None:
filename = r2.match(item).group() # should give me evertying before .html
makePage(outer_file, outer_js, filename) # self defined function
else:
print item + ': no'
filename = r2.match(item).group()
should be
filename = r2.match(item).groups() # plural !
According to the documentation, group will return one or more subgroups, whereas groups will return them all.
Figured out the problem. In my function, I changed directories, but never changed back. So when function ended and went back to for loop, it was now looking for the folder name in the wrong location. It's as simple as
def makePage(arg1, arg2, arg3):
os.chdir('path/to/desktop')
# write file to new location
os.chdir(start) # go back to start and continue original search
return
Also .group() worked for me and returned everything in the folder name before the string .html whereas .groups() just returned ()
The code in original post stayed the same. Something so simple, causing all this headache..
I am having issues passing a string variable into a search function.
Here is what I'm trying to accomplish:
I have a file full of values and I want to check the file to make sure a specific matching line exists before I proceed. I want to ensure that the line <endSW=UNIQUE-DNS-NAME-HERE<> exists if a valid <begSW=UNIQUE-DNS-NAME-HERE<> exists and is reachable.
Everything works fine until I call if searchForString(searchString,fileLoc): which always returns false. If I assign the variable 'searchString' a direct value and pass it it works, so I know it must be something with the way I'm combining the strings, but I can't seem to figure out what I'm doing wrong.
If I examine the data that 'searchForString' is using I see what seems to be valid values:
values in fileLines list:
['<begSW=UNIQUE-DNS-NAME-HERE<>', ' <begPortType=UNIQUE-PORT-HERE<>', ' <portNumbers=80,443,22<>', ' <endPortType=UNIQUE-PORT-HERE<>', '<endSW=UNIQUE-DNS-NAME-HERE<>']
value of searchVar:
<endSW=UNIQUE-DNS-NAME-HERE<>
An example of the entry in the file is:
<begSW=UNIQUE-DNS-NAME-HERE<>
<begPortType=UNIQUE-PORT-HERE<>
<portNumbers=80,443,22<>
<endPortType=UNIQUE-PORT-HERE<>
<endSW=UNIQUE-DNS-NAME-HERE<>
Here is the code in question:
def searchForString(searchVar,readFile):
with open(readFile) as findMe:
fileLines = findMe.read().splitlines()
print fileLines
print searchVar
if searchVar in fileLines:
return True
return False
findMe.close()
fileLoc = '/dir/folder/file'
fileLoc.lstrip()
fileLoc.rstrip()
with open(fileLoc,'r') as switchFile:
for line in switchFile:
#declare all the vars we need
lineDelimiter = '#'
endLine = '<>\n'
begSWLine= '<begSW='
endSWLine = '<endSW='
begPortType = '<begPortType='
endPortType = '<endPortType='
portNumList = '<portNumbers='
#skip over commented lines -(REMOVE THIS)
if line.startswith(lineDelimiter):
pass
#checks the file for a valid switch name
#checks to see if the host is up and reachable
#checks to see if there is a file input is valid
if line.startswith(begSWLine):
#extract switch name from file
switchName = line[7:-3]
#check to make sure switch is up
if pingCheck(switchName):
print 'Ping success. Host is reachable.'
searchString = endSWLine+switchName+'<>'
**#THIS PART IS SUCKING, WORKS WITH DIRECT STRING PASS
#WONT WORK WITH A VARIABLE**
if searchForString(searchString,fileLoc):
print 'found!'
else:
print 'not found'
Any advice or guidance would be extremely helpful.
Hard to tell without the file's contents, but I would try
switchName = line[7:-2]
So that would look like
>>> '<begSW=UNIQUE-DNS-NAME-HERE<>'[7:-2]
'UNIQUE-DNS-NAME-HERE'
Additionally, you could look into regex searches to make your cleanup more versatile.
import re
# re.findall(search_expression, string_to_search)
>>> re.findall('\=(.+)(?:\<)', '<begSW=UNIQUE-DNS-NAME-HERE<>')[0]
'UNIQUE-DNS-NAME-HERE'
>>> e.findall('\=(.+)(?:\<)', ' <portNumbers=80,443,22<>')[0]
'80,443,22'
I found how to recursively iterate over XML tags in Python using ElementTree? and used the methods detailed to parse an XML file instead of using a TXT file.
In order to see if a filename is correctly named (using re) I use the following regular expression pattern :
*^S_hc_[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}_[0-9]{4,4}-[0-9]{1,3}T[0-9]{6,6}\.xml$"*
Here is a correct file name : *S_hc_1.2.3_2014-213T123121.xml*
Here is an incorrect file name : *S_hc_1.2.IncorrectName_2014-213T123121.xml*
I would like to know if a simple way to retrieve the part of the file which to do not match exits.
In the end, an error message would display :
Error, incorrect file name, the part 'IncorrectName' does not match with expected name.
You can use re.split and a generator expression within next but you also need to check the structure of your string that match waht you want, you can do it with following re.match :
re.match(r"^S_hc_(.*)\.(.*)\.(.*)_(.*)-(.*)\.xml$",s2)
And in code:
>>> import re
>>> s2 ='S_hc_1.2.IncorrectName_2014-213T123121.xml'
>>> s1
'S_hc_1.2.3_2014-213T123121.xml'
#with s1
>>> next((i for i in re.split(r'^S_hc_|[0-9]{1,2}\.|[0-9]{1,2}_|_|[0-9]{4,4}|-|[0-9]{1,3}T[0-9]{6}|\.|xml$',s1) if i and re.match(r"^S_hc_(.*)\.(.*)\.(.*)_(.*)-(.*)\.xml$",s2)),None)
#with s2
>>> next((i for i in re.split(r'^S_hc_|[0-9]{1,2}\.|[0-9]{1,2}_|_|[0-9]{4,4}|-|[0-9]{1,3}T[0-9]{6}|\.|xml$',s2) if i and re.match(r"^S_hc_(.*)\.(.*)\.(.*)_(.*)-(.*)\.xml$",s2)),None)
'IncorrectName'
All you need is to use pip (|) between unique part of your regex patterns,then the split function will split your string based on one of that patterns.
And the part that doesn't match with one of your pattern will not be split and you can find it with looping over your split text!
next(iterator[, default])
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised.
If you want in several line :
>>> for i in re.split(r'^S_hc_|[0-9]{1,2}\.|[0-9]{1,2}_|_|[0-9]{4,4}|-|[0-9]{1,3}T[0-9]{6}|\.|xml$',s2):
... if i and re.match(r"^S_hc_(.*)\.(.*)\.(.*)_(.*)-(.*)\.xml$",s2):
... print i
...
IncorrectName
Maybe this is a longer solution but it will tell you what failed and what it expected. It is similar to Kasra's solution - breaking up the file name into individual bits and matching them in turn. This allows you to find out where the matching breaks:
import re
# break up the big file name pattern into individual bits that we can match
RX = re.compile
pattern = [
RX(r"\*"),
RX(r"S_hc_"),
RX(r"[0-9]{1,2}"),
RX(r"\."),
RX(r"[0-9]{1,2}"),
RX(r"\."),
RX(r"[0-9]{1,2}"),
RX(r"_"),
RX(r"[0-9]{4}"),
RX(r"-"),
RX(r"[0-9]{1,3}"),
RX(r"T"),
RX(r"[0-9]{6}"),
RX(r"\.xml"),
RX(r"\*")
]
# 'fn' is the file name matched so far
def reductor(fn, rx):
if fn is None:
return None
mo = rx.match(fn)
if mo is None:
print "File name mismatch: got {}, expected {}".format(fn, rx.pattern)
return None
# proceed with the remainder of the string
return fn[mo.end():]
validFile = lambda fn: reduce(reductor, pattern, fn) is not None
Let's test it:
print validFile("*S_hc_1.2.3_2014-213T123121.xml*")
print validFile("*S_hc_1.2.IncorrectName_2014-213T123121.xml*")
Outputs:
True
File name mismatch: got IncorrectName_2014-213T123121.xml*, expected [0-9]{1,2}
False
Here is the method I am going to use, please let me know if cases mismatch:
def verifyFileName(self, filename__, pattern__):
'''
Verifies if a file name is correct
:param filename__: file name
:param pattern__: pattern
:return: empty string if file name is correct, otherwise the incorrect part of file
'''
incorrectPart =""
pattern = pattern__.replace('\.','|\.|').replace('_','|_|')
for i in re.split(pattern, filename__):
if len(i)>1:
incorrectPart = i
return incorrectPart
Here's the counterexample. I've taken your method and defined three test cases - file names plus expected output.
Here's the output, the code follows below:
$> python m.py
S_hc_1.2.3_2014-213T123121.xml: PASS [expect None got None]
S_hc_1.2.3_Incorrect-213T123121.xml: PASS [expect Incorrect- got Incorrect-]
X_hc_1.2.3_2014-213T123121.xml: FAIL [expect X got None]
This is the code - cut & paste & run it.
def verifyFileName(filename__, pattern__):
'''
Verifies if a file name is correct
:param filename__: file name
:param pattern__: pattern
:return: empty string if file name is correct, otherwise the incorrect part of file
'''
incorrectPart = None
pattern = pattern__.replace('\.','|\.|').replace('_','|_|')
for i in re.split(pattern, filename__):
if len(i)>1:
incorrectPart = i
return incorrectPart
pattern = "^S_hc_[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}_[0-9]{4,4}-[0-9]{1,3}T[0-9]{6,6}\.xml$"
# list of test cases: filenames + expected return from verifyFileName:
testcases = [
# correct file name
("S_hc_1.2.3_2014-213T123121.xml", None),
# obviously incorrect
("S_hc_1.2.3_Incorrect-213T123121.xml", "Incorrect-"),
# subtly incorrect but still incorrect
("X_hc_1.2.3_2014-213T123121.xml", "X")
]
for (fn, expect) in testcases:
res = verifyFileName(fn, pat)
print "{}: {} [expect {} got {}]".format(fn, "PASS" if res==expect else "FAIL", expect, str(res))