-->

Friday 12 December 2014

Finding Discounts on Amazon

The following bookmarklets are for finding discounts on Amazon. To use them drag them to your bookmarks bar (they cannot be added like normal links). Go to Amazon and do a search. Any page that has search results (showing products and their prices) and click the link.

Amazon: The Amazon link asks you for one number.


I put in 70 (no percent sign) and press OK. Here are the results:


Amazon2:
I realised this may be too many results so I created the second link that enables you to choose an upper-bound as well. So here are high heels with 55-56% off. Much more manageable.


Friday 25 October 2013

Ipython Notebook Playing with Probability

In [2]:
%pylab inline
%autocall
from matplotlib import mpl,pyplot,colors
import numpy as np
import itertools
Populating the interactive namespace from numpy and matplotlib
Automatic calling is: Smart

The next cell imports the or and and operators. We then give these more convenient names for when we call them in the future.
In [3]:
import operator

OR = operator.__or__
AND =operator.__and__
In [4]:
# list
class Prob(object):
    def __init__(self, vals):
        self.vals = vals
        
    def values(self):
        return self.vals
    
    def size(self):
        return len(self.vals)
    
    @staticmethod
    def function(string):
        def f(x):
            return eval (string)
        return f
    
    

def combs(a,b):
    """returns all combinations of two probability objects"""
    return list(itertools.product(*[a.values(),b.values()]))   
        
    
class Dice(Prob):
    def __init__(self, sides = 6):
        Prob.__init__(self, arange(1,sides+1))
    
    # check if a value is odd
    @staticmethod
    def odd():
        def isOdd(n):
            return n % 2 == 1
        return isOdd
    
    # check if a value is even
    @staticmethod
    def even():
        def isEven(n):
            return n % 2 == 0
        return isEven
    
    
        
        
class Coin(Prob):
    vals = ['Heads', 'Tails']
    def __init__(self):
        Prob.__init__(self,Coin.vals)
    
    # check if a coin came up 'Heads'
    @staticmethod
    def heads():
        def isHead(side):
            return side == 'Heads'
        return isHead
    
    # check if a coin came up 'Tails'
    @staticmethod   
    def tails():
        def isTail(side):
            return side == 'Tails'
        return isTail
            

def evaluate(t1,t2, op):
    # get all combinations of the probability objects
    each = combs(t1[0], t2[0])
    
    # turns true or false into +/-5 for Colour Map
    def g(x):
        if x:
            return 5 
        else:
            return -5
    
    # run the rules on the elements of each and use op to combine them
    bools = [op(t1[1](element[0]) , t2[1](element[1])) for element in each]
    
    # use g to convert to number
    # convert list to numpy array so it can be reshaped
    zvals = np.array([g(boolean) for boolean in bools])
    
    return zvals.reshape(t1[0].size(), t2[0].size())
In [5]:
def show(a,b,op):
    zvals = evaluate(a,b,op)
    plot(a[0],b[0], zvals)
    
def compare(d1, d2, rule):
        c = combs(d1, d2) 
        print [(x,y, eval(rule)) for x,y in c]
        
        
        def g(x):
            if x:
                return 5 
            else:
                return -5
            
        zvals = np.array([g(eval(rule)) for x,y in c]).reshape(d1.size(), d2.size())
        
        plot(d1,d2, zvals)
    


def plot(p2,p1,zvals):
    fig, ax = pyplot.subplots()
    
    # make a color map of fixed colors
    cmap = mpl.colors.ListedColormap(['blue','red'])
    bounds=[2,6,2,6]
    norm = mpl.colors.BoundaryNorm(bounds, cmap.N)


    # tell imshow about color map so that only set colors are used
    img = pyplot.pcolormesh(zvals, cmap = cmap,norm=norm)

    #pyplot.grid(b=True, which='major', color='black', linestyle='-')
    
    m = max(p1.size(), p2.size())

    pyplot.axis([0,m,0,m])
    
    
    ax.tick_params(axis='x',which='minor',bottom='off') 
    ax.tick_params(axis='y',which='minor',bottom='off')  
   
    
    px = p1.size()
    xlocations = np.array(range(px))
    xminorlocations = np.array(range(px))+0.5
    
    py = p2.size()
    ylocations = np.array(range(py))
    yminorlocations = np.array(range(py))+0.5
    
    pyplot.xticks(xminorlocations, p1.values(), rotation=0, size=15)
    ax.set_xticks(xlocations, minor=True)
    
    pyplot.yticks(yminorlocations, p2.values(), rotation=0, size=15)
    ax.set_yticks(ylocations, minor=True)
    grid(True, which='minor', linestyle='-')

    pyplot.show()
    
    
    

Creating Our Probability Objects

A coin or dice can be created by calling Coin() or Dice() respectively. A different-sided dice can be created by pass ing a number to Dice(). Here we will create a 12-sided dice.
In [6]:
d = Dice()
d12 = Dice(12)
c = Coin()

Creating (Probability Object, Rule) 2-Tuples


IPython Notebook Playing With Functions

In [149]:
%pylab inline
from matplotlib import mpl,pyplot,colors
import numpy as np
from sympy import *
from sympy.interactive import printing
import functools
Populating the interactive namespace from numpy and matplotlib

