<commit_before>from twisted.web import resource
import os

from hatena import Log, ServerLog, Silent, NotFound
from DB import Database
from Hatenatools import TMB

#The movie folder:
class PyResource(resource.Resource):
	isLeaf = False
	def __init__(self):
		resource.Resource.__init__(self)

		self.CreatorID = CreatorIDResource()
	def getChild(self, name, request):
		if Database.CreatorExists(name):
			return self.CreatorID
		elif name == "":
			return self
		else:
			return NotFound
	def render(self, request):
		request.setResponseCode(403)
		return "403 - Denied access"

#The creator ID folder:
class CreatorIDResource(resource.Resource):
	isLeaf = False
	def __init__(self):
		resource.Resource.__init__(self)

		self.CreatorIDFile = CreatorIDFileResource()
	def getChild(self, name, request):
		CreatorID = request.path.split("/")[-2]
		filename = ".".join(name.split(".")[:-1])

		if Database.FlipnoteExists(CreatorID, filename):#html, ppm and info
			return self.CreatorIDFile
		elif name == "":
			return self
		else:
			return NotFound
	def render(self, request):
		request.setResponseCode(403)
		return "403 - Denied access"

#Any public file inside creator ID folder:
class CreatorIDFileResource(resource.Resource):
	isLeaf = True
	def __init__(self):
		resource.Resource.__init__(self)
	def render(self, request):
		creator, file = request.path.split("/")[-2:]
		filetype = file.split(".")[-1].lower()

		if filetype in "ppm":
			#log it:
			path = "/".join(request.path.split("/")[3:])
			Log(request, path)

			#add a view:
			Database.AddView(creator, file[:-4])

			#read ppm file:
			data = Database.GetFlipnotePPM(creator, file[:-4])

			#send file to the client:
			request.responseHeaders.setRawHeaders('content-type', ['text/plain'])
			return data
		elif filetype == "info":
			path = "/".join(request.path.split("/")[3:])
			Log(request, path, True)
			request.responseHeaders.setRawHeaders('content-type', ['text/plain'])
			return "0\n0\n"#undocumented what it means
		elif filetype == "htm":
			#maybe cache the details page of Database.Newest?

			if "mode" in request.args:
				if request.args["mode"][0] == "commentshalfsize":
					pass

			return self.GenerateDetailsPage(creator, ".".join(file.split(".")[:-1])).encode("UTF-8")
		elif filetype == "star":
			path = "/".join(request.path.split("/")[3:])
			headers = request.getAllHeaders()

			#bad formatting
			if "x-hatena-star-count" not in headers:
				ServerLog.write("%s got 403 when requesting %s without a X-Hatena-Star-Count header" % (request.getClientIP(), path), Silent)
				request.setResponseCode(403)
				return "403 - Denied access\nRequest lacks a X-Hatena-Star-Count http header"

			#add the stars:
			amount = int(headers["x-hatena-star-count"])
			if (amount < 1) or (amount > 65535):
				ServerLog.write("%s got 403 when requesting %s with an invalid X-Hatena-Star-Count header" % (request.getClientIP(), path), Silent)
				request.setResponseCode(403)
				return "403 - Denied access\nRequest has an invalid X-Hatena-Star-Count http header"

			if not Database.AddStar(creator, file[:-5], amount):
				#error
				ServerLog.write("%s got 500 when requesting %s" % (request.getClientIP(), path), Silent)
				request.setResponseCode(500)
				return "500 - Internal server error\nAdding the stars seem to have failed."

			#report success
			ServerLog.write("%s added %i stars to %s/%s.ppm" % (request.getClientIP(), amount, creator, file[:-5]), Silent)
			return "Success"
		elif filetype == "dl":
			path = "/".join(request.path.split("/")[3:])
			Log(request, path, True)
			#this is POSTed to when it've been stored to memory.

			Database.AddDownload(creator, file[:-3])

			return "Noted ;)"
		else:
			path = "/".join(request.path.split("/")[3:])
			ServerLog.write("%s got 403 when requesting %s" % (request.getClientIP(), path), Silent)

			request.setResponseCode(403)
			return "403 - Denied access"
	#details page
	def GenerateDetailsPage(self, CreatorID, filename):#filename without ext
		flipnote = Database.GetFlipnote(CreatorID, filename)#flipnote = [filename, views, stars, green stars, red stars, blue stars, purple stars, Channel], all probably strings
		if not flipnote:
			return "This flipnote doesn't exist!"
		tmb = TMB().Read(Database.GetFlipnoteTMB(CreatorID, filename))
		if not tmb:
			return "This flipnote is corrupt!"

		#Is it a spinoff?
		Spinnoff = ""
		if tmb.OriginalAuthorID <> tmb.EditorAuthorID or tmb.OriginalFilename <> tmb.CurrentFilename:
			if Database.FlipnoteExists(tmb.OriginalAuthorID, tmb.OriginalFilename[:-4]):
				Spinnoff = SpinoffTemplate1.replace("%%CreatorID%%", tmb.OriginalAuthorID).replace("%%Filename%%", tmb.OriginalFilename[:-4])
			elif tmb.OriginalAuthorID <> tmb.EditorAuthorID:
				Spinnoff = SpinoffTemplate2

		#make each entry:
		Entries = []

		#Creator username:
		name = "Creator"
		#content = "%s" % (CreatorID, tmb.EditorAuthorName)
		content = '%s' % (CreatorID, tmb.Username)
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Stars:
		name = "Stars"
		content = u'\u2605 %s' % (CreatorID, filename, flipnote[2])#yellow stars
		#todo: add other stars
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Views:
		name = "Views"
		content = str(flipnote[1])
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Channel:
		if flipnote[7]:#todo: make channels work at all
			name = "Channel"
			content = 'a href="http://flipnote.hatena.com/ds/v2-xx/ch/%s.uls">%s' % (flipnote[7], flipnote[7])
			Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Comments:
		Comments = "0"

		#doto: add original author info too

		#add the entries to page:
		return DetailsPageTemplate.replace("%%CreatorID%%", CreatorID).replace("%%Filename%%", filename).replace("%%CommentCount%%", Comments).replace("%%Spinoff%%", Spinnoff).replace("%%PageEntries%%", PageEntrySeparator.join(Entries))

