Open Side Menu Go to the Top

12-06-2011 , 02:01 PM
For future reference, "find" gives you the index of the earliest appearance of an expression (and returns "-1" if there aren't any). For instance, here's a recursive version in python 3:

Code:
def counter(mystring, expression):
    index = mystring.find(expression)
    if index == -1:
        return 0
    else:
        return 1 + counter(mystring[index+1:], expression)

x = 'sss'
print(counter(x, 'ss'))
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **
12-06-2011 , 10:59 PM
I'm sure this is lolcode but it works. What would be a cleaner way of finding a straight?
Code:
def evalmystraight(): #mysevenlist is your 2 cards + community cards
    found = 0
    mystraightcount = []
    for x in range(0,7): #this changes pairs so algo can check for consecutive numbers
        if mysevenlist.count(mysevenlist[x]) != 1:
            mysevenlist[x] = mysevenlist[x] + 30 
    mysevenlist.sort()
    mysevenlist.reverse() #list in order to check for straight
    Ace = 0 #if ace in deck have to add 1 to check for wheel, list count becomes 8
    if 14 in mysevenlist:
        Ace = 1
        mysevenlist.append(1) 
    for z in range(0,3 + Ace): #this code cycles through 7 cards for A=0, 8 for A=1 
        if found == 1:
            break
        for x in range(z,z+4): #only need z+4 because 5th card added with x+1 below
            mystraightcount.append(mysevenlist[x]-mysevenlist[x+1])
            if mystraightcount == [1, 1, 1, 1]: #straight when 5 cards seperated by 1
                mystraightvalue = mysevenlist[x-3] #this is the high card of straight
                print ('straight with high card', mystraightvalue) 
                found = 1
        mystraightcount = []#clears count
If you think this is bad you would lol hard at what I wrote to find pairs, full houses, etc
** Python Support Thread ** Quote
12-06-2011 , 11:21 PM
You can use (x in list) as a boolean

I haven't tried this in the 7-card case (I wrote a video poker sim recently but it was for 5-card draw), but I think you could do something like this:

Code:
#Whatever code makes aces count as both high and low
for card in hand:
     for i in range(4):
          if card+i+1 not in hand:
               break
     else:
          #If the for loop actually completes without breaking you have a straight
** Python Support Thread ** Quote
12-07-2011 , 02:14 AM
Quote:
Originally Posted by scrolls
kind of a noob to python so apologize if this is a dumb question:

>x = 'sss'
>x.count('ss')
1

whats the easiest way for me to count 'ss' in this string and have the result be 2? it seems count only counts the first 'ss' whereas i need it to also count the second 'ss' that overlaps the first 'ss', if that makes sense.
Here is a neat solution:

Code:
def count(x):
    for i in range(len(x)):
        if i >len(x)-2:
            return
        if x[i]==x[i+1]:
            yield 1
        else:
            yield 0

print sum(count('xxxakdd'))
Yield seems like a really neat solution, maybe a bit overkill here But def a solution to keep in mind if x gets really big.
** Python Support Thread ** Quote
12-07-2011 , 02:57 AM
Quote:
Originally Posted by scrolls
kind of a noob to python so apologize if this is a dumb question:

>x = 'sss'
>x.count('ss')
1

whats the easiest way for me to count 'ss' in this string and have the result be 2? it seems count only counts the first 'ss' whereas i need it to also count the second 'ss' that overlaps the first 'ss', if that makes sense.
This is my easiest answer:

Code:
counter = 0
init = 'sss'
check = 'ss'

for i in range(len(init)):
    if check in init:
        init = init[:-1]
        counter += 1

print(counter)
Quote:
Originally Posted by swisstard
Here is a neat solution:

Code:
def count(x):
    for i in range(len(x)):
        if i >len(x)-2:
            return
        if x[i]==x[i+1]:
            yield 1
        else:
            yield 0

print sum(count('xxxakdd'))
Yield seems like a really neat solution, maybe a bit overkill here But def a solution to keep in mind if x gets really big.
Way overkill, IMO. I don't like the idea of naming functions the same as built-ins. I mean, maybe it doesn't matter in this specific case, but later one, you will likely learn how to create your own classes, and .myClass() is how you call them.

Just saying that if you end up with .count() class and .count() built-in, etc, then you run into problems.

Regardless, not even sure if your code is doing at all, tbh, I get that you are trying to return a 'count' of something, but I get the answer: 3, which I'm pretty sure isn't the intended output, but I could be wrong here. I'm also using Python 3 so I had to add the requisite parens to this which may have blown my output, but please explain what this is doing and why it works for the question.
** Python Support Thread ** Quote
12-07-2011 , 03:57 AM
swiss's algorithm just counts every instance of two neigboring letters that match each other. It doesn't allow for arbitrary substrings or even searching for 'ss' while excluding 'xx'. It does return the right answer for scrolls's problem if you change 'xxxakdd' to 'sss'

EDIT: dave, yours doesn't actually work. Try init = 'sss000'

Last edited by Xhad; 12-07-2011 at 04:04 AM.
** Python Support Thread ** Quote
12-07-2011 , 11:27 AM
Here's my quick one liner implementation.
Didn't put much thought into it so I Haven't thought of all the corner cases but it seems to work ok.
Code:
def count_substr(needle,haystack):
    return len([1 for i in range(len(haystack)) if haystack[i:i+len(needle)] ==needle])

to_test = (
    (2,'ss','sss'),
    (0,'ss','sxs'),
    (1,'ss','ssoooo'),
    (2,'ss','sssooo'),
    (1,'ss','ooooss'),
    (2,'ss','ssoooss'),
    (6,'ss','ssssossss'),
    (4,'sss','ssssossss'),
)
    

for expected,needle,haystack in to_test:
    print needle,haystack,expected,expected==find_substr(needle,haystack)
results in:

Code:
ss sss 2 True
ss sxs 0 True
ss ssoooo 1 True
ss sssooo 2 True
ss ooooss 1 True
ss ssoooss 2 True
ss ssssossss 6 True
sss ssssossss 4 True
** Python Support Thread ** Quote
12-07-2011 , 04:49 PM
Quote:
Originally Posted by Xhad
You can use (x in list) as a boolean

I haven't tried this in the 7-card case (I wrote a video poker sim recently but it was for 5-card draw), but I think you could do something like this:

Code:
#Whatever code makes aces count as both high and low
for card in hand:
     for i in range(4):
          if card+i+1 not in hand:
               break
     else:
          #If the for loop actually completes without breaking you have a straight
So I just realized that this doesn't completely work unless the cards are sorted in descending order (in ascending order, it incorrectly reads 56789TJ as a nine-high straight).

Neko: Thanks to you I just learned something I didn't know about slicing.

Code:
a = [1, 2, 3]
#I could have sworn this would give an index error but it doesn't
print(a[1:5])
** Python Support Thread ** Quote
12-07-2011 , 10:49 PM
yeah, it seems like it should throw an IndexError but it's pretty nice that it doesn't.
** Python Support Thread ** Quote
12-08-2011 , 04:13 AM
Quote:
Originally Posted by Xhad
swiss's algorithm just counts every instance of two neigboring letters that match each other. It doesn't allow for arbitrary substrings or even searching for 'ss' while excluding 'xx'. It does return the right answer for scrolls's problem if you change 'xxxakdd' to 'sss'

EDIT: dave, yours doesn't actually work. Try init = 'sss000'
It appears I misunderstood the question. I thought it was:

"How can I count how many time the string 'ss' appears in 'sss'?"

Not:

"How many time does 'ss' appear in an arbitrary string?"

or:

"How many times does 's' appear next to each other in an arbitrary string?"

I could answer version two adding a few letters into the code, thus it is well-formed IMO since it is easily extensible to even "How many times does an arbitrary string appear in an arbitrary string?"

My code, as it stands, will work with: "how many times does 's' x 500 appear in string 's' x 100**100."

I took his question too literally, obv.
** Python Support Thread ** Quote
12-08-2011 , 05:37 AM
If you really thought he was asking only about the specific question posted then why did you go for the massive overkill solution instead of "return 2"?
** Python Support Thread ** Quote
12-08-2011 , 10:46 PM
Originaly, I was going to tell him to type 2 in the command line and press enter, but clearly, clicking a mouse over the Python icon would have been overkill in that case.
** Python Support Thread ** Quote
12-09-2011 , 06:11 PM
Quote:
Originally Posted by daveT
Way overkill, IMO. I don't like the idea of naming functions the same as built-ins. I mean, maybe it doesn't matter in this specific case, but later one, you will likely learn how to create your own classes, and .myClass() is how you call them.

Just saying that if you end up with .count() class and .count() built-in, etc, then you run into problems.

Regardless, not even sure if your code is doing at all, tbh, I get that you are trying to return a 'count' of something, but I get the answer: 3, which I'm pretty sure isn't the intended output, but I could be wrong here. I'm also using Python 3 so I had to add the requisite parens to this which may have blown my output, but please explain what this is doing and why it works for the question.
There shouldnt be any problem with my naming convention of count. There is no built in function named count. There is however a built in method named count of class string. Those two should not interfere with each other.
Yield is used to make generators. Check out (link) for more info. I suggested it, because this option is often forgotten and is really useful if you can start processing partial results.
My code should work in python 3.0. The only thing I can think of that doesnt work is print. In python 3.0 you cant use
Code:
print object
you have to use from python 3.0
Code:
print(object)
see link for other things that changed.
** Python Support Thread ** Quote
12-09-2011 , 06:12 PM
I thought goal was to just count neighboring letters. My bad.

If you just want to count number of substrings in a string, here is a neat solution using recursion:

Code:
myhay = 'sssxxss'
myneedle = 'ss'

def counter(hay,needle):
    lowerInd = hay.find(needle)

    if lowerInd == -1:
        return 0
    else:
        return counter(hay[(lowerInd+1):],needle) + 1

print counter(myhay,myneedle)
** Python Support Thread ** Quote
12-09-2011 , 09:51 PM
One thing that sucks about Python is that it has maximum recusion depths. Not sure if this is included in all programs, but I threw that error a few times doing Project Eulers, which makes me pretty ashamed to admit. I def agree that Yield is a good addition though an option I don't use enough.
** Python Support Thread ** Quote
12-09-2011 , 09:56 PM
Yeah, I was going for easy but I realize the recursive version could have issues for large strings. I don't really see the utility of yield in this problem because intermediate results are useless. Is there a reason to prefer a generator over a loop or a comprehension like Neko's?
** Python Support Thread ** Quote
12-09-2011 , 11:02 PM
Quote:
Originally Posted by daveT
One thing that sucks about Python is that it has maximum recusion depths. Not sure if this is included in all programs, but I threw that error a few times doing Project Eulers, which makes me pretty ashamed to admit. I def agree that Yield is a good addition though an option I don't use enough.
I think what you mean is that the default recursion limit is set too low (which it definitely is for some nice solutions to Project Euler problems). Try sys.setrecursionlimit().
** Python Support Thread ** Quote
12-10-2011 , 12:07 AM
Quote:
Originally Posted by RoundTower
I think what you mean is that the default recursion limit is set too low (which it definitely is for some nice solutions to Project Euler problems). Try sys.setrecursionlimit().
That's awesome. You must read a page of the docs everyday. :0

Last edited by daveT; 12-10-2011 at 12:19 AM. Reason: Oh, now I don't feel as stupid for throwing the error. Trust your idea of 'nice solution.'
** Python Support Thread ** Quote
12-10-2011 , 12:07 AM
Here's my shortest solution to the question at hand:

Code:
myString = 'ss'
theirString = 'sss000'

counter = 0

while len(myString) <= len(theirString):
    if myString == theirString[-len(myString):]:
        counter += 1
    theirString = theirString[:-1]

print(counter)
Not sure how I feel about the above code. It seems like len(myString) should just be a flat variable. Is it getting called over and over again without the answer being bound?
** Python Support Thread ** Quote
12-11-2011 , 01:23 AM
Quote:
Originally Posted by daveT
Here's my shortest solution to the question at hand:

Code:
myString = 'ss'
theirString = 'sss000'

counter = 0

while len(myString) <= len(theirString):
    if myString == theirString[-len(myString):]:
        counter += 1
    theirString = theirString[:-1]

print(counter)
Not sure how I feel about the above code. It seems like len(myString) should just be a flat variable. Is it getting called over and over again without the answer being bound?

in your above example what should counter be? 2?
** Python Support Thread ** Quote
12-11-2011 , 03:10 AM
Code:
myString = 'ss'
theirString = 'sss000'

counter = 0

for b in xrange( len(theirString) - len(myString) + 1 ):
    if myString == theirString[ b : b + len(myString) ]:
        counter += 1

print(counter)
I don't know if this code is faster than yours, but it eliminates the step of popping off the first letter in the string.

len(myString) is the same value every time it is called so I would imagine that setting it before hand might save a few cpu cycles.

Below is code that I wrote to figure out if you could save the extra variable.

I am pretty sure that I created Arrays instead of Tuples but I will leave my code as is, because it was a learning experience

Code:
x = "ss"
y = "sss000"
myTuple = (x,len(x))
theirTuple = (y, len(y))

count = 0

for b in xrange( theirTuple[1] - myTuple[1] + 1 ):
	if myTuple[0] == theirTuple[0][ b : b + myTuple[1] ]:
		count += 1
print (count)
** Python Support Thread ** Quote
12-15-2011 , 08:37 PM
Anyone here know of any good replacements for python's re module? Attempting to upgrade in increase speed. Tried out pyre2 which is based on google's RE2, but it turned out to be half-complete in it's mapping to the way python handles regex. Look aheads are not supported, and i got several UTF-8 encoding errors whereas the standard re produced none. Thanks
** Python Support Thread ** Quote
12-15-2011 , 08:52 PM
I'm not aware of any other re modules...just to eliminate the obvious solution, presumably you are using re.compile already?
** Python Support Thread ** Quote
12-15-2011 , 09:17 PM
Quote:
Originally Posted by Neko
I'm not aware of any other re modules...just to eliminate the obvious solution, presumably you are using re.compile already?
yup
** Python Support Thread ** Quote
12-15-2011 , 09:36 PM
Have you seen this module http://code.google.com/p/mrab-regex-hg/? I've never used it and have no idea how good or fast it is, but probably worth a look.
** Python Support Thread ** Quote
** Python Support Thread **
150% up to $2,000 Welcome Bonus on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** Python Support Thread **

      
m