WARNING: pylab import has clobbered these variables: ['prod', 'plotting', 'cosh', 'Circle', 'power', 'diag', 'sinh', 'trunc', 'binomial', 'plot', 'eye', 'det', 'tan', 'product', 'gamma', 'roots', 'vectorize', 'zeros', 'interactive', 'conjugate', 'take', 'solve', 'trace', 'beta', 'colors', 'ones', 'multinomial', 'transpose', 'cos', 'diff', 'invert', 'pi', 'tanh', 'Polygon', 'reshape', 'sqrt', 'source', 'add', 'test', 'poly', 'mod', 'sign', 'log', 'var', 'seterr', 'flatten', 'floor', 'nan', 'exp', 'sin']
`%pylab --no-import-all` prevents importing * from pylab and numpy

In [150]:
x = Symbol('x')

class Function(object):
    def __init__(self, coeff, start=-5, end = 5, points = 20):
        # more points = more accurate but take more time
        self.points =(end-start)* points
        
        # tuples in the form (coefficient, power of x)
        l = len(coeff)
        self.coeff = [(value, l - 1 - index) for index, value in enumerate(coeff)]
        
        
        self.X = np.linspace(start, end, self.points)
        
        
        # coefficients for the first and second derivatives
        self.D1 = [(a*b, b-1) for a,b in self.coeff[:-1]]
        self.D2 = [(a*b, b-1) for a,b in self.D1[:-1]]
        
        # set the Y values
        self.Y = np.zeros(self.points)
        for a,b in self.coeff:            
            self.Y = self.Y +a*(self.X**b) 
            
            
       
    def y(self,coeff, change = None):
        y = np.zeros(self.points)
        
        for a,b in coeff:
            if b == change:
                print "changing",change
                y = y -a*(self.X**b)
            else:
                
                y = y +a*(self.X**b)
            
        return y
        
        
    def values(self):
        pass
    
    def d1(self):
        return self.D1
    
    def d2(self):
        return self.D2
    
    
    # plot the function and its first derivative
    def plotD1(self):
        pyplot.plot(self.X,self.Y)
        pyplot.plot(self.X,self.y(self.D1))
    
    # plot the function and its first AND second derivatives
    def plotD1D2(self):
        pyplot.plot(self.X,self.Y)
        pyplot.plot(self.X,self.y(self.D1))
        pyplot.plot(self.X,self.y(self.D2))
        grid(True)
    
    def plot(self, coeff = None):
        pyplot.plot(self.X,self.Y)
        pyplot.grid()
            
        pyplot.show()
        
    def change(self,co):
        pyplot.plot(self.X,self.Y)
        #pyplot.plot(self.X,self.y(self.D1))
        #pyplot.plot(self.X,self.y(self.D1,co-1))
        pyplot.grid()
        pyplot.plot(self.X,self.y(self.coeff, co))
        
    def changeWithDerivative(self,co):
        x1 = self.X
        
        #plt.subplot(2, 1, 1)
        plt.plot(x1, self.Y, 'b-')
        plt.plot(x1, self.y(self.D1), 'b-')
        
        plt.grid(which='major', color='k', linestyle='-')

        #plt.subplot(2, 1, 2)
        plt.plot(self.X,self.y(self.coeff, co), 'r-')
        plt.plot(self.X, self.y(self.D1,co-1), 'r-')
        
        
        plt.grid(which='major', color='k', linestyle='-')

        plt.show()
    
             

def functionFromRoots(listOfRoots, start=-5, end = 5, points = 10):
    factors = [(x-a) for a in listOfRoots]
    print "Here are the factors:", factors
    
    
    def ffr(a,b):
        return expand(a*b)
    poly = functools.reduce(lambda a,b: ffr(a,b), factors)
    
    print "Here is the polynomial", latex(poly)
    
    poly = Poly(poly)
    
    return Function(poly.coeffs(), start, end, points)
    
roots = [1,-1,4]
ffr = functionFromRoots(roots)
ffr.plot()   
    
l = [1,-1,-14,0]
a = Function(l)


#a.plotD1D2()
Here are the factors: [x - 1, x + 1, x - 4]
Here is the polynomial x^{3} - 4 x^{2} - x + 4

In [151]:
ff = functionFromRoots([1,2,3])

z = Poly(expand((x+1)*(x+2)*(x+3)))

print z.coeffs()
Here are the factors: [x - 1, x - 2, x - 3]
Here is the polynomial x^{3} - 6 x^{2} + 11 x - 6
[1, 6, 11, 6]

Drawing a Polynomial From Roots

When working with larger degree polynomials we could just enter more numbers into the Function constructor. For example:
f = Function[1,5,-7,12])
The higher the degree the harder it is to intuitively get real roots in a narrow range. For this we can use functionFromRoots(listOfRoots) which takes a list of roots as its argument.
In [152]:
roots = [1,-1,4]
ffr = functionFromRoots(roots)
ffr.plot()
Here are the factors: [x - 1, x + 1, x - 4]
Here is the polynomial x^{3} - 4 x^{2} - x + 4

Using [1,-1,4] makes it hard to look at the key parts so I will also use 'start = -2' to bring the picture into focus
In [153]:
ffr = functionFromRoots(roots, start=-2)
ffr.plotD1D2()
Here are the factors: [x - 1, x + 1, x - 4]
Here is the polynomial x^{3} - 4 x^{2} - x + 4

Change The Sign Of a Coefficient

Arrow Key Nav