#templates:
DetailsPageTemplate = """

		<title>Flipnote by %%Username%%</title>
		<meta name="upperlink" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
		<meta name="starbutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star">
		<meta name="savebutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
		<meta name="playcontrolbutton" content="">
		<link rel="stylesheet" href="http://flipnote.hatena.com/css/ds/basic.css">

Description

					Comments(%%CommentCount%%)

%%Spinoff%%

%%PageEntries%%

"""
SpinoffTemplate1 = """

			This Flipnote is a spin-off.

			Original Flipnote

"""
SpinoffTemplate2 = """

			This Flipnote is a spin-off.

"""
PageEntryTemplate = """

%%Name%%

						%%Content%%

"""
PageEntrySeparator="""

"""
<commit_msg>Added downloads to movie details (#19)<commit_after>from twisted.web import resource
import os

from hatena import Log, ServerLog, Silent, NotFound
from DB import Database
from Hatenatools import TMB

#The movie folder:
class PyResource(resource.Resource):
	isLeaf = False
	def __init__(self):
		resource.Resource.__init__(self)

		self.CreatorID = CreatorIDResource()
	def getChild(self, name, request):
		if Database.CreatorExists(name):
			return self.CreatorID
		elif name == "":
			return self
		else:
			return NotFound
	def render(self, request):
		request.setResponseCode(403)
		return "403 - Denied access"

#The creator ID folder:
class CreatorIDResource(resource.Resource):
	isLeaf = False
	def __init__(self):
		resource.Resource.__init__(self)

		self.CreatorIDFile = CreatorIDFileResource()
	def getChild(self, name, request):
		CreatorID = request.path.split("/")[-2]
		filename = ".".join(name.split(".")[:-1])

		if Database.FlipnoteExists(CreatorID, filename):#html, ppm and info
			return self.CreatorIDFile
		elif name == "":
			return self
		else:
			return NotFound
	def render(self, request):
		request.setResponseCode(403)
		return "403 - Denied access"

#Any public file inside creator ID folder:
class CreatorIDFileResource(resource.Resource):
	isLeaf = True
	def __init__(self):
		resource.Resource.__init__(self)
	def render(self, request):
		creator, file = request.path.split("/")[-2:]
		filetype = file.split(".")[-1].lower()

		if filetype in "ppm":
			#log it:
			path = "/".join(request.path.split("/")[3:])
			Log(request, path)

			#add a view:
			Database.AddView(creator, file[:-4])

			#read ppm file:
			data = Database.GetFlipnotePPM(creator, file[:-4])

			#send file to the client:
			request.responseHeaders.setRawHeaders('content-type', ['text/plain'])
			return data
		elif filetype == "info":
			path = "/".join(request.path.split("/")[3:])
			Log(request, path, True)
			request.responseHeaders.setRawHeaders('content-type', ['text/plain'])
			return "0\n0\n"#undocumented what it means
		elif filetype == "htm":
			#maybe cache the details page of Database.Newest?

			if "mode" in request.args:
				if request.args["mode"][0] == "commentshalfsize":
					pass

			return self.GenerateDetailsPage(creator, ".".join(file.split(".")[:-1])).encode("UTF-8")
		elif filetype == "star":
			path = "/".join(request.path.split("/")[3:])
			headers = request.getAllHeaders()

			#bad formatting
			if "x-hatena-star-count" not in headers:
				ServerLog.write("%s got 403 when requesting %s without a X-Hatena-Star-Count header" % (request.getClientIP(), path), Silent)
				request.setResponseCode(403)
				return "403 - Denied access\nRequest lacks a X-Hatena-Star-Count http header"

			#add the stars:
			amount = int(headers["x-hatena-star-count"])
			if (amount < 1) or (amount > 65535):
				ServerLog.write("%s got 403 when requesting %s with an invalid X-Hatena-Star-Count header" % (request.getClientIP(), path), Silent)
				request.setResponseCode(403)
				return "403 - Denied access\nRequest has an invalid X-Hatena-Star-Count http header"

			if not Database.AddStar(creator, file[:-5], amount):
				#error
				ServerLog.write("%s got 500 when requesting %s" % (request.getClientIP(), path), Silent)
				request.setResponseCode(500)
				return "500 - Internal server error\nAdding the stars seem to have failed."

			#report success
			ServerLog.write("%s added %i stars to %s/%s.ppm" % (request.getClientIP(), amount, creator, file[:-5]), Silent)
			return "Success"
		elif filetype == "dl":
			path = "/".join(request.path.split("/")[3:])
			Log(request, path, True)
			#this is POSTed to when it've been stored to memory.

			Database.AddDownload(creator, file[:-3])

			return "Noted ;)"
		else:
			path = "/".join(request.path.split("/")[3:])
			ServerLog.write("%s got 403 when requesting %s" % (request.getClientIP(), path), Silent)

			request.setResponseCode(403)
			return "403 - Denied access"
	#details page
	def GenerateDetailsPage(self, CreatorID, filename):#filename without ext
		flipnote = Database.GetFlipnote(CreatorID, filename)#flipnote = [filename, views, stars, green stars, red stars, blue stars, purple stars, Channel], all probably strings
		if not flipnote:
			return "This flipnote doesn't exist!"
		tmb = TMB().Read(Database.GetFlipnoteTMB(CreatorID, filename))
		if not tmb:
			return "This flipnote is corrupt!"

		#Is it a spinoff?
		Spinnoff = ""
		if tmb.OriginalAuthorID <> tmb.EditorAuthorID or tmb.OriginalFilename <> tmb.CurrentFilename:
			if Database.FlipnoteExists(tmb.OriginalAuthorID, tmb.OriginalFilename[:-4]):
				Spinnoff = SpinoffTemplate1.replace("%%CreatorID%%", tmb.OriginalAuthorID).replace("%%Filename%%", tmb.OriginalFilename[:-4])
			elif tmb.OriginalAuthorID <> tmb.EditorAuthorID:
				Spinnoff = SpinoffTemplate2

		#make each entry:
		Entries = []

		#Creator username:
		name = "Creator"
		#content = "%s" % (CreatorID, tmb.EditorAuthorName)
		content = '%s' % (CreatorID, tmb.Username)
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Stars:
		name = "Stars"
		content = u'\u2605 %s' % (CreatorID, filename, flipnote[2])#yellow stars
		#todo: add other stars
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Views:
		name = "Views"
		content = str(flipnote[1])
		Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		# Downloads:
                name = "Downloads"
                content = str(flipnote[8])
                Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Channel:
		if flipnote[7]:#todo: make channels work at all
			name = "Channel"
			content = 'a href="http://flipnote.hatena.com/ds/v2-xx/ch/%s.uls">%s' % (flipnote[7], flipnote[7])
			Entries.append(PageEntryTemplate.replace("%%Name%%", name).replace("%%Content%%", content))

		#Comments:
		Comments = "0"

		#doto: add original author info too

		#add the entries to page:
		return DetailsPageTemplate.replace("%%CreatorID%%", CreatorID).replace("%%Filename%%", filename).replace("%%CommentCount%%", Comments).replace("%%Spinoff%%", Spinnoff).replace("%%PageEntries%%", PageEntrySeparator.join(Entries))

#templates:
DetailsPageTemplate = """

		<title>Flipnote by %%Username%%</title>
		<meta name="upperlink" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
		<meta name="starbutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.star">
		<meta name="savebutton" content="http://flipnote.hatena.com/ds/v2-xx/movie/%%CreatorID%%/%%Filename%%.ppm">
		<meta name="playcontrolbutton" content="">
		<link rel="stylesheet" href="http://flipnote.hatena.com/css/ds/basic.css">

Description

					Comments(%%CommentCount%%)

%%Spinoff%%

%%PageEntries%%

"""
SpinoffTemplate1 = """

			This Flipnote is a spin-off.

			Original Flipnote

"""
SpinoffTemplate2 = """

			This Flipnote is a spin-off.

"""
PageEntryTemplate = """

%%Name%%

						%%Content%%

"""
PageEntrySeparator="""

"""
<|endoftext|>


<commit_before>from __future__ import division

from functools import cmp_to_key
from itertools import cycle

import param
import numpy as np

from ..core.dimension import Dimension
from ..core.data import Dataset
from ..core.operation import Operation
from ..core.util import OrderedDict, unique_array, RecursionError, get_param_values
from .graphs import Graph, Nodes, EdgePaths, redim_graph
from .util import quadratic_bezier

class _layout_sankey(Operation):
    """
    Computes a Sankey diagram from a Graph element for internal use in
    the Sankey element constructor.

    Adapted from d3-sankey under BSD-3 license.
    """

    bounds = param.NumericTuple(default=(0, 0, 1000, 500))

    node_width = param.Number(default=15, doc="""
        Width of the nodes.""")

    node_padding = param.Integer(default=10, doc="""
        Number of pixels of padding relative to the bounds.""")

    iterations = param.Integer(default=32, doc="""
        Number of iterations to run the layout algorithm.""")

    def _process(self, element, key=None):
        nodes, edges, graph = self.layout(element, **self.p)
        params = get_param_values(element)
        return Sankey((element.data, nodes, edges), sankey=graph, **params)

    def layout(self, element, **params):
        self.p = param.ParamOverrides(self, params)
        graph = {'nodes': [], 'links': []}
        self.computeNodeLinks(element, graph)
        self.computeNodeValues(graph)
        self.computeNodeDepths(graph)
        self.computeNodeBreadths(graph)
        self.computeLinkBreadths(graph)
        paths = self.computePaths(graph)

        node_data = []
        for node in graph['nodes']:
            node_data.append((np.mean([node['x0'], node['x1']]),
                              np.mean([node['y0'], node['y1']]),
                              node['index'])+tuple(node['values']))
        if element.nodes.ndims == 3:
            kdims = element.nodes.kdims
        elif element.nodes.ndims:
            kdims = element.node_type.kdims[:2] + element.nodes.kdims[-1:]
        else:
            kdims = element.node_type.kdims
        nodes = element.node_type(node_data, kdims=kdims, vdims=element.nodes.vdims)
        edges = element.edge_type(paths)
        return nodes, edges, graph

    def computePaths(self, graph):
        paths = []
        for link in graph['links']:
            source, target = link['source'], link['target']
            x0, y0 = source['x1'], link['y0']
            x1, y1 = target['x0'], link['y1']
            start = np.array([(x0, link['width']+y0),
                              (x0, y0)])
            src = (x0, y0)
            ctr1 = ((x0+x1)/2., y0)
            ctr2 = ((x0+x1)/2., y1)
            tgt = (x1, y1)
            bottom = quadratic_bezier(src, tgt, ctr1, ctr2)
            mid = np.array([(x1, y1),
                            (x1, y1+link['width'])])

            xmid = (x0+x1)/2.
            y0 = y0+link['width']
            y1 = y1+link['width']
            src = (x1, y1)
            ctr1 = (xmid, y1)
            ctr2 = (xmid, y0)
            tgt = (x0, y0)
            top = quadratic_bezier(src, tgt, ctr1, ctr2)
            spline = np.concatenate([start, bottom, mid, top])
            paths.append(spline)
        return paths

    @classmethod
    def weightedSource(cls, link):
        return cls.nodeCenter(link['source']) * link['value']

    @classmethod
    def weightedTarget(cls, link):
        return cls.nodeCenter(link['target']) * link['value']

    @classmethod
    def nodeCenter(cls, node):
        return (node['y0'] + node['y1']) / 2

    @classmethod
    def ascendingBreadth(cls, a, b):
        return int(a['y0'] - b['y0'])

    @classmethod
    def ascendingSourceBreadth(cls, a, b):
        return cls.ascendingBreadth(a['source'], b['source']) | a['index'] - b['index']

    @classmethod
    def ascendingTargetBreadth(cls, a, b):
        return cls.ascendingBreadth(a['target'], b['target']) | a['index'] - b['index']

    @classmethod
    def computeNodeLinks(cls, element, graph):
        """
        Populate the sourceLinks and targetLinks for each node.
        Also, if the source and target are not objects, assume they are indices.
        """
        index = element.nodes.kdims[-1]
        node_map = {}
        if element.nodes.vdims:
            values = zip(*(element.nodes.dimension_values(d)
                           for d in element.nodes.vdims))
        else:
            values = cycle([tuple()])
        for index, vals in zip(element.nodes.dimension_values(index), values):
            node = {'index': index, 'sourceLinks': [], 'targetLinks': [], 'values': vals}
            graph['nodes'].append(node)
            node_map[index] = node

        links = [element.dimension_values(d) for d in element.dimensions()[:3]]
        for i, (src, tgt, value) in enumerate(zip(*links)):
            source, target = node_map[src], node_map[tgt]
            link = dict(index=i, source=source, target=target, value=value)
            graph['links'].append(link)
            source['sourceLinks'].append(link)
            target['targetLinks'].append(link)

    @classmethod
    def computeNodeValues(cls, graph):
        """
        Compute the value (size) of each node by summing the associated links.
        """
        for node in graph['nodes']:
            source_val = np.sum([l['value'] for l in node['sourceLinks']])
            target_val = np.sum([l['value'] for l in node['targetLinks']])
            node['value'] = max([source_val, target_val])

    def computeNodeDepths(self, graph):
        """
        Iteratively assign the depth (x-position) for each node.
        Nodes are assigned the maximum depth of incoming neighbors plus one;
        nodes with no incoming links are assigned depth zero, while
        nodes with no outgoing links are assigned the maximum depth.
        """
        nodes = graph['nodes']
        depth = 0
        while nodes:
            next_nodes = []
            for node in nodes:
                node['depth'] = depth
                for link in node['sourceLinks']:
                    if link['target'] not in next_nodes:
                        next_nodes.append(link['target'])
            nodes = next_nodes
            depth +=1
            if depth > 10000:
                raise RecursionError('Sankey diagrams only support acyclic graphs.')

        nodes = graph['nodes']
        depth = 0
        while nodes:
            next_nodes = []
            for node in nodes:
                node['height'] = depth
                for link in node['targetLinks']:
                    if link['source'] not in next_nodes:
                        next_nodes.append(link['source'])
            nodes = next_nodes
            depth +=1
            if depth > 10000:
                raise RecursionError('Sankey diagrams only support acyclic graphs.')

        x0, _, x1, _ = self.p.bounds
        dx = self.p.node_width
        kx = (x1 - x0 - dx) / (depth - 1)
        for node in graph['nodes']:
            d  = node['depth'] if node['sourceLinks'] else depth - 1
            node['x0'] = x0 + max([0, min([depth-1, np.floor(d)]) * kx])
            node['x1'] = node['x0'] + dx

    def computeNodeBreadths(self, graph):
        node_map = OrderedDict()
        for n in graph['nodes']:
            if n['x0'] not in node_map:
                node_map[n['x0']] = []
            node_map[n['x0']].append(n)

        _, y0, _, y1 = self.p.bounds
        py = self.p.node_padding

        def initializeNodeBreadth():
            kys = []
            for nodes in node_map.values():
                nsum = np.sum([node['value'] for node in nodes])
                ky = (y1 - y0 - (len(nodes)-1) * py) / nsum
                kys.append(ky)
            ky = np.min(kys)

            for nodes in node_map.values():
                for i, node in enumerate(nodes):
                    node['y0'] = i
                    node['y1'] = i + node['value'] * ky

            for link in graph['links']:
                link['width'] = link['value'] * ky

        def relaxLeftToRight(alpha):
            for nodes in node_map.values():
                for node in nodes:
                    if not node['targetLinks']:
                        continue
                    weighted = sum([self.weightedSource(l) for l in node['targetLinks']])
                    tsum = sum([l['value'] for l in node['targetLinks']])
                    center = self.nodeCenter(node)
                    dy = (weighted/tsum - center)*alpha
                    node['y0'] += dy
                    node['y1'] += dy

        def relaxRightToLeft(alpha):
            for nodes in list(node_map.values())[::-1]:
                for node in nodes:
                    if not node['sourceLinks']:
                        continue
                    weighted = sum([self.weightedTarget(l) for l in node['sourceLinks']])
                    tsum = sum([l['value'] for l in node['sourceLinks']])
                    center = self.nodeCenter(node)
                    dy = (weighted/tsum - center)*alpha
                    node['y0'] += dy
                    node['y1'] += dy

        def resolveCollisions():
            for nodes in node_map.values():
                y = y0
                nodes.sort(key=cmp_to_key(self.ascendingBreadth))
                for node in nodes:
                    dy = y-node['y0']
                    if dy > 0:
                        node['y0'] += dy
                        node['y1'] += dy
                    y = node['y1'] + py

                dy = y-py-y1
                if dy > 0:
                    node['y0'] -= dy
                    node['y1'] -= dy
                    y = node['y0']
                    for node in nodes[:-1][::-1]:
                        dy = node['y1'] + py - y;
                        if dy>0:
                            node['y0'] -= dy
                            node['y1'] -= dy
                        y = node['y0']

        initializeNodeBreadth()
        resolveCollisions()
        alpha = 1
        for _ in range(self.p.iterations):
            alpha = alpha*0.99
            relaxRightToLeft(alpha)
            resolveCollisions()
            relaxLeftToRight(alpha)
            resolveCollisions()

    @classmethod
    def computeLinkBreadths(cls, graph):
        for node in graph['nodes']:
            node['sourceLinks'].sort(key=cmp_to_key(cls.ascendingTargetBreadth))
            node['targetLinks'].sort(key=cmp_to_key(cls.ascendingSourceBreadth))

        for node in graph['nodes']:
            y0 = y1 = node['y0']
            for link in node['sourceLinks']:
                link['y0'] = y0
                y0 += link['width']
            for link in node['targetLinks']:
                link['y1'] = y1
                y1 += link['width']

class Sankey(Graph):
    """
    Sankey is an acyclic, directed Graph type that represents the flow
    of some quantity between its nodes.
    """

    group = param.String(default='Sankey', constant=True)

    vdims = param.List(default=[Dimension('Value')])

    def __init__(self, data, kdims=None, vdims=None, **params):
        if isinstance(data, tuple):
            data = data + (None,)*(3-len(data))
            edges, nodes, edgepaths = data
        else:
            edges, nodes, edgepaths = data, None, None
        sankey_graph = params.pop('sankey', None)
        compute = not (sankey_graph and isinstance(nodes, Nodes) and isinstance(edgepaths, EdgePaths))
        super(Graph, self).__init__(edges, kdims=kdims, vdims=vdims, **params)
        if compute:
            if nodes is None:
                src = self.dimension_values(0, expanded=False)
                tgt = self.dimension_values(1, expanded=False)
                values = unique_array(np.concatenate([src, tgt]))
                nodes = Dataset(values, 'index')
            elif not isinstance(nodes, Dataset):
                try:
                    nodes = Dataset(nodes)
                except:
                    nodes = Dataset(nodes, 'index')
            if not nodes.kdims:
                raise ValueError('Could not determine index in supplied node data. '
                                 'Ensure data has at least one key dimension, '
                                 'which matches the node ids on the edges.')
            self._nodes = nodes
            nodes, edgepaths, graph = _layout_sankey.instance().layout(self)
            self._nodes = nodes
            self._edgepaths = edgepaths
            self._sankey = graph
        else:
            if not isinstance(nodes, self.node_type):
                raise TypeError("Expected Nodes object in data, found %s."
                                % type(nodes))
            self._nodes = nodes
            if not isinstance(edgepaths, self.edge_type):
                raise TypeError("Expected EdgePaths object in data, found %s."
                                % type(edgepaths))
            self._edgepaths = edgepaths
            self._sankey = sankey_graph
        self._validate()
        self.redim = redim_graph(self, mode='dataset')

    def clone(self, data=None, shared_data=True, new_type=None, *args, **overrides):
        if data is None:
            overrides['sankey'] = self._sankey
        return super(Sankey, self).clone(data, shared_data, new_type, *args, **overrides)
<commit_msg>Fixed Sankey recursive comparison issue (#2575)<commit_after>from __future__ import division

from functools import cmp_to_key
from itertools import cycle

import param
import numpy as np

from ..core.dimension import Dimension
from ..core.data import Dataset
from ..core.operation import Operation
from ..core.util import OrderedDict, unique_array, RecursionError, get_param_values
from .graphs import Graph, Nodes, EdgePaths, redim_graph
from .util import quadratic_bezier

class _layout_sankey(Operation):
    """
    Computes a Sankey diagram from a Graph element for internal use in
    the Sankey element constructor.

    Adapted from d3-sankey under BSD-3 license.
    """

    bounds = param.NumericTuple(default=(0, 0, 1000, 500))

    node_width = param.Number(default=15, doc="""
        Width of the nodes.""")

    node_padding = param.Integer(default=10, doc="""
        Number of pixels of padding relative to the bounds.""")

    iterations = param.Integer(default=32, doc="""
        Number of iterations to run the layout algorithm.""")

    def _process(self, element, key=None):
        nodes, edges, graph = self.layout(element, **self.p)
        params = get_param_values(element)
        return Sankey((element.data, nodes, edges), sankey=graph, **params)

    def layout(self, element, **params):
        self.p = param.ParamOverrides(self, params)
        graph = {'nodes': [], 'links': []}
        self.computeNodeLinks(element, graph)
        self.computeNodeValues(graph)
        self.computeNodeDepths(graph)
        self.computeNodeBreadths(graph)
        self.computeLinkBreadths(graph)
        paths = self.computePaths(graph)

        node_data = []
        for node in graph['nodes']:
            node_data.append((np.mean([node['x0'], node['x1']]),
                              np.mean([node['y0'], node['y1']]),
                              node['index'])+tuple(node['values']))
        if element.nodes.ndims == 3:
            kdims = element.nodes.kdims
        elif element.nodes.ndims:
            kdims = element.node_type.kdims[:2] + element.nodes.kdims[-1:]
        else:
            kdims = element.node_type.kdims
        nodes = element.node_type(node_data, kdims=kdims, vdims=element.nodes.vdims)
        edges = element.edge_type(paths)
        return nodes, edges, graph

    def computePaths(self, graph):
        paths = []
        for link in graph['links']:
            source, target = link['source'], link['target']
            x0, y0 = source['x1'], link['y0']
            x1, y1 = target['x0'], link['y1']
            start = np.array([(x0, link['width']+y0),
                              (x0, y0)])
            src = (x0, y0)
            ctr1 = ((x0+x1)/2., y0)
            ctr2 = ((x0+x1)/2., y1)
            tgt = (x1, y1)
            bottom = quadratic_bezier(src, tgt, ctr1, ctr2)
            mid = np.array([(x1, y1),
                            (x1, y1+link['width'])])

            xmid = (x0+x1)/2.
            y0 = y0+link['width']
            y1 = y1+link['width']
            src = (x1, y1)
            ctr1 = (xmid, y1)
            ctr2 = (xmid, y0)
            tgt = (x0, y0)
            top = quadratic_bezier(src, tgt, ctr1, ctr2)
            spline = np.concatenate([start, bottom, mid, top])
            paths.append(spline)
        return paths

    @classmethod
    def weightedSource(cls, link):
        return cls.nodeCenter(link['source']) * link['value']

    @classmethod
    def weightedTarget(cls, link):
        return cls.nodeCenter(link['target']) * link['value']

    @classmethod
    def nodeCenter(cls, node):
        return (node['y0'] + node['y1']) / 2

    @classmethod
    def ascendingBreadth(cls, a, b):
        return int(a['y0'] - b['y0'])

    @classmethod
    def ascendingSourceBreadth(cls, a, b):
        return cls.ascendingBreadth(a['source'], b['source']) | a['index'] - b['index']

    @classmethod
    def ascendingTargetBreadth(cls, a, b):
        return cls.ascendingBreadth(a['target'], b['target']) | a['index'] - b['index']

    @classmethod
    def computeNodeLinks(cls, element, graph):
        """
        Populate the sourceLinks and targetLinks for each node.
        Also, if the source and target are not objects, assume they are indices.
        """
        index = element.nodes.kdims[-1]
        node_map = {}
        if element.nodes.vdims:
            values = zip(*(element.nodes.dimension_values(d)
                           for d in element.nodes.vdims))
        else:
            values = cycle([tuple()])
        for index, vals in zip(element.nodes.dimension_values(index), values):
            node = {'index': index, 'sourceLinks': [], 'targetLinks': [], 'values': vals}
            graph['nodes'].append(node)
            node_map[index] = node

        links = [element.dimension_values(d) for d in element.dimensions()[:3]]
        for i, (src, tgt, value) in enumerate(zip(*links)):
            source, target = node_map[src], node_map[tgt]
            link = dict(index=i, source=source, target=target, value=value)
            graph['links'].append(link)
            source['sourceLinks'].append(link)
            target['targetLinks'].append(link)

    @classmethod
    def computeNodeValues(cls, graph):
        """
        Compute the value (size) of each node by summing the associated links.
        """
        for node in graph['nodes']:
            source_val = np.sum([l['value'] for l in node['sourceLinks']])
            target_val = np.sum([l['value'] for l in node['targetLinks']])
            node['value'] = max([source_val, target_val])

    def computeNodeDepths(self, graph):
        """
        Iteratively assign the depth (x-position) for each node.
        Nodes are assigned the maximum depth of incoming neighbors plus one;
        nodes with no incoming links are assigned depth zero, while
        nodes with no outgoing links are assigned the maximum depth.
        """
        nodes = graph['nodes']
        depth = 0
        while nodes:
            next_nodes = []
            for node in nodes:
                node['depth'] = depth
                for link in node['sourceLinks']:
                    if not any(link['target'] is node for node in next_nodes):
                        next_nodes.append(link['target'])
            nodes = next_nodes
            depth += 1
            if depth > 10000:
                raise RecursionError('Sankey diagrams only support acyclic graphs.')

        nodes = graph['nodes']
        depth = 0
        while nodes:
            next_nodes = []
            for node in nodes:
                node['height'] = depth
                for link in node['targetLinks']:
                    if not any(link['source'] is node for node in next_nodes):
                        next_nodes.append(link['source'])
            nodes = next_nodes
            depth += 1
            if depth > 10000:
                raise RecursionError('Sankey diagrams only support acyclic graphs.')

        x0, _, x1, _ = self.p.bounds
        dx = self.p.node_width
        kx = (x1 - x0 - dx) / (depth - 1)
        for node in graph['nodes']:
            d  = node['depth'] if node['sourceLinks'] else depth - 1
            node['x0'] = x0 + max([0, min([depth-1, np.floor(d)]) * kx])
            node['x1'] = node['x0'] + dx

    def computeNodeBreadths(self, graph):
        node_map = OrderedDict()
        for n in graph['nodes']:
            if n['x0'] not in node_map:
                node_map[n['x0']] = []
            node_map[n['x0']].append(n)

        _, y0, _, y1 = self.p.bounds
        py = self.p.node_padding

        def initializeNodeBreadth():
            kys = []
            for nodes in node_map.values():
                nsum = np.sum([node['value'] for node in nodes])
                ky = (y1 - y0 - (len(nodes)-1) * py) / nsum
                kys.append(ky)
            ky = np.min(kys)

            for nodes in node_map.values():
                for i, node in enumerate(nodes):
                    node['y0'] = i
                    node['y1'] = i + node['value'] * ky

            for link in graph['links']:
                link['width'] = link['value'] * ky

        def relaxLeftToRight(alpha):
            for nodes in node_map.values():
                for node in nodes:
                    if not node['targetLinks']:
                        continue
                    weighted = sum([self.weightedSource(l) for l in node['targetLinks']])
                    tsum = sum([l['value'] for l in node['targetLinks']])
                    center = self.nodeCenter(node)
                    dy = (weighted/tsum - center)*alpha
                    node['y0'] += dy
                    node['y1'] += dy

        def relaxRightToLeft(alpha):
            for nodes in list(node_map.values())[::-1]:
                for node in nodes:
                    if not node['sourceLinks']:
                        continue
                    weighted = sum([self.weightedTarget(l) for l in node['sourceLinks']])
                    tsum = sum([l['value'] for l in node['sourceLinks']])
                    center = self.nodeCenter(node)
                    dy = (weighted/tsum - center)*alpha
                    node['y0'] += dy
                    node['y1'] += dy

        def resolveCollisions():
            for nodes in node_map.values():
                y = y0
                nodes.sort(key=cmp_to_key(self.ascendingBreadth))
                for node in nodes:
                    dy = y-node['y0']
                    if dy > 0:
                        node['y0'] += dy
                        node['y1'] += dy
                    y = node['y1'] + py

                dy = y-py-y1
                if dy > 0:
                    node['y0'] -= dy
                    node['y1'] -= dy
                    y = node['y0']
                    for node in nodes[:-1][::-1]:
                        dy = node['y1'] + py - y;
                        if dy>0:
                            node['y0'] -= dy
                            node['y1'] -= dy
                        y = node['y0']

        initializeNodeBreadth()
        resolveCollisions()
        alpha = 1
        for _ in range(self.p.iterations):
            alpha = alpha*0.99
            relaxRightToLeft(alpha)
            resolveCollisions()
            relaxLeftToRight(alpha)
            resolveCollisions()

    @classmethod
    def computeLinkBreadths(cls, graph):
        for node in graph['nodes']:
            node['sourceLinks'].sort(key=cmp_to_key(cls.ascendingTargetBreadth))
            node['targetLinks'].sort(key=cmp_to_key(cls.ascendingSourceBreadth))

        for node in graph['nodes']:
            y0 = y1 = node['y0']
            for link in node['sourceLinks']:
                link['y0'] = y0
                y0 += link['width']
            for link in node['targetLinks']:
                link['y1'] = y1
                y1 += link['width']

class Sankey(Graph):
    """
    Sankey is an acyclic, directed Graph type that represents the flow
    of some quantity between its nodes.
    """

    group = param.String(default='Sankey', constant=True)

    vdims = param.List(default=[Dimension('Value')])

    def __init__(self, data, kdims=None, vdims=None, **params):
        if isinstance(data, tuple):
            data = data + (None,)*(3-len(data))
            edges, nodes, edgepaths = data
        else:
            edges, nodes, edgepaths = data, None, None
        sankey_graph = params.pop('sankey', None)
        compute = not (sankey_graph and isinstance(nodes, Nodes) and isinstance(edgepaths, EdgePaths))
        super(Graph, self).__init__(edges, kdims=kdims, vdims=vdims, **params)
        if compute:
            if nodes is None:
                src = self.dimension_values(0, expanded=False)
                tgt = self.dimension_values(1, expanded=False)
                values = unique_array(np.concatenate([src, tgt]))
                nodes = Dataset(values, 'index')
            elif not isinstance(nodes, Dataset):
                try:
                    nodes = Dataset(nodes)
                except:
                    nodes = Dataset(nodes, 'index')
            if not nodes.kdims:
                raise ValueError('Could not determine index in supplied node data. '
                                 'Ensure data has at least one key dimension, '
                                 'which matches the node ids on the edges.')
            self._nodes = nodes
            nodes, edgepaths, graph = _layout_sankey.instance().layout(self)
            self._nodes = nodes
            self._edgepaths = edgepaths
            self._sankey = graph
        else:
            if not isinstance(nodes, self.node_type):
                raise TypeError("Expected Nodes object in data, found %s."
                                % type(nodes))
            self._nodes = nodes
            if not isinstance(edgepaths, self.edge_type):
                raise TypeError("Expected EdgePaths object in data, found %s."
                                % type(edgepaths))
            self._edgepaths = edgepaths
            self._sankey = sankey_graph
        self._validate()
        self.redim = redim_graph(self, mode='dataset')

    def clone(self, data=None, shared_data=True, new_type=None, *args, **overrides):
        if data is None:
            overrides['sankey'] = self._sankey
        return super(Sankey, self).clone(data, shared_data, new_type, *args, **overrides)
<|endoftext|>


<commit_before>import unittest

from calexicon.constants import *

class TestConstants(unittest.TestCase):
    def test_constants(self):
        self.assertEqual(number_of_days_in_400_gregorian_years, 365 * 400 + 97)
<commit_msg>Remove import *.<commit_after>import unittest

from calexicon.constants import number_of_days_in_400_gregorian_years

class TestConstants(unittest.TestCase):
    def test_constants(self):
        self.assertEqual(number_of_days_in_400_gregorian_years, 365 * 400 + 97)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
controlpoint.py
~~~~~~~~~~~~~~~

This file contains the primary ControlPoint class. This is the core portion of
the API, and implements the bulk of the UPnP functionality.
"""
import socket
import random

# Minimum and maximum ports to bind to locally.
LOW_PORT  = 10000
HIGH_PORT = 65535

class ControlPoint(object):
    """
    Represents a single UPnP control point.
    """
    def __init__(self):
        self.__bind_sockets()

    def __bind_sockets(self):
        """
        Bind any necessary sockets.
        """
        local_port = random.randint(LOW_PORT, HIGH_PORT)
        self.__udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__udp_socket.bind(('', local_port))
        return

    def discover(self, duration):
        """
        Discover UPnP devices on the network.

        :param duration: The number of seconds to listen for responses to the
                         initial discovery request.
        """
        # Set the socket to broadcast mode.
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

        # Build the message. Currently, this just involves blatting a
        # pre-written message over the wire.
        msg = '\r\n'.join(["M-SEARCH * HTTP/1.1",
                           "HOST: 239.255.255.250:1900",
                           "MAN: ssdp:discover",
                           "MX: " + str(duration),
                           "ST: ssdp:all",
                           ""])

        # Send the message.
        sock.sendto(msg, ('<broadcast>', 1900))
        return
<commit_msg>Actually listen to the discovery packets<commit_after># -*- coding: utf-8 -*-
"""
controlpoint.py
~~~~~~~~~~~~~~~

This file contains the primary ControlPoint class. This is the core portion of
the API, and implements the bulk of the UPnP functionality.
"""
import socket
import random
import time

# Minimum and maximum ports to bind to locally.
LOW_PORT  = 10000
HIGH_PORT = 65535

class ControlPoint(object):
    """
    Represents a single UPnP control point.
    """
    def __init__(self):
        self.__bind_sockets()

    def __bind_sockets(self):
        """
        Bind any necessary sockets.
        """
        local_port = random.randint(LOW_PORT, HIGH_PORT)
        self.__udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__udp_socket.bind(('', local_port))
        self.__udp_socket.setblocking(0)
        return

    def discover(self, duration):
        """
        Discover UPnP devices on the network.

        :param duration: The number of seconds to listen for responses to the
                         initial discovery request.
        """
        # Set the socket to broadcast mode.
        self.__udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

        # Build the message. Currently, this just involves blatting a
        # pre-written message over the wire.
        msg = '\r\n'.join(["M-SEARCH * HTTP/1.1",
                           "HOST: 239.255.255.250:1900",
                           "MAN: ssdp:discover",
                           "MX: " + str(duration),
                           "ST: ssdp:all",
                           ""])

        # Send the message.
        self.__udp_socket.sendto(msg, ('<broadcast>', 1900))

        # Return the socket to its pre-broadcast-mode state.
        self.__udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

        return self._listen_for_discover(duration)

    def _listen_for_discover(self, duration):
        """
        Listen for responses to the discovery packet for a number of seconds up
        to the value of ``duration``.

        :param duration: The number of seconds to listen for responses to the
                         initial discovery request.
        """
        start = time.time()

        while (time.time() < (start + duration)):
            try:
                data, addr = self.__udp_socket.recvfrom(2048)
                print data
            except socket.error:
                pass

        return
<|endoftext|>


<commit_before>from __future__ import print_function, division

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

def lex_keyfile(filename):
    lines = []
    with open(filename) as fh:
        for line in fh:
            for ignored in ["#", ";"]:
                if line.startswith(ignored):
                    break
            else:
                lines.append(line.rstrip().split('\t'))
    return lines

def count_keyfile_lines(filename):
    """Count number of barcodes in keyfile"""
    return len(lex_keyfile(filename))

def keyfile_names(filename):
    """Parse names only from keyfile"""
    return [bcd[-1] for bcd in lex_keyfile(filename)]
<commit_msg>remove obsolete simhelpers module<commit_after><|endoftext|>


<commit_before>from rest_framework import status, permissions
from rest_framework.views import APIView
from rest_framework.response import Response
import json

from django.http import Http404, HttpResponseBadRequest, HttpResponse

from .serializers import *
from .heartRateAnalyzer import *

class DataTypes(APIView):
	def get(self, request, format=None):
		dataTypes = DataType.objects.all()
		serializer = DataTypeSerializer(dataTypes, many=True)
		return Response(serializer.data)
	def post(self, request, format=None):
		serializer = DataTypeSerializer(data=request.DATA)
		if serializer.is_valid():
			serializer.save()
			return Response(serializer.data, status=status.HTTP_200_OK)
		return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserTest(APIView):
	def get(self, request, format=None):
		users = User.objects.all()
		serializer = UserSerializer(users, many=True)
		return Response(serializer.data)
	def post(self, request, format=None):
		serializer = UserSerializer(data=request.DATA)
		if serializer.is_valid(raise_exception=True):
			serializer.save()
			return Response(serializer.data, status=status.HTTP_200_OK)
		else:
			return HttpResponse(json.dumps({"user": "2"}), content_type='application/json')

class HeartRateInfo(APIView):
	def get(self, request, format=None):
		age = int(request.GET.get("age", 0))
		print("testing age: " + str(age))
		if age <= 0:
			return HttpResponseBadRequest("Invalid Age")

		analyzer = HeartRateAnalyzer()
		max_hr = {"max_hr": analyzer.maxHR(age)}
		return HttpResponse(json.dumps(max_hr), content_type='application/json')

class httpResponse(APIView):
	def get(self, request, format=None):
		to_json = {"Test": 1}
		return HttpResponse(json.dumps(to_json), content_type='application/json')

class IndexView(APIView):
	def get(self, request, format=None):
		template = loader.get_template("core/index.html")
		c = Context()
		return HttpResponse(template.render(c))

	# form_class = UserRegistrationForm
	# success_url = reverse_lazy("organizations")
<commit_msg>Added TargetHR to analysis payload<commit_after>from rest_framework import status, permissions
from rest_framework.views import APIView
from rest_framework.response import Response
import json

from django.http import Http404, HttpResponseBadRequest, HttpResponse

from .serializers import *
from .heartRateAnalyzer import *

class DataTypes(APIView):
	def get(self, request, format=None):
		dataTypes = DataType.objects.all()
		serializer = DataTypeSerializer(dataTypes, many=True)
		return Response(serializer.data)
	def post(self, request, format=None):
		serializer = DataTypeSerializer(data=request.DATA)
		if serializer.is_valid():
			serializer.save()
			return Response(serializer.data, status=status.HTTP_200_OK)
		return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class UserTest(APIView):
	def get(self, request, format=None):
		users = User.objects.all()
		serializer = UserSerializer(users, many=True)
		return Response(serializer.data)
	def post(self, request, format=None):
		serializer = UserSerializer(data=request.DATA)
		if serializer.is_valid(raise_exception=True):
			serializer.save()
			return Response(serializer.data, status=status.HTTP_200_OK)
		else:
			return HttpResponse(json.dumps({"user": "2"}), content_type='application/json')

class HeartRateInfo(APIView):
	def get(self, request, format=None):
		age = int(request.GET.get("age", 0))
		print("Testing age: " + str(age))
		if age <= 0:
			return HttpResponseBadRequest("Invalid Age")

		analyzer = HeartRateAnalyzer()
		max_hr = {"max_hr": analyzer.maxHR(age), "target_hr": analyzer.targetHRZone(age)}
		return HttpResponse(json.dumps(max_hr), content_type='application/json')

class httpResponse(APIView):
	def get(self, request, format=None):
		to_json = {"Test": 1}
		return HttpResponse(json.dumps(to_json), content_type='application/json')

class IndexView(APIView):
	def get(self, request, format=None):
		template = loader.get_template("core/index.html")
		c = Context()
		return HttpResponse(template.render(c))

	# form_class = UserRegistrationForm
	# success_url = reverse_lazy("organizations")
<|endoftext|>


<commit_before>import copy
import numpy as np
from matplotlib import pyplot as plt

try:
    from mpld3 import plugins
except:
    plugins = None

import param

from ..core.options import Store
from ..ipython.magics import ViewMagic
from ..core import NdOverlay, Overlay
from ..element import HeatMap, Raster, Scatter, Curve, Points, Bars, Histogram
from ..plotting import Plot, CurvePlot, PointPlot, OverlayPlot, MatrixPlot, HistogramPlot

class PlottingHook(param.ParameterizedFunction):
    """
    PlottingHooks can be used to extend the default functionality
    of HoloViews. Each ElementPlot type can be provided with a list of
    hooks to apply at the end of plotting. The PlottingHook is provided
    with ElementPlot instance, which gives access to the figure, axis
    and artists via the handles, and the Element currently displayed
    by the Plot. Since each Plot can be associated with multiple
    Element plot types the Element types are validated against the
    Elements in the types parameter.
    """

    types = param.List([], doc="""List of types processed by the hook.""")

    __abstract = True

    def _applies(self, plot, view):
        return type(view) in self.types

class MplD3Plugin(PlottingHook):
    """
    The mpld3 library available as an optional backend
    for HoloViews provides the option of adding
    interactivity to the plot through various plugins.
    Subclasses of this PlottingHook can enable
    """

    css = param.String(doc="""CSS applied to HTML mpld3 Plugins.""", default="""
          table {border-collapse: collapse;}
          th {color: #ffffff; background-color: #000000;}
          td {background-color: #cccccc;}
          table, th, td {font-family:Arial, Helvetica, sans-serif;
                         border: 1px solid black; text-align: right;}""")

    hoffset = param.Integer(default=10, doc="Vertical offset of the labels.")

    voffset = param.Integer(default=10, doc="Horizontal offset of the labels.")

    __abstract = True

    def _applies(self, plot, view):
        types_match = super(MplD3Plugin, self)._applies(view)
        if plot.projection == '3d': return False
        if plot.subplots:
            return not any(sp.projection == '3d' for sp in plot.subplots.values())
        mpld3_backend = ViewMagic.options['backend'] == 'd3'
        return types_match and mpld3_backend

class PointPlugin(MplD3Plugin):
    "Labels each point with a table of its values."

    types = param.List([Points, Scatter])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        df = view.dframe()
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))
        tooltip = plugins.PointHTMLTooltip(plot.handles['paths'], labels,
                                           voffset=self.voffset, hoffset=self.hoffset,
                                           css=self.css)
        plugins.connect(fig, tooltip)

class CurvePlugin(MplD3Plugin):
    "Labels each line with the Curve objects label"

    format_string = param.String(default='
{label}
', doc="""
       Defines the HTML representation of the Element label""")

    types = param.List([Curve])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        labels = [self.format_string.format(label=view.label)]
        tooltip = plugins.LineHTMLTooltip(plot.handles['line_segment'], labels,
                                          voffset=self.voffset, hoffset=self.hoffset,
                                          css=self.css)
        plugins.connect(fig, tooltip)

class BarPlugin(MplD3Plugin):
    "Labels each bar with a table of its values."

    types = param.List([Bars, Histogram])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']

        df = view.dframe()
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))

        for i, (bar, label) in enumerate(zip(plot.handles['bars'].get_children(), labels)):
            tooltip = plugins.LineHTMLTooltip(bar, label, voffset=self.voffset,
                                              hoffset=self.hoffset, css=self.css)
            plugins.connect(fig, tooltip)

class RasterPlugin(MplD3Plugin):
    """
    Replaces the imshow based Raster image with a
    pcolormesh, allowing each pixel to be labelled.
    """

    types = param.List(default=[Raster, HeatMap])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return

        fig = plot.handles['fig']
        ax = plot.handles['axis']
        valid_opts = ['cmap']

        opts = {k:v for k,v, in Store.lookup_options(view, 'style').options.items()
                if k in valid_opts}

        data = view.data
        if isinstance(view, HeatMap):
            data = np.ma.array(data, mask=np.isnan(data))
            cmap = copy.copy(plt.cm.get_cmap(opts.get('cmap', 'gray')))
            cmap.set_bad('w', 1.)
            for ann in plot.handles['annotations'].values():
                ann.set_visible(False)
            df = view.dframe(True).fillna(0)
            df = df.sort([d.name for d in view.dimensions()[1:2]])[::-1]
        else:
            df = view.dframe().sort([d.name for d in view.dimensions()[0:2]][::-1])[::-1]

        # Generate color mesh to label each point
        l, b, r, t = view.extents
        rows, cols = view.data.shape
        cmin, cmax = view.range(2)
        x, y = np.meshgrid(np.linspace(l, r, cols+1), np.linspace(b, t, rows+1))
        plot.handles['im'].set_visible(False)
        mesh = ax.pcolormesh(x, y, data[::-1,:], vmin=cmin, vmax=cmax, **opts)
        ax.invert_yaxis() # Doesn't work uninverted
        df.index = range(len(df))
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))

        tooltip = plugins.PointHTMLTooltip(mesh, labels[::-1], hoffset=self.hoffset,
                                           voffset=self.voffset, css=self.css)
        plugins.connect(fig, tooltip)

class LegendPlugin(MplD3Plugin):
    """
    Provides an interactive legend allowing selecting
    and unselecting of different elements.
    """

    alpha_unsel = param.Number(default=0.2, doc="""
       The alpha level of the unselected elements""")

    alpha_sel = param.Number(default=2.0, doc="""
       The alpha level of the unselected elements""")

    types = param.List([Overlay, NdOverlay])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        line_segments, labels = [], []
        keys = view.keys()
        for idx, subplot in enumerate(plot.subplots.values()):
            if isinstance(subplot, PointPlot):
                line_segments.append(subplot.handles['paths'])
                if isinstance(view, NdOverlay):
                    labels.append(str(keys[idx]))
                else:
                    labels.append(subplot.map.last.label)
            elif isinstance(subplot, CurvePlot):
                line_segments.append(subplot.handles['line_segment'])
                if isinstance(view, NdOverlay):
                    labels.append(str(keys[idx]))
                else:
                    labels.append(subplot.map.last.label)

        tooltip = plugins.InteractiveLegendPlugin(line_segments, labels,
                                                  alpha_sel=self.alpha_sel,
                                                  alpha_unsel=self.alpha_unsel)
        plugins.connect(fig, tooltip)

if plugins is not None:
    OverlayPlot.finalize_hooks = [LegendPlugin]
    MatrixPlot.finalize_hooks = [RasterPlugin]
    CurvePlot.finalize_hooks = [CurvePlugin]
    PointPlot.finalize_hooks = [PointPlugin]
    HistogramPlot.finalize_hooks = [BarPlugin]
<commit_msg>Fixed MplD3Hook bug<commit_after>import copy
import numpy as np
from matplotlib import pyplot as plt

try:
    from mpld3 import plugins
except:
    plugins = None

import param

from ..core.options import Store
from ..ipython.magics import ViewMagic
from ..core import NdOverlay, Overlay
from ..element import HeatMap, Raster, Scatter, Curve, Points, Bars, Histogram
from ..plotting import Plot, CurvePlot, PointPlot, OverlayPlot, MatrixPlot, HistogramPlot

class PlottingHook(param.ParameterizedFunction):
    """
    PlottingHooks can be used to extend the default functionality
    of HoloViews. Each ElementPlot type can be provided with a list of
    hooks to apply at the end of plotting. The PlottingHook is provided
    with ElementPlot instance, which gives access to the figure, axis
    and artists via the handles, and the Element currently displayed
    by the Plot. Since each Plot can be associated with multiple
    Element plot types the Element types are validated against the
    Elements in the types parameter.
    """

    types = param.List([], doc="""List of types processed by the hook.""")

    __abstract = True

    def _applies(self, plot, view):
        return type(view) in self.types

class MplD3Plugin(PlottingHook):
    """
    The mpld3 library available as an optional backend
    for HoloViews provides the option of adding
    interactivity to the plot through various plugins.
    Subclasses of this PlottingHook can enable
    """

    css = param.String(doc="""CSS applied to HTML mpld3 Plugins.""", default="""
          table {border-collapse: collapse;}
          th {color: #ffffff; background-color: #000000;}
          td {background-color: #cccccc;}
          table, th, td {font-family:Arial, Helvetica, sans-serif;
                         border: 1px solid black; text-align: right;}""")

    hoffset = param.Integer(default=10, doc="Vertical offset of the labels.")

    voffset = param.Integer(default=10, doc="Horizontal offset of the labels.")

    __abstract = True

    def _applies(self, plot, view):
        types_match = super(MplD3Plugin, self)._applies(plot, view)
        if plot.projection == '3d': return False
        if plot.subplots:
            return not any(sp.projection == '3d' for sp in plot.subplots.values())
        mpld3_backend = ViewMagic.options['backend'] == 'd3'
        return types_match and mpld3_backend

class PointPlugin(MplD3Plugin):
    "Labels each point with a table of its values."

    types = param.List([Points, Scatter])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        df = view.dframe()
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))
        tooltip = plugins.PointHTMLTooltip(plot.handles['paths'], labels,
                                           voffset=self.voffset, hoffset=self.hoffset,
                                           css=self.css)
        plugins.connect(fig, tooltip)

class CurvePlugin(MplD3Plugin):
    "Labels each line with the Curve objects label"

    format_string = param.String(default='
{label}
', doc="""
       Defines the HTML representation of the Element label""")

    types = param.List([Curve])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        labels = [self.format_string.format(label=view.label)]
        tooltip = plugins.LineHTMLTooltip(plot.handles['line_segment'], labels,
                                          voffset=self.voffset, hoffset=self.hoffset,
                                          css=self.css)
        plugins.connect(fig, tooltip)

class BarPlugin(MplD3Plugin):
    "Labels each bar with a table of its values."

    types = param.List([Bars, Histogram])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']

        df = view.dframe()
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))

        for i, (bar, label) in enumerate(zip(plot.handles['bars'].get_children(), labels)):
            tooltip = plugins.LineHTMLTooltip(bar, label, voffset=self.voffset,
                                              hoffset=self.hoffset, css=self.css)
            plugins.connect(fig, tooltip)

class RasterPlugin(MplD3Plugin):
    """
    Replaces the imshow based Raster image with a
    pcolormesh, allowing each pixel to be labelled.
    """

    types = param.List(default=[Raster, HeatMap])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return

        fig = plot.handles['fig']
        ax = plot.handles['axis']
        valid_opts = ['cmap']

        opts = {k:v for k,v, in Store.lookup_options(view, 'style').options.items()
                if k in valid_opts}

        data = view.data
        if isinstance(view, HeatMap):
            data = np.ma.array(data, mask=np.isnan(data))
            cmap = copy.copy(plt.cm.get_cmap(opts.get('cmap', 'gray')))
            cmap.set_bad('w', 1.)
            for ann in plot.handles['annotations'].values():
                ann.set_visible(False)
            df = view.dframe(True).fillna(0)
            df = df.sort([d.name for d in view.dimensions()[1:2]])[::-1]
        else:
            df = view.dframe().sort([d.name for d in view.dimensions()[0:2]][::-1])[::-1]

        # Generate color mesh to label each point
        l, b, r, t = view.extents
        rows, cols = view.data.shape
        cmin, cmax = view.range(2)
        x, y = np.meshgrid(np.linspace(l, r, cols+1), np.linspace(b, t, rows+1))
        plot.handles['im'].set_visible(False)
        mesh = ax.pcolormesh(x, y, data[::-1,:], vmin=cmin, vmax=cmax, **opts)
        ax.invert_yaxis() # Doesn't work uninverted
        df.index = range(len(df))
        labels = []
        for i in range(len(df)):
            label = df.ix[[i], :].T
            label.columns = [view.label]
            labels.append(str(label.to_html(header=len(view.label)>0)))

        tooltip = plugins.PointHTMLTooltip(mesh, labels[::-1], hoffset=self.hoffset,
                                           voffset=self.voffset, css=self.css)
        plugins.connect(fig, tooltip)

class LegendPlugin(MplD3Plugin):
    """
    Provides an interactive legend allowing selecting
    and unselecting of different elements.
    """

    alpha_unsel = param.Number(default=0.2, doc="""
       The alpha level of the unselected elements""")

    alpha_sel = param.Number(default=2.0, doc="""
       The alpha level of the unselected elements""")

    types = param.List([Overlay, NdOverlay])

    def __call__(self, plot, view):
        if not self._applies(plot, view): return
        fig = plot.handles['fig']
        line_segments, labels = [], []
        keys = view.keys()
        for idx, subplot in enumerate(plot.subplots.values()):
            if isinstance(subplot, PointPlot):
                line_segments.append(subplot.handles['paths'])
                if isinstance(view, NdOverlay):
                    labels.append(str(keys[idx]))
                else:
                    labels.append(subplot.map.last.label)
            elif isinstance(subplot, CurvePlot):
                line_segments.append(subplot.handles['line_segment'])
                if isinstance(view, NdOverlay):
                    labels.append(str(keys[idx]))
                else:
                    labels.append(subplot.map.last.label)

        tooltip = plugins.InteractiveLegendPlugin(line_segments, labels,
                                                  alpha_sel=self.alpha_sel,
                                                  alpha_unsel=self.alpha_unsel)
        plugins.connect(fig, tooltip)

if plugins is not None:
    OverlayPlot.finalize_hooks = [LegendPlugin]
    MatrixPlot.finalize_hooks = [RasterPlugin]
    CurvePlot.finalize_hooks = [CurvePlugin]
    PointPlot.finalize_hooks = [PointPlugin]
    HistogramPlot.finalize_hooks = [BarPlugin]
<|endoftext|>


<commit_before>from __future__ import division
from math import sqrt
#import tool

#itemSimSet=tool.loadPickle('/itemSimOnType.pkl')

def sim_distance(prefs,item1,item2):
	#get the list of shared items
    si={};
    for item in prefs[item1]:
        if item in prefs[item2]:
            si[item]=1;
    #if they have no shared items,return 0;
    if len(si)==0:return 0;

    #Add the squares of all the differences
    sum_of_squares=sum([pow(prefs[item1][item]-prefs[item2][item],2) for item in prefs[item1] if item in prefs[item2]])
    return 1/(1+sqrt(sum_of_squares))

# Returns the Pearson correlation coefficient for p1 and p2
def sim_pearson(prefs,p1,p2):
    # Get the list of mutually rated items
	si={}
	for item in prefs[p1]:
		if item in prefs[p2]: si[item]=1

	# if they are no ratings in common, return 0
	if len(si)==0: return 0

	# Sum calculations
	n=len(si)

	# Sums of all the preferences
	sum1=float(sum([prefs[p1][it] for it in si]))
	sum2=float(sum([prefs[p2][it] for it in si]))

	# Sums of the squares
	sum1Sq=float(sum([pow(prefs[p1][it],2) for it in si]))
	sum2Sq=float(sum([pow(prefs[p2][it],2) for it in si]))

	# Sum of the products
	pSum=float(sum([prefs[p1][it]*prefs[p2][it] for it in si]))

	# Calculate r (Pearson score)
	num=float(pSum-(sum1*sum2/n))
	den=float(sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n)))
	if den==0: return 0

	r=float(num/den)

	return round(r,7)

def sim_pearson1(prefs,person1,person2):
	#get the list of shared items
	si={}
	for item in prefs[person1]:
		if item in prefs[person2]:
			si[item]=1
    #if they have no shared items, return 0
	if len(si)==0:return 0

    #find the number of elements
	n=len(si)

    #add up all the prefs
	sum1=sum([prefs[person1][item] for item in si])
	sum2=sum([prefs[person2][item] for item in si])

    #calculate the mean of the critics of p1 and p2
	mean1=sum1/n;
	mean2=sum2/n;

    #calculate the covariance
	covariance=sum([(prefs[person1][item]-mean1)*(prefs[person2][item]-mean2) for item in si])/n

    #calculate the standard_deviation
	sd1=sqrt(sum([pow(prefs[person1][item]-mean1,2) for item in si])/n)
	sd2=sqrt(sum([pow(prefs[person2][item]-mean2,2) for item in si])/n)

	if sd1*sd2==0:return 0
    #calculate the pearson correlation improved
	pearson=(covariance/(sd1*sd2))
	return pearson

def sim_pearson_improved(prefs,person1,person2):
	#get the list of shared items
	si={}
	for item in prefs[person1]:
		if item in prefs[person2]:
			si[item]=1
    #if they have no shared items, return 0
	if len(si)==0:return 0

    #find the number of elements
	n=len(si)

    #get the count of items rated by person
	count1=0
	count2=0
	for person in prefs[person1]:
		count1+=1
	for item in prefs[person2]:
		count2+=1

	totalCount=count1+count2-n

    #add up all the prefs
	sum1=sum([prefs[person1][item] for item in si])
	sum2=sum([prefs[person2][item] for item in si])

    #calculate the mean of the critics of p1 and p2
	mean1=sum1/n;
	mean2=sum2/n;

    #calculate the covariance
	covariance=sum([(prefs[person1][item]-mean1)*(prefs[person2][item]-mean2) for item in si])/n

    #calculate the standard_deviation
	sd1=sqrt(sum([pow(prefs[person1][item]-mean1,2) for item in si])/n)
	sd2=sqrt(sum([pow(prefs[person2][item]-mean2,2) for item in si])/n)

	if sd1*sd2==0:return 0
    #calculate the pearson correlation improved
	pearson=(covariance/(sd1*sd2))*(float(n)/float(totalCount))
    #print n,count,float(n)/float(count),pearson
	return pearson

def sim_cosine(prefs,item1,item2):
	si={}
	for i in prefs[item1]:
		if i in prefs[item2]:
			si[i]=1
	#print si
	if len(si)==0: return 0
	x=sqrt(sum([prefs[item1][it]**2 for it in si]))
	y=sqrt(sum([prefs[item2][it]**2 for it in si]))
	xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
	cos=xy/(x*y)
	return cos
def sim_cosine_improved(prefs,item1,item2):
	si={}
	for i in prefs[item1]:
		if i in prefs[item2]:
			si[i]=1
	#print si
	n=len(si)
	if n==0: return 0

	count1=0
	count2=0
	for item in prefs[item1]:
		count1+=1
	for item in prefs[item2]:
		count2+=1

	totalCount=count1+count2-n

	x=sqrt(sum([prefs[item1][it]**2 for it in si]))
	y=sqrt(sum([prefs[item2][it]**2 for it in si]))
	xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
	cos=xy/(x*y)
	return cos*(float(n)/float(totalCount))

def sim_Jaccard(s1,s2,length):
	count=0
	for i in range(0,length):
		if s1[i]=='1' and s2[i]=='1':
			count+=1
		if s1[i]=='1\n' and s2[i]=='1\n':
			count+=1
	return count/(length-count)

def sim_itemType(s1,s2,length):
	count=0
	for i in range(0,length):
		if s1[i]=='1' and s2[i]=='1':
			count+=1
		if s1[i]=='1\n' and s2[i]=='1\n':
			count+=1
	return count/5

def sim_cosine_improved_tag(prefs,item1,item2,movieTags):
	common=0
	for i in movieTags[item1]:
		if i in movieTags[item2]:
			common+=1
	if common>=5:
		return 0.8
	else:
		si={}
		for i in prefs[item1]:
			if i in prefs[item2]:
				si[i]=1
		#print si
		n=len(si)
		if n==0: return 0

		count1=0
		count2=0
		for item in prefs[item1]:
			count1+=1
		for item in prefs[item2]:
			count2+=1

		totalCount=count1+count2-n

		x=sqrt(sum([prefs[item1][it]**2 for it in si]))
		y=sqrt(sum([prefs[item2][it]**2 for it in si]))
		xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
		cos=xy/(x*y)
		return cos*(float(n)/float(totalCount))

#def sim_pearson_improved_typeAdded(prefs,item1,item2):
#	pearson_improved=sim_pearson_improved(prefs,item1,item2)
#	item_type=itemSimSet[item1][item2]
#	return 0.9*(pearson_improved+1)/2.0+0.1*item_type
<commit_msg>Formatting similarity.py<commit_after>from __future__ import division
from math import sqrt
#import tool

#itemSimSet=tool.loadPickle('/itemSimOnType.pkl')

def sim_distance(prefs,item1,item2):
	#get the list of shared items
	si={};
	for item in prefs[item1]:
		if item in prefs[item2]:
			si[item]=1;
	#if they have no shared items,return 0;
	if len(si)==0:return 0;

	#Add the squares of all the differences
	sum_of_squares=sum([pow(prefs[item1][item]-prefs[item2][item],2) for item in prefs[item1] if item in prefs[item2]])
	return 1/(1+sqrt(sum_of_squares))

# Returns the Pearson correlation coefficient for p1 and p2
def sim_pearson(prefs,p1,p2):
	# Get the list of mutually rated items
	si={}
	for item in prefs[p1]:
		if item in prefs[p2]: si[item]=1

	# if they are no ratings in common, return 0
	if len(si)==0: return 0

	# Sum calculations
	n=len(si)

	# Sums of all the preferences
	sum1=float(sum([prefs[p1][it] for it in si]))
	sum2=float(sum([prefs[p2][it] for it in si]))

	# Sums of the squares
	sum1Sq=float(sum([pow(prefs[p1][it],2) for it in si]))
	sum2Sq=float(sum([pow(prefs[p2][it],2) for it in si]))

	# Sum of the products
	pSum=float(sum([prefs[p1][it]*prefs[p2][it] for it in si]))

	# Calculate r (Pearson score)
	num=float(pSum-(sum1*sum2/n))
	den=float(sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n)))
	if den==0: return 0

	r=float(num/den)

	return round(r,7)

def sim_pearson1(prefs,person1,person2):
	#get the list of shared items
	si={}
	for item in prefs[person1]:
		if item in prefs[person2]:
			si[item]=1
	#if they have no shared items, return 0
	if len(si)==0:return 0

	#find the number of elements
	n=len(si)

	#add up all the prefs
	sum1=sum([prefs[person1][item] for item in si])
	sum2=sum([prefs[person2][item] for item in si])

	#calculate the mean of the critics of p1 and p2
	mean1=sum1/n;
	mean2=sum2/n;

	#calculate the covariance
	covariance=sum([(prefs[person1][item]-mean1)*(prefs[person2][item]-mean2) for item in si])/n

	#calculate the standard_deviation
	sd1=sqrt(sum([pow(prefs[person1][item]-mean1,2) for item in si])/n)
	sd2=sqrt(sum([pow(prefs[person2][item]-mean2,2) for item in si])/n)

	if sd1*sd2==0:return 0
	#calculate the pearson correlation improved
	pearson=(covariance/(sd1*sd2))
	return pearson

def sim_pearson_improved(prefs,person1,person2):
	#get the list of shared items
	si={}
	for item in prefs[person1]:
		if item in prefs[person2]:
			si[item]=1
	#if they have no shared items, return 0
	if len(si)==0:return 0

	#find the number of elements
	n=len(si)

	#get the count of items rated by person
	count1=0
	count2=0
	for person in prefs[person1]:
		count1+=1
	for item in prefs[person2]:
		count2+=1

	totalCount=count1+count2-n

	#add up all the prefs
	sum1=sum([prefs[person1][item] for item in si])
	sum2=sum([prefs[person2][item] for item in si])

	#calculate the mean of the critics of p1 and p2
	mean1=sum1/n;
	mean2=sum2/n;

	#calculate the covariance
	covariance=sum([(prefs[person1][item]-mean1)*(prefs[person2][item]-mean2) for item in si])/n
	#calculate the standard_deviation
	sd1=sqrt(sum([pow(prefs[person1][item]-mean1,2) for item in si])/n)
	sd2=sqrt(sum([pow(prefs[person2][item]-mean2,2) for item in si])/n)

	if sd1*sd2==0:return 0
	#calculate the pearson correlation improved
	pearson=(covariance/(sd1*sd2))*(float(n)/float(totalCount))
	#print n,count,float(n)/float(count),pearson
	return pearson

def sim_cosine(prefs,item1,item2):
	si={}
	for i in prefs[item1]:
		if i in prefs[item2]:
			si[i]=1
	#print si
	if len(si)==0: return 0
	x=sqrt(sum([prefs[item1][it]**2 for it in si]))
	y=sqrt(sum([prefs[item2][it]**2 for it in si]))
	xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
	cos=xy/(x*y)
	return cos
def sim_cosine_improved(prefs,item1,item2):
	si={}
	for i in prefs[item1]:
		if i in prefs[item2]:
			si[i]=1
	#print si
	n=len(si)
	if n==0: return 0

	count1=0
	count2=0
	for item in prefs[item1]:
		count1+=1
	for item in prefs[item2]:
		count2+=1

	totalCount=count1+count2-n

	x=sqrt(sum([prefs[item1][it]**2 for it in si]))
	y=sqrt(sum([prefs[item2][it]**2 for it in si]))
	xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
	cos=xy/(x*y)
	return cos*(float(n)/float(totalCount))

def sim_Jaccard(s1,s2,length):
	count=0
	for i in range(0,length):
		if s1[i]=='1' and s2[i]=='1':
			count+=1
		if s1[i]=='1\n' and s2[i]=='1\n':
			count+=1
	return count/(length-count)

def sim_itemType(s1,s2,length):
	count=0
	for i in range(0,length):
		if s1[i]=='1' and s2[i]=='1':
			count+=1
		if s1[i]=='1\n' and s2[i]=='1\n':
			count+=1
	return count/5

def sim_cosine_improved_tag(prefs,item1,item2,movieTags):
	common=0
	for i in movieTags[item1]:
		if i in movieTags[item2]:
			common+=1
	if common>=5:
		return 0.8
	else:
		si={}
		for i in prefs[item1]:
			if i in prefs[item2]:
				si[i]=1
		#print si
		n=len(si)
		if n==0: return 0

		count1=0
		count2=0
		for item in prefs[item1]:
			count1+=1
		for item in prefs[item2]:
			count2+=1

		totalCount=count1+count2-n

		x=sqrt(sum([prefs[item1][it]**2 for it in si]))
		y=sqrt(sum([prefs[item2][it]**2 for it in si]))
		xy=sum([prefs[item1][it]*prefs[item2][it] for it in si])
		cos=xy/(x*y)
		return cos*(float(n)/float(totalCount))

#def sim_pearson_improved_typeAdded(prefs,item1,item2):
#	pearson_improved=sim_pearson_improved(prefs,item1,item2)
#	item_type=itemSimSet[item1][item2]
#	return 0.9*(pearson_improved+1)/2.0+0.1*item_type
<|endoftext|>