#NEWLINE# def fisher_exact_test( a , b , c , d , **kwargs ) : #NEWLINE# #INDENT# " Fast implementation of Fisher's exact test (two-tailed).\n        Returns the significance p for the given 2 x 2 contingency table:\n        p < 0.05: significant\n        p < 0.01: very significant\n        The following test shows a very significant correlation between gender & dieting:\n        -----------------------------\n        |             | men | women |\n        |     dieting |  1  |   9   |\n        | non-dieting | 11  |   3   |\n        -----------------------------\n        fisher_exact_test(a=1, b=9, c=11, d=3) => 0.0028\n    " #NEWLINE# _cache = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# def p( a , b , c , d ) : #NEWLINE# #INDENT# return ( ( C ( ( a + b ) , a ) * C ( ( c + d ) , c ) ) / C ( ( ( ( a + b ) + c ) + d ) , ( a + c ) ) ) #NEWLINE# #UNINDENT# def C( n , k ) : #NEWLINE# #INDENT# if ( len ( _cache ) > 10000 ) : #NEWLINE# #INDENT# _cache . clear ( ) #NEWLINE# #UNINDENT# if ( k > ( n - k ) ) : #NEWLINE# #INDENT# k = ( n - k ) #NEWLINE# #UNINDENT# if ( ( 0 <= k <= n ) and ( ( n , k ) not in _cache ) ) : #NEWLINE# #INDENT# c = 1.0 #NEWLINE# for i in xrange ( 1 , int ( ( k + 1 ) ) ) : #NEWLINE# #INDENT# c *= ( ( n - k ) + i ) #NEWLINE# c /= i #NEWLINE# #UNINDENT# _cache [ ( n , k ) ] = c #NEWLINE# #UNINDENT# return _cache . get ( ( n , k ) , 0.0 ) #NEWLINE# #UNINDENT# cutoff = p ( a , b , c , d ) #NEWLINE# s = ( ( [ cutoff ] + [ p ( ( a + i ) , ( b - i ) , ( c - i ) , ( d + i ) ) for i in xrange ( 1 , ( min ( int ( b ) , int ( c ) ) + 1 ) ) ] ) + [ p ( ( a - i ) , ( b + i ) , ( c + i ) , ( d - i ) ) for i in xrange ( 1 , ( min ( int ( a ) , int ( d ) ) + 1 ) ) ] ) #NEWLINE# return ( sum ( ( v for v in s if ( v <= cutoff ) ) ) or 0.0 )