{"action":"created","comment":{"url":"https://api.github.com/repos/bhtucker/agents/pulls/comments/65008399","id":65008399,"diff_hunk":"@@ -35,182 +37,330 @@\n     'C': 'g'\n }\n \n-MESSAGES = [\n-    \"message one\",\n-    \"message dos\",\n-]\n+\n \n class Population(object):\n+    \"\"\"A set of connected Entities. Handles message passing and displaying.\"\"\"\n+\n     def __init__(self):\n         self.points = []\n         self.path = []\n         self.show = True\n         self.success_lens = []\n+        self.connectivity_matrix = None\n+\n \n     def pass_message(self, recipient, task, sender):\n-        display(self.points, self.connectivity_matrix, recipient, task.target, show=self.show)\n+        \"\"\"\n+        Displays current state and routes the message one connection\n+        down. Handles the case where the recipient is the target. Calls\n+        Entity.receive_task(). <recipient> is the index of the recipient\n+        Entity.\n+        \"\"\"\n+\n+        self.display(recipient, task.target)\n         self.path.append(recipient)\n+        self.points[recipient].receive_task(task, sender)\n+\n         if recipient == task.target:\n             # import ipdb ; ipdb.set_trace#z()  # breakpoint 223cdcc4 //\n \n-            k = float(len(self.path))\n-            for ix, point in enumerate(self.path):\n-                i_value = (task.value / k) + ((k - ix) * 5)\n-                self.points[point].award(i_value)\n+            for point in self.path:\n+                amount = self.calculate_award(task, self.path, point)\n+                self.points[point].award(amount)\n+\n             self.success_lens.append(len(self.path))\n             self.path = []\n \n-        self.points[recipient].receive_task(task, sender)\n+\n+    def calculate_award(self, task, path, entity):\n+        \"\"\"\n+        Returns the amount awarded to <entity> after <task> has been\n+        routed through <path>.\n+        \"\"\"\n+        k = k = float(len(path))\n+        return (task.value / k) + ((k - path.index(entity)) * 5)\n+\n \n     def set_connections(self):\n-        self.connectivity_matrix = get_connectivity_matrix(self.points)\n+        \"\"\"Initializes each Entity's adjacency list.\"\"\"\n+\n+        self.make_connectivity_matrix()\n         for index, point in enumerate(self.points):\n             point.set_adjacencies(self.connectivity_matrix[index])\n \n-    def display(self):\n-        display(self.points, self.connectivity_matrix, show=self.show)\n+\n+    def make_connectivity_matrix(self):\n+        \"\"\"\n+        Computes the connectivity matrix of this Population. Each point is\n+        connected to each other within a radius.\n+        \"\"\"\n+\n+        if self.connectivity_matrix:\n+            return\n+\n+        points_arr = np.array([[p.x, p.y] for p in self.points])\n+        distance_mat = euclidean_distances(points_arr, points_arr)\n+\n+        # Every point p will be connected to each other point whose distance\n+        # to p is less than a cut-off value. This value is computed as the\n+        # mean of {min_nonzero(dist_mat(p)) | p is a point}, times a factor\n+        min_nonzero = lambda r: min(r[r > 0])\n+\n+        # apply_along_axis(f, axis=1, arr) applies f to each row\n+        min_neighbor_distances = np.apply_along_axis(min_nonzero, axis=1, arr=distance_mat)\n+\n+        factor = 2.2\n+        neighbor_cutoff = np.mean(min_neighbor_distances) * factor\n+        connectivity_matrix = distance_mat < neighbor_cutoff\n+\n+        self.connectivity_matrix = connectivity_matrix\n+\n+\n+    def display(self, current=None, target=None):\n+        \"\"\"\n+        Plots the state of the task. If <show> = False, doesn't plot\n+        anything and the simulation can run faster.\n+        \"\"\"\n+\n+        if not self.show:\n+            return\n+\n+        # Scatter plot of points, color coded by class\n+        pts = self.points\n+        size = 35\n+        for cluster, color in cluster_colors.iteritems():\n+            class_points = [x for x in pts if x.cluster == cluster]\n+            plt.scatter([p.x for p in class_points], [p.y for p in class_points], c=color, s=size)\n+\n+        # Draw the connections\n+        if self.connectivity_matrix is not None:\n+            for start_ix, connections in enumerate(self.connectivity_matrix):\n+                for connect_ix, connected in enumerate(connections):\n+                    if connected and connect_ix != start_ix:\n+                        plt.plot(*zip(\n+                            (pts[start_ix].x, pts[start_ix].y),\n+                            (pts[connect_ix].x, pts[connect_ix].y)),\n+                            c='k', linewidth=0.5)\n+\n+        # Show where the message is going and where it currently is\n+        if current and target:\n+            plt.scatter(pts[current].x, pts[current].y, c='m', s=150)\n+            plt.scatter(pts[target].x,  pts[target].y,  c='y', s=190)\n+\n+        plt.show()\n+\n \n     def initiate_task(self, fixed_pair=None):\n-        start, end = ([-1, -1] if not fixed_pair else fixed_pair)\n+        \"\"\"Initializes a task, and calls pass_message().\"\"\"\n+\n+        start, end = [-1, -1] if not fixed_pair else fixed_pair\n+\n+        if fixed_pair and start == end:\n+            print(\"changing fixed pair: they're the same!\")\n+\n         while start == end:\n             [start, end] = np.random.randint(len(self.points), size=2).tolist()\n-        message = choice(MESSAGES)\n-        print('new task: %s' % message)\n+\n+        print('new task created')\n         print('starting at %s and aiming for %s' % (start, end))\n-        task = Task(end, message)\n-        self.pass_message(start, task, len(self.points))\n+\n+        task = Task(end)\n+        self.pass_message(start, task, None)\n+\n \n     def clear(self):\n+        \"\"\"\n+        Clear every Entity's history. Called when the package is stuck\n+        in a cycle.\n+        \"\"\"\n+\n         for point in self.points:\n-            # point.adjacencies = list(set(point.adjacencies))\n             adjs = point.adjacencies, set(point.adjacencies)\n             if len(adjs[0]) != len(adjs[1]):\n                 print(\"clearing %s\" % point.index + '---' * 20)\n                 print(point.adjacencies, set(point.adjacencies))\n             point.sent = []\n \n+\n+\n class Task(object):\n-    def __init__(self, target, message):\n+    \"\"\"Represents a message to be routed.\"\"\"\n+\n+    def __init__(self, target):\n         self.target = target\n-        self.message = message\n         self.id = uuid4()\n         self.value = 100\n \n \n+\n class Entity(object):\n     \"\"\"An entity in our world\"\"\"\n+\n     def __init__(self, population, index, x, y, cluster):\n         self.x = x\n         self.y = y\n         self.index = index\n         self.cluster = cluster\n-        self.adjacencies = []\n         self.population = population\n+\n+        self.sent = []    # list of points to whom I've passed the current message\n+        self.value = 0    # value awarded for a successful message\n+\n+        # extended adjacency list (see pass_message() and learn())\n+        self.adjacencies = []\n+\n+        # task_attempt_map[task_id] hold a list of the neighbors to whom\n+        # this entity gave the task\n         self.task_attempt_map = defaultdict(lambda: [index])\n-        self.sent = []\n-        self.value = 0\n-    \n+\n+\n     def receive_task(self, task, sender):\n-        if sender not in self.task_attempt_map[task.id]:\n-            self.task_attempt_map[task.id].append(sender)\n-        print(sender, self.sent)\n-        if sender in self.sent:\n-            print('popping %s' % self.sent.pop(self.sent.index(sender)))\n+        \"\"\"\n+        Handles a message received. Calls pass_message(). Use\n+        sender=None if this is the Entity that receives the original\n+        message.\n+        \"\"\"\n+\n+        print(\"%d: past receipients are \" % (self.index,) + str(self.sent))\n+\n+        if sender:\n+            if sender not in self.task_attempt_map[task.id]:\n+                self.task_attempt_map[task.id].append(sender)\n+\n+            if sender in self.sent:\n+                print('popping %s' % self.sent.pop(self.sent.index(sender)))\n+\n+        # If I have passed the message to all of my neighbors and I still\n+        # received it back, bail out.\n         if set(self.adjacencies).issubset(set(self.task_attempt_map[task.id])):\n+            # FIXME: this catches cycles eventually, but also catches randomly\n+            # followed closed paths\n             print 'caught in a cycle! bailing!'\n             self.population.clear()\n             return\n+\n         if self.index == task.target:\n-            print 'message delivered! %s' % task.message\n+            print 'message delivered!'\n         else:\n             self.pass_message(task, sender)\n \n-    def compare(self, other):\n-        pass\n \n     def pass_message(self, task, sender):\n+        \"\"\"\n+        If this Entity knows the target, send the message directly.\n+        Otherwise, choose randomly among the (extended) adjacency list.\n+        Calls Population.pass_message() with the chosen target.\n+        \"\"\"\n+\n         next_recipient = task.target if task.target in self.adjacencies else self.index\n+\n         while next_recipient in self.task_attempt_map[task.id]:\n             next_recipient = choice(self.adjacencies)\n+\n         self.task_attempt_map[task.id].append(next_recipient)\n-        print \"passing message from %s to %s\" % (self.index, next_recipient)\n+        print \"%s -> %s\" % (self.index, next_recipient)\n+\n         self.sent.append(next_recipient)\n         self.population.pass_message(next_recipient, task, self.index)\n \n+\n     def set_adjacencies(self, connectivity_vector):\n+        \"\"\"\n+        Builds the adjacency list for this Entity. <connectivity_vector>\n+        is a row from an adjacency matrix.\n+        \"\"\"\n+\n         for connect_ix, connected in enumerate(connectivity_vector):\n             if connected and connect_ix != self.index:\n                 self.adjacencies.append(connect_ix)\n \n \n     def award(self, value):\n+        \"\"\"\n+        Accepts <value> as award after having participated in the\n+        successful routing of a message. Calls self.learn() and then\n+        cleans up to prepare for the next message.\n+        \"\"\"\n+\n         self.value += value\n-        print(self.value, self.index, self.adjacencies)\n+        print(\"\")\n+        print(\"awarding %.2f to %d\" % (self.value, self.index))\n+        print(\"Map: \" + str(dict(self.task_attempt_map)))\n+        print(\"Adj before: \" + str(self.adjacencies))\n+\n+        self.learn()","path":"abm_sketch.py","position":318,"original_position":318,"commit_id":"2448575b85f1945b6793564cff2583793a74ffdf","original_commit_id":"2448575b85f1945b6793564cff2583793a74ffdf","user":{"login":"bhtucker","id":4284131,"avatar_url":"https://avatars.githubusercontent.com/u/4284131?v=3","gravatar_id":"","url":"https://api.github.com/users/bhtucker","html_url":"https://github.com/bhtucker","followers_url":"https://api.github.com/users/bhtucker/followers","following_url":"https://api.github.com/users/bhtucker/following{/other_user}","gists_url":"https://api.github.com/users/bhtucker/gists{/gist_id}","starred_url":"https://api.github.com/users/bhtucker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhtucker/subscriptions","organizations_url":"https://api.github.com/users/bhtucker/orgs","repos_url":"https://api.github.com/users/bhtucker/repos","events_url":"https://api.github.com/users/bhtucker/events{/privacy}","received_events_url":"https://api.github.com/users/bhtucker/received_events","type":"User","site_admin":false},"body":"great","created_at":"2016-05-29T17:19:24Z","updated_at":"2016-05-29T17:19:24Z","html_url":"https://github.com/bhtucker/agents/pull/1#discussion_r65008399","pull_request_url":"https://api.github.com/repos/bhtucker/agents/pulls/1","_links":{"self":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/comments/65008399"},"html":{"href":"https://github.com/bhtucker/agents/pull/1#discussion_r65008399"},"pull_request":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/1"}}},"pull_request":{"url":"https://api.github.com/repos/bhtucker/agents/pulls/1","id":71814223,"html_url":"https://github.com/bhtucker/agents/pull/1","diff_url":"https://github.com/bhtucker/agents/pull/1.diff","patch_url":"https://github.com/bhtucker/agents/pull/1.patch","issue_url":"https://api.github.com/repos/bhtucker/agents/issues/1","number":1,"state":"open","locked":false,"title":"Network generation","user":{"login":"Leockard","id":1096704,"avatar_url":"https://avatars.githubusercontent.com/u/1096704?v=3","gravatar_id":"","url":"https://api.github.com/users/Leockard","html_url":"https://github.com/Leockard","followers_url":"https://api.github.com/users/Leockard/followers","following_url":"https://api.github.com/users/Leockard/following{/other_user}","gists_url":"https://api.github.com/users/Leockard/gists{/gist_id}","starred_url":"https://api.github.com/users/Leockard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Leockard/subscriptions","organizations_url":"https://api.github.com/users/Leockard/orgs","repos_url":"https://api.github.com/users/Leockard/repos","events_url":"https://api.github.com/users/Leockard/events{/privacy}","received_events_url":"https://api.github.com/users/Leockard/received_events","type":"User","site_admin":false},"body":"I studied the code line by line, added comments and refactored a few bits. Fixed a couple of bugs. Changed the console output to make it more descriptive.\r\n\r\nI submit a PR now because both the code and the inner workings of the simulation behave almost exactly the same as in master, whereas the next changes I'll be making from now on will change how the network is created.","created_at":"2016-05-28T23:33:32Z","updated_at":"2016-05-29T17:19:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d069cabb307712c4398adb2d05d5b1520d76f0e2","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/bhtucker/agents/pulls/1/commits","review_comments_url":"https://api.github.com/repos/bhtucker/agents/pulls/1/comments","review_comment_url":"https://api.github.com/repos/bhtucker/agents/pulls/comments{/number}","comments_url":"https://api.github.com/repos/bhtucker/agents/issues/1/comments","statuses_url":"https://api.github.com/repos/bhtucker/agents/statuses/2448575b85f1945b6793564cff2583793a74ffdf","head":{"label":"bhtucker:network_generation","ref":"network_generation","sha":"2448575b85f1945b6793564cff2583793a74ffdf","user":{"login":"bhtucker","id":4284131,"avatar_url":"https://avatars.githubusercontent.com/u/4284131?v=3","gravatar_id":"","url":"https://api.github.com/users/bhtucker","html_url":"https://github.com/bhtucker","followers_url":"https://api.github.com/users/bhtucker/followers","following_url":"https://api.github.com/users/bhtucker/following{/other_user}","gists_url":"https://api.github.com/users/bhtucker/gists{/gist_id}","starred_url":"https://api.github.com/users/bhtucker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhtucker/subscriptions","organizations_url":"https://api.github.com/users/bhtucker/orgs","repos_url":"https://api.github.com/users/bhtucker/repos","events_url":"https://api.github.com/users/bhtucker/events{/privacy}","received_events_url":"https://api.github.com/users/bhtucker/received_events","type":"User","site_admin":false},"repo":{"id":59847156,"name":"agents","full_name":"bhtucker/agents","owner":{"login":"bhtucker","id":4284131,"avatar_url":"https://avatars.githubusercontent.com/u/4284131?v=3","gravatar_id":"","url":"https://api.github.com/users/bhtucker","html_url":"https://github.com/bhtucker","followers_url":"https://api.github.com/users/bhtucker/followers","following_url":"https://api.github.com/users/bhtucker/following{/other_user}","gists_url":"https://api.github.com/users/bhtucker/gists{/gist_id}","starred_url":"https://api.github.com/users/bhtucker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhtucker/subscriptions","organizations_url":"https://api.github.com/users/bhtucker/orgs","repos_url":"https://api.github.com/users/bhtucker/repos","events_url":"https://api.github.com/users/bhtucker/events{/privacy}","received_events_url":"https://api.github.com/users/bhtucker/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bhtucker/agents","description":"Agent based modeling from the ground up","fork":false,"url":"https://api.github.com/repos/bhtucker/agents","forks_url":"https://api.github.com/repos/bhtucker/agents/forks","keys_url":"https://api.github.com/repos/bhtucker/agents/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bhtucker/agents/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bhtucker/agents/teams","hooks_url":"https://api.github.com/repos/bhtucker/agents/hooks","issue_events_url":"https://api.github.com/repos/bhtucker/agents/issues/events{/number}","events_url":"https://api.github.com/repos/bhtucker/agents/events","assignees_url":"https://api.github.com/repos/bhtucker/agents/assignees{/user}","branches_url":"https://api.github.com/repos/bhtucker/agents/branches{/branch}","tags_url":"https://api.github.com/repos/bhtucker/agents/tags","blobs_url":"https://api.github.com/repos/bhtucker/agents/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bhtucker/agents/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bhtucker/agents/git/refs{/sha}","trees_url":"https://api.github.com/repos/bhtucker/agents/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bhtucker/agents/statuses/{sha}","languages_url":"https://api.github.com/repos/bhtucker/agents/languages","stargazers_url":"https://api.github.com/repos/bhtucker/agents/stargazers","contributors_url":"https://api.github.com/repos/bhtucker/agents/contributors","subscribers_url":"https://api.github.com/repos/bhtucker/agents/subscribers","subscription_url":"https://api.github.com/repos/bhtucker/agents/subscription","commits_url":"https://api.github.com/repos/bhtucker/agents/commits{/sha}","git_commits_url":"https://api.github.com/repos/bhtucker/agents/git/commits{/sha}","comments_url":"https://api.github.com/repos/bhtucker/agents/comments{/number}","issue_comment_url":"https://api.github.com/repos/bhtucker/agents/issues/comments{/number}","contents_url":"https://api.github.com/repos/bhtucker/agents/contents/{+path}","compare_url":"https://api.github.com/repos/bhtucker/agents/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bhtucker/agents/merges","archive_url":"https://api.github.com/repos/bhtucker/agents/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bhtucker/agents/downloads","issues_url":"https://api.github.com/repos/bhtucker/agents/issues{/number}","pulls_url":"https://api.github.com/repos/bhtucker/agents/pulls{/number}","milestones_url":"https://api.github.com/repos/bhtucker/agents/milestones{/number}","notifications_url":"https://api.github.com/repos/bhtucker/agents/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bhtucker/agents/labels{/name}","releases_url":"https://api.github.com/repos/bhtucker/agents/releases{/id}","deployments_url":"https://api.github.com/repos/bhtucker/agents/deployments","created_at":"2016-05-27T16:07:57Z","updated_at":"2016-05-27T16:19:31Z","pushed_at":"2016-05-28T23:33:32Z","git_url":"git://github.com/bhtucker/agents.git","ssh_url":"git@github.com:bhtucker/agents.git","clone_url":"https://github.com/bhtucker/agents.git","svn_url":"https://github.com/bhtucker/agents","homepage":null,"size":141,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"bhtucker:master","ref":"master","sha":"7395d9f5ebd4f050170af071b2ce6c31ee4450ec","user":{"login":"bhtucker","id":4284131,"avatar_url":"https://avatars.githubusercontent.com/u/4284131?v=3","gravatar_id":"","url":"https://api.github.com/users/bhtucker","html_url":"https://github.com/bhtucker","followers_url":"https://api.github.com/users/bhtucker/followers","following_url":"https://api.github.com/users/bhtucker/following{/other_user}","gists_url":"https://api.github.com/users/bhtucker/gists{/gist_id}","starred_url":"https://api.github.com/users/bhtucker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhtucker/subscriptions","organizations_url":"https://api.github.com/users/bhtucker/orgs","repos_url":"https://api.github.com/users/bhtucker/repos","events_url":"https://api.github.com/users/bhtucker/events{/privacy}","received_events_url":"https://api.github.com/users/bhtucker/received_events","type":"User","site_admin":false},"repo":{"id":59847156,"name":"agents","full_name":"bhtucker/agents","owner":{"login":"bhtucker","id":4284131,"avatar_url":"https://avatars.githubusercontent.com/u/4284131?v=3","gravatar_id":"","url":"https://api.github.com/users/bhtucker","html_url":"https://github.com/bhtucker","followers_url":"https://api.github.com/users/bhtucker/followers","following_url":"https://api.github.com/users/bhtucker/following{/other_user}","gists_url":"https://api.github.com/users/bhtucker/gists{/gist_id}","starred_url":"https://api.github.com/users/bhtucker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bhtucker/subscriptions","organizations_url":"https://api.github.com/users/bhtucker/orgs","repos_url":"https://api.github.com/users/bhtucker/repos","events_url":"https://api.github.com/users/bhtucker/events{/privacy}","received_events_url":"https://api.github.com/users/bhtucker/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bhtucker/agents","description":"Agent based modeling from the ground up","fork":false,"url":"https://api.github.com/repos/bhtucker/agents","forks_url":"https://api.github.com/repos/bhtucker/agents/forks","keys_url":"https://api.github.com/repos/bhtucker/agents/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bhtucker/agents/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bhtucker/agents/teams","hooks_url":"https://api.github.com/repos/bhtucker/agents/hooks","issue_events_url":"https://api.github.com/repos/bhtucker/agents/issues/events{/number}","events_url":"https://api.github.com/repos/bhtucker/agents/events","assignees_url":"https://api.github.com/repos/bhtucker/agents/assignees{/user}","branches_url":"https://api.github.com/repos/bhtucker/agents/branches{/branch}","tags_url":"https://api.github.com/repos/bhtucker/agents/tags","blobs_url":"https://api.github.com/repos/bhtucker/agents/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bhtucker/agents/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bhtucker/agents/git/refs{/sha}","trees_url":"https://api.github.com/repos/bhtucker/agents/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bhtucker/agents/statuses/{sha}","languages_url":"https://api.github.com/repos/bhtucker/agents/languages","stargazers_url":"https://api.github.com/repos/bhtucker/agents/stargazers","contributors_url":"https://api.github.com/repos/bhtucker/agents/contributors","subscribers_url":"https://api.github.com/repos/bhtucker/agents/subscribers","subscription_url":"https://api.github.com/repos/bhtucker/agents/subscription","commits_url":"https://api.github.com/repos/bhtucker/agents/commits{/sha}","git_commits_url":"https://api.github.com/repos/bhtucker/agents/git/commits{/sha}","comments_url":"https://api.github.com/repos/bhtucker/agents/comments{/number}","issue_comment_url":"https://api.github.com/repos/bhtucker/agents/issues/comments{/number}","contents_url":"https://api.github.com/repos/bhtucker/agents/contents/{+path}","compare_url":"https://api.github.com/repos/bhtucker/agents/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bhtucker/agents/merges","archive_url":"https://api.github.com/repos/bhtucker/agents/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bhtucker/agents/downloads","issues_url":"https://api.github.com/repos/bhtucker/agents/issues{/number}","pulls_url":"https://api.github.com/repos/bhtucker/agents/pulls{/number}","milestones_url":"https://api.github.com/repos/bhtucker/agents/milestones{/number}","notifications_url":"https://api.github.com/repos/bhtucker/agents/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bhtucker/agents/labels{/name}","releases_url":"https://api.github.com/repos/bhtucker/agents/releases{/id}","deployments_url":"https://api.github.com/repos/bhtucker/agents/deployments","created_at":"2016-05-27T16:07:57Z","updated_at":"2016-05-27T16:19:31Z","pushed_at":"2016-05-28T23:33:32Z","git_url":"git://github.com/bhtucker/agents.git","ssh_url":"git@github.com:bhtucker/agents.git","clone_url":"https://github.com/bhtucker/agents.git","svn_url":"https://github.com/bhtucker/agents","homepage":null,"size":141,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/1"},"html":{"href":"https://github.com/bhtucker/agents/pull/1"},"issue":{"href":"https://api.github.com/repos/bhtucker/agents/issues/1"},"comments":{"href":"https://api.github.com/repos/bhtucker/agents/issues/1/comments"},"review_comments":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/1/comments"},"review_comment":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/bhtucker/agents/pulls/1/commits"},"statuses":{"href":"https://api.github.com/repos/bhtucker/agents/statuses/2448575b85f1945b6793564cff2583793a74ffdf"}}}}
{"actor":{"display_login":"bhtucker"}}