Two Plus Two Poker Forums

Two Plus Two Poker Forums (https://forumserver.twoplustwo.com/)
-   Computer and Technical Help (https://forumserver.twoplustwo.com/48/computer-technical-help/)
-   -   ** Python Support Thread ** (https://forumserver.twoplustwo.com/48/computer-technical-help/python-support-thread-1007515/)

Xhad 12-06-2011 02:01 PM

Re: ** Python Support Thread **
 
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'))


e i pi 12-06-2011 10:59 PM

Re: ** Python Support Thread **
 
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

Xhad 12-06-2011 11:21 PM

Re: ** Python Support Thread **
 
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


swisstard 12-07-2011 02:14 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by scrolls (Post 30231737)
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.

daveT 12-07-2011 02:57 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by scrolls (Post 30231737)
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 (Post 30246259)
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.

Xhad 12-07-2011 03:57 AM

Re: ** Python Support Thread **
 
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'

Neko 12-07-2011 11:27 AM

Re: ** Python Support Thread **
 
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


Xhad 12-07-2011 04:49 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by Xhad (Post 30243570)
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])


Neko 12-07-2011 10:49 PM

Re: ** Python Support Thread **
 
yeah, it seems like it should throw an IndexError but it's pretty nice that it doesn't.

daveT 12-08-2011 04:13 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by Xhad (Post 30247188)
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.

RoundTower 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"?

daveT 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.

swisstard 12-09-2011 06:11 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by daveT (Post 30246704)
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.

swisstard 12-09-2011 06:12 PM

Re: ** Python Support Thread **
 
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)


daveT 12-09-2011 09:51 PM

Re: ** Python Support Thread **
 
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.

Xhad 12-09-2011 09:56 PM

Re: ** Python Support Thread **
 
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?

RoundTower 12-09-2011 11:02 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by daveT (Post 30297041)
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().

daveT 12-10-2011 12:07 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by RoundTower (Post 30297983)
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

daveT 12-10-2011 12:07 AM

Re: ** Python Support Thread **
 
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?

stanek 12-11-2011 01:23 AM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by daveT (Post 30298822)
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?

stanek 12-11-2011 03:10 AM

Re: ** Python Support Thread **
 
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)


ChazDazzle 12-15-2011 08:37 PM

Re: ** Python Support Thread **
 
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

Neko 12-15-2011 08:52 PM

Re: ** Python Support Thread **
 
I'm not aware of any other re modules...just to eliminate the obvious solution, presumably you are using re.compile already?

ChazDazzle 12-15-2011 09:17 PM

Re: ** Python Support Thread **
 
Quote:

Originally Posted by Neko (Post 30411577)
I'm not aware of any other re modules...just to eliminate the obvious solution, presumably you are using re.compile already?

yup

Neko 12-15-2011 09:36 PM

Re: ** Python Support Thread **
 
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.


All times are GMT -4. The time now is 06:18 PM.

Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.

Copyright © 2008-2020, Two Plus Two Interactive