Instruction:
How would you code a function in Python 3 to
submit this item to the gallery.

Response:
def submit_to_gallery(self, title, bypass_terms=False):
        """
        Add this to the gallery.

        Require that the authenticated user has accepted gallery terms and
        verified their email.

        :param title: The title of the new gallery item.
        :param bypass_terms: If the user has not accepted Imgur's terms yet,
            this method will return an error. Set this to True to by-pass the
            terms.
        """
        url = self._imgur._base_url + "/3/gallery/{0}".format(self.id)
        payload = {'title': title, 'terms': '1' if bypass_terms else '0'}
        self._imgur._send_request(url, needs_auth=True, params=payload,
                                  method='POST')
        item = self._imgur.get_gallery_album(self.id)
        _change_object(self, item)
        return self


Instruction:
Can you tell what is the following Python 3 function doing
def update(self, title=None, description=None, images=None, cover=None,
               layout=None, privacy=None):
        """
        Update the album's information.

        Arguments with the value None will retain their old values.

        :param title: The title of the album.
        :param description: A description of the album.
        :param images: A list of the images we want the album to contain.
            Can be Image objects, ids or a combination of the two. Images that
            images that you cannot set (non-existing or not owned by you) will
            not cause exceptions, but fail silently.
        :param privacy: The albums privacy level, can be public, hidden or
            secret.
        :param cover: The id of the cover image.
        :param layout: The way the album is displayed, can be blog, grid,
            horizontal or vertical.
        """
        url = (self._imgur._base_url + "/3/album/"
               "{0}".format(self._delete_or_id_hash))
        is_updated = self._imgur._send_request(url, params=locals(),
                                               method='POST')
        if is_updated:
            self.title = title or self.title
            self.description = description or self.description
            self.layout = layout or self.layout
            self.privacy = privacy or self.privacy
            if cover is not None:
                self.cover = (cover if isinstance(cover, Image)
                              else Image({'id': cover}, self._imgur,
                                         has_fetched=False))
            if images:
                self.images = [img if isinstance(img, Image) else
                               Image({'id': img}, self._imgur, False)
                               for img in images]
        return is_updated

Response: Update the album s information.


Instruction:
Can you generate the documentation for the following Python 3 function
def get_replies(self):
        url = self._imgur._base_url + "/3/comment/{0}/replies".format(self.id)
        json = self._imgur._send_request(url)
        child_comments = json['children']
        return [Comment(com, self._imgur) for com in child_comments]

Response: Get the replies to this comment.


Instruction:
Can you implement a function in Python 3 that
makes a top - level comment to this.

Response:
def comment(self, text):
        """
        Make a top-level comment to this.

        :param text: The comment text.
        """
        url = self._imgur._base_url + "/3/comment"
        payload = {'image_id': self.id, 'comment': text}
        resp = self._imgur._send_request(url, params=payload, needs_auth=True,
                                         method='POST')
        return Comment(resp, imgur=self._imgur, has_fetched=False)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def downvote(self):
        url = self._imgur._base_url + "/3/gallery/{0}/vote/down".format(self.id)
        return self._imgur._send_request(url, needs_auth=True, method='POST')

Response: Downvote the item with the highest priority.


Instruction:
Write a Python 3 function that can
get a list of the top - level comments.

Response:
def get_comments(self):
        """Get a list of the top-level comments."""
        url = self._imgur._base_url + "/3/gallery/{0}/comments".format(self.id)
        resp = self._imgur._send_request(url)
        return [Comment(com, self._imgur) for com in resp]


Instruction:
Implement a Python 3 function for
removing this image from the gallery.

Response:
def remove_from_gallery(self):
        """Remove this image from the gallery."""
        url = self._imgur._base_url + "/3/gallery/{0}".format(self.id)
        self._imgur._send_request(url, needs_auth=True, method='DELETE')
        if isinstance(self, Image):
            item = self._imgur.get_image(self.id)
        else:
            item = self._imgur.get_album(self.id)
        _change_object(self, item)
        return self


Instruction:
Can you tell what is the following Python 3 function doing
def download(self, path='', name=None, overwrite=False, size=None):
        def save_as(filename):
            local_path = os.path.join(path, filename)
            if os.path.exists(local_path) and not overwrite:
                raise Exception("Trying to save as {0}, but file "
                                "already exists.".format(local_path))
            with open(local_path, 'wb') as out_file:
                out_file.write(resp.content)
            return local_path
        valid_sizes = {'small_square': 's', 'big_square': 'b',
                       'small_thumbnail': 't', 'medium_thumbnail': 'm',
                       'large_thumbnail': 'l', 'huge_thumbnail': 'h'}
        if size is not None:
            size = size.lower().replace(' ', '_')
            if size not in valid_sizes:
                raise LookupError('Invalid size. Valid options are: {0}'.format(
                                  ", " .join(valid_sizes.keys())))
        suffix = valid_sizes.get(size, '')
        base, sep, ext = self.link.rpartition('.')
        resp = requests.get(base + suffix + sep + ext)
        if name or self.title:
            try:
                return save_as((name or self.title) + suffix + sep + ext)
            except IOError:
                pass
            # Invalid filename
        return save_as(self.id + suffix + sep + ext)

Response:
Download the image.

        :param path: The image will be downloaded to the folder specified at
            path, if path is None (default) then the current working directory
            will be used.
        :param name: The name the image will be stored as (not including file
            extension). If name is None, then the title of the image will be
            used. If the image doesn't have a title, it's id will be used. Note
            that if the name given by name or title is an invalid filename,
            then the hash will be used as the name instead.
        :param overwrite: If True overwrite already existing file with the same
            name as what we want to save the file as.
        :param size: Instead of downloading the image in it's original size, we
            can choose to instead download a thumbnail of it. Options are
            'small_square', 'big_square', 'small_thumbnail',
            'medium_thumbnail', 'large_thumbnail' or 'huge_thumbnail'.

        :returns: Name of the new file.


Instruction:
How would you code a function in Python 3 to
update the image with a new title and or description.

Response:
def update(self, title=None, description=None):
        """Update the image with a new title and/or description."""
        url = (self._imgur._base_url + "/3/image/"
               "{0}".format(self._delete_or_id_hash))
        is_updated = self._imgur._send_request(url, params=locals(),
                                               method='POST')
        if is_updated:
            self.title = title or self.title
            self.description = description or self.description
        return is_updated


Instruction:
Here you have a function in Python 3, explain what it does
def _send_request(self, url, needs_auth=False, **kwargs):
        # TODO: Add automatic test for timed_out access_tokens and
        # automatically refresh it before carrying out the request.
        if self.access_token is None and needs_auth:
            # TODO: Use inspect to insert name of method in error msg.
            raise Exception("Authentication as a user is required to use this "
                            "method.")
        if self.access_token is None:
            # Not authenticated as a user. Use anonymous access.
            auth = {'Authorization': 'Client-ID {0}'.format(self.client_id)}
        else:
            auth = {'Authorization': 'Bearer {0}'.format(self.access_token)}
        if self.mashape_key:
            auth.update({'X-Mashape-Key': self.mashape_key})
        content = []
        is_paginated = False
        if 'limit' in kwargs:
            is_paginated = True
            limit = kwargs['limit'] or self.DEFAULT_LIMIT
            del kwargs['limit']
            page = 0
            base_url = url
            url.format(page)
        kwargs['authentication'] = auth
        while True:
            result = request.send_request(url, verify=self.verify, **kwargs)
            new_content, ratelimit_info = result
            if is_paginated and new_content and limit > len(new_content):
                content += new_content
                page += 1
                url = base_url.format(page)
            else:
                if is_paginated:
                    content = (content + new_content)[:limit]
                else:
                    content = new_content
                break
        # Note: When the cache is implemented, it's important that the
        # ratelimit info doesn't get updated with the ratelimit info in the
        # cache since that's likely incorrect.
        for key, value in ratelimit_info.items():
            setattr(self, key[2:].replace('-', '_'), value)
        return content

Response: Send a request to the Imgur API.


Instruction:
Can you write a function in Python 3 where it
returns the authorization url that s needed to authorize as a user.

Response:
def authorization_url(self, response, state=""):
        """
        Return the authorization url that's needed to authorize as a user.

        :param response: Can be either code or pin. If it's code the user will
            be redirected to your redirect url with the code as a get parameter
            after authorizing your application. If it's pin then after
            authorizing your application, the user will instead be shown a pin
            on Imgurs website. Both code and pin are used to get an
            access_token and refresh token with the exchange_code and
            exchange_pin functions respectively.
        :param state: This optional parameter indicates any state which may be
            useful to your application upon receipt of the response. Imgur
            round-trips this parameter, so your application receives the same
            value it sent. Possible uses include redirecting the user to the
            correct resource in your site, nonces, and
            cross-site-request-forgery mitigations.
        """
        return AUTHORIZE_URL.format(self._base_url, self.client_id, response, state)


Instruction:
Write a Python 3 script to
change the current authentication.

Response:
def change_authentication(self, client_id=None, client_secret=None,
                              access_token=None, refresh_token=None):
        """Change the current authentication."""
        # TODO: Add error checking so you cannot change client_id and retain
        # access_token. Because that doesn't make sense.
        self.client_id = client_id or self.client_id
        self.client_secret = client_secret or self.client_secret
        self.access_token = access_token or self.access_token
        self.refresh_token = refresh_token or self.refresh_token


Instruction:
Make a summary of the following Python 3 code
def create_album(self, title=None, description=None, images=None,
                     cover=None):
        """
        Create a new Album.

        :param title: The title of the album.
        :param description: The albums description.
        :param images: A list of the images that will be added to the album
            after it's created.  Can be Image objects, ids or a combination of
            the two.  Images that you cannot add (non-existing or not owned by
            you) will not cause exceptions, but fail silently.
        :param cover: The id of the image you want as the albums cover image.

        :returns: The newly created album.
        """
        url = self._base_url + "/3/album/"
        payload = {'ids': images, 'title': title,
                   'description': description, 'cover': cover}
        resp = self._send_request(url, params=payload, method='POST')
        return Album(resp, self, has_fetched=False)

Response: Create a new Album.


Instruction:
Implement a Python 3 function for
exchanging one - use code for an access_token and request_token.

Response:
def exchange_code(self, code):
        """Exchange one-use code for an access_token and request_token."""
        params = {'client_id': self.client_id,
                  'client_secret': self.client_secret,
                  'grant_type': 'authorization_code',
                  'code': code}
        result = self._send_request(EXCHANGE_URL.format(self._base_url),
                                    params=params, method='POST',
                                    data_field=None)
        self.access_token = result['access_token']
        self.refresh_token = result['refresh_token']
        return self.access_token, self.refresh_token


Instruction:
Given the following Python 3 function, write the documentation
def exchange_pin(self, pin):
        params = {'client_id': self.client_id,
                  'client_secret': self.client_secret,
                  'grant_type': 'pin',
                  'pin': pin}
        result = self._send_request(EXCHANGE_URL.format(self._base_url),
                                    params=params, method='POST',
                                    data_field=None)
        self.access_token = result['access_token']
        self.refresh_token = result['refresh_token']
        return self.access_token, self.refresh_token

Response: Exchange one - use pin for an access_token and request_token.


Instruction:
Given the following Python 3 function, write the documentation
def get_album(self, id):
        url = self._base_url + "/3/album/{0}".format(id)
        json = self._send_request(url)
        return Album(json, self)

Response: Return information about this album.


Instruction:
Here you have a function in Python 3, explain what it does
def get_at_url(self, url):
        class NullDevice():
            def write(self, string):
                pass

        def get_gallery_item(id):
            """
            Special helper method to get gallery items.

            The problem is that it's impossible to distinguish albums and
            images from each other based on the url. And there isn't a common
            url endpoints that return either a Gallery_album or a Gallery_image
            depending on what the id represents. So the only option is to
            assume it's a Gallery_image and if we get an exception then try
            Gallery_album.  Gallery_image is attempted first because there is
            the most of them.
            """
            try:
                # HACK: Problem is that send_request prints the error message
                # from Imgur when it encounters an error. This is nice because
                # this error message is more descriptive than just the status
                # code that Requests give. But since we first assume the id
                # belong to an image, it means we will get an error whenever
                # the id belongs to an album. The following code temporarily
                # disables stdout to avoid give a cryptic and incorrect error.

                # Code for disabling stdout is from
                # http://coreygoldberg.blogspot.dk/2009/05/
                # python-redirect-or-turn-off-stdout-and.html
                original_stdout = sys.stdout  # keep a reference to STDOUT
                sys.stdout = NullDevice()  # redirect the real STDOUT
                return self.get_gallery_image(id)
            # TODO: Add better error codes so I don't have to do a catch-all
            except Exception:
                return self.get_gallery_album(id)
            finally:
                sys.stdout = original_stdout  # turn STDOUT back on

        if not self.is_imgur_url(url):
            return None

        objects = {'album': {'regex': "a/(?P<id>[\w.]*?)$",
                             'method': self.get_album},
                   'comment': {'regex': "gallery/\w*/comment/(?P<id>[\w.]*?)$",
                               'method': self.get_comment},
                   'gallery': {'regex': "(gallery|r/\w*?)/(?P<id>[\w.]*?)$",
                               'method': get_gallery_item},
                   # Valid image extensions: http://imgur.com/faq#types
                   # All are between 3 and 4 chars long.
                   'image': {'regex': "(?P<id>[\w.]*?)(\\.\w{3,4})?$",
                             'method': self.get_image},
                   'user': {'regex': "user/(?P<id>[\w.]*?)$",
                            'method': self.get_user}
                   }
        parsed_url = urlparse(url)
        for obj_type, values in objects.items():
            regex_result = re.match('/' + values['regex'], parsed_url.path)
            if regex_result is not None:
                obj_id = regex_result.group('id')
                initial_object = values['method'](obj_id)
                if obj_type == 'image':
                    try:
                        # A better version might be to ping the url where the
                        # gallery_image should be with a requests.head call. If
                        # we get a 200 returned, then that means it exists and
                        # this becomes less hacky.
                        original_stdout = sys.stdout
                        sys.stdout = NullDevice()
                        if getattr(initial_object, 'section', None):
                            sub = initial_object.section
                            return self.get_subreddit_image(sub, obj_id)
                        return self.get_gallery_image(obj_id)
                    except Exception:
                        pass
                    finally:
                        sys.stdout = original_stdout
                return initial_object

Response: Return a object representing the content at the given url.


Instruction:
Explain what the following Python 3 code does
def get_comment(self, id):
        url = self._base_url + "/3/comment/{0}".format(id)
        json = self._send_request(url)
        return Comment(json, self)

Response: Return information about this comment.


Instruction:
Implement a Python 3 function for
getting a list of albums and gallery images.

Response:
def get_gallery(self, section='hot', sort='viral', window='day',
                    show_viral=True, limit=None):
        """
        Return a list of gallery albums and gallery images.

        :param section: hot | top | user - defaults to hot.
        :param sort: viral | time - defaults to viral.
        :param window: Change the date range of the request if the section is
            "top", day | week | month | year | all, defaults to day.
        :param show_viral: true | false - Show or hide viral images from the
            'user' section. Defaults to true.
        :param limit: The number of items to return.
        """
        url = (self._base_url + "/3/gallery/{}/{}/{}/{}?showViral="
               "{}".format(section, sort, window, '{}', show_viral))
        resp = self._send_request(url, limit=limit)
        return [_get_album_or_image(thing, self) for thing in resp]


Instruction:
Given the following Python 3 function, write the documentation
def get_gallery_album(self, id):
        url = self._base_url + "/3/gallery/album/{0}".format(id)
        resp = self._send_request(url)
        return Gallery_album(resp, self)

Response: Get a gallery album by id


Instruction:
How would you explain what the following Python 3 function does
def get_gallery_image(self, id):
        url = self._base_url + "/3/gallery/image/{0}".format(id)
        resp = self._send_request(url)
        return Gallery_image(resp, self)

Response: Get a gallery image by id


Instruction:
Implement a Python 3 function for
returning a Image object representing the image with the given id.

Response:
def get_image(self, id):
        """Return a Image object representing the image with the given id."""
        url = self._base_url + "/3/image/{0}".format(id)
        resp = self._send_request(url)
        return Image(resp, self)


Instruction:
Write a Python 3 function for
getting a message object for given id.

Response:
def get_message(self, id):
        """
        Return a Message object for given id.

        :param id: The id of the message object to return.
        """
        url = self._base_url + "/3/message/{0}".format(id)
        resp = self._send_request(url)
        return Message(resp, self)


Instruction:
How would you explain what the following Python 3 function does
def get_notification(self, id):
        url = self._base_url + "/3/notification/{0}".format(id)
        resp = self._send_request(url)
        return Notification(resp, self)

Response: Get a specific notification object.


Instruction:
Explain what the following Python 3 code does
def get_memes_gallery(self, sort='viral', window='week', limit=None):
        url = (self._base_url + "/3/gallery/g/memes/{0}/{1}/{2}".format(
               sort, window, '{}'))
        resp = self._send_request(url, limit=limit)
        return [_get_album_or_image(thing, self) for thing in resp]

Response: Get a list of gallery albums or images submitted to the memes gallery


Instruction:
Can you tell what is the following Python 3 function doing
def get_subreddit_gallery(self, subreddit, sort='time', window='top',
                              limit=None):
        """
        Return a list of gallery albums/images submitted to a subreddit.

        A subreddit is a subsection of the website www.reddit.com, where users
        can, among other things, post images.

        :param subreddit: A valid subreddit name.
        :param sort: time | top - defaults to top.
        :param window: Change the date range of the request if the section is
            "top", day | week | month | year | all, defaults to day.
        :param limit: The number of items to return.
        """
        url = (self._base_url + "/3/gallery/r/{0}/{1}/{2}/{3}".format(
               subreddit, sort, window, '{}'))
        resp = self._send_request(url, limit=limit)
        return [_get_album_or_image(thing, self) for thing in resp]

Response: Return a list of gallery albums or images submitted to a subreddit.


Instruction:
Create a Python 3 function to
get the Gallery_image with the id submitted to subreddit gallery

Response:
def get_subreddit_image(self, subreddit, id):
        """
        Return the Gallery_image with the id submitted to subreddit gallery

        :param subreddit: The subreddit the image has been submitted to.
        :param id: The id of the image we want.
        """
        url = self._base_url + "/3/gallery/r/{0}/{1}".format(subreddit, id)
        resp = self._send_request(url)
        return Gallery_image(resp, self)


Instruction:
Make a summary of the following Python 3 code
def get_user(self, username):
        url = self._base_url + "/3/account/{0}".format(username)
        json = self._send_request(url)
        return User(json, self)

Response: Get a User object for this username.


Instruction:
Write a Python 3 function for
refreshing the access_token. The self.access_token attribute will be updated with the value of the new access_token which will also be returned.

Response:
def refresh_access_token(self):
        """
        Refresh the access_token.

        The self.access_token attribute will be updated with the value of the
        new access_token which will also be returned.
        """
        if self.client_secret is None:
            raise Exception("client_secret must be set to execute "
                            "refresh_access_token.")
        if self.refresh_token is None:
            raise Exception("refresh_token must be set to execute "
                            "refresh_access_token.")
        params = {'client_id': self.client_id,
                  'client_secret': self.client_secret,
                  'grant_type': 'refresh_token',
                  'refresh_token': self.refresh_token}
        result = self._send_request(REFRESH_URL.format(self._base_url),
                                    params=params, method='POST',
                                    data_field=None)
        self.access_token = result['access_token']
        return self.access_token


Instruction:
Given the following Python 3 function, write the documentation
def search_gallery(self, q):
        url = self._base_url + "/3/gallery/search?q={0}".format(q)
        resp = self._send_request(url)
        return [_get_album_or_image(thing, self) for thing in resp]

Response: Search the gallery with the given query string.


Instruction:
Implement a Python 3 function for
uploading an image at either path or url.

Response:
def upload_image(self, path=None, url=None, title=None, description=None,
                     album=None):
        """
        Upload the image at either path or url.

        :param path: The path to the image you want to upload.
        :param url: The url to the image you want to upload.
        :param title: The title the image will have when uploaded.
        :param description: The description the image will have when uploaded.
        :param album: The album the image will be added to when uploaded. Can
            be either a Album object or it's id. Leave at None to upload
            without adding to an Album, adding it later is possible.
            Authentication as album owner is necessary to upload to an album
            with this function.

        :returns: An Image object representing the uploaded image.
        """
        if bool(path) == bool(url):
            raise LookupError("Either path or url must be given.")
        if path:
            with open(path, 'rb') as image_file:
                binary_data = image_file.read()
                image = b64encode(binary_data)
        else:
            image = url

        payload = {'album_id': album, 'image': image,
                   'title': title, 'description': description}

        resp = self._send_request(self._base_url + "/3/image",
                                  params=payload, method='POST')
        # TEMPORARY HACK:
        # On 5-08-2013 I noticed Imgur now returned enough information from
        # this call to fully populate the Image object. However those variables
        # that matched arguments were always None, even if they had been given.
        # See https://groups.google.com/forum/#!topic/imgur/F3uVb55TMGo
        resp['title'] = title
        resp['description'] = description
        if album is not None:
            resp['album'] = (Album({'id': album}, self, False) if not
                             isinstance(album, Album) else album)
        return Image(resp, self)


Instruction:
Write a Python 3 function that can
return the message thread this Message is in.

Response:
def get_thread(self):
        """Return the message thread this Message is in."""
        url = (self._imgur._base_url + "/3/message/{0}/thread".format(
               self.first_message.id))
        resp = self._imgur._send_request(url)
        return [Message(msg, self._imgur) for msg in resp]


Instruction:
Create a Python 3 function for
replying to this message.

Response:
def reply(self, body):
        """
        Reply to this message.

        This is a convenience method calling User.send_message. See it for more
        information on usage. Note that both recipient and reply_to are given
        by using this convenience method.

        :param body: The body of the message.
        """
        return self.author.send_message(body=body, reply_to=self.id)


Instruction:
How would you implement a function in Python 3 that
updates the settings of the user.

Response:
def change_settings(self, bio=None, public_images=None,
                        messaging_enabled=None, album_privacy=None,
                        accepted_gallery_terms=None):
        """
        Update the settings for the user.

        :param bio: A basic description filled out by the user, is displayed in
            the gallery profile page.
        :param public_images: Set the default privacy setting of the users
            images. If True images are public, if False private.
        :param messaging_enabled: Set to True to enable messaging.
        :param album_privacy: The default privacy level of albums created by
            the user. Can be public, hidden or secret.
        :param accepted_gallery_terms: The user agreement to Imgur Gallery
            terms. Necessary before the user can submit to the gallery.
        """
        # NOTE: album_privacy should maybe be renamed to default_privacy
        # NOTE: public_images is a boolean, despite the documentation saying it
        # is a string.
        url = self._imgur._base_url + "/3/account/{0}/settings".format(self.name)
        resp = self._imgur._send_request(url, needs_auth=True, params=locals(),
                                         method='POST')
        return resp


Instruction:
Write a Python 3 script for
returning a list of the user s albums.

Response:
def get_albums(self, limit=None):
        """
        Return  a list of the user's albums.

        Secret and hidden albums are only returned if this is the logged-in
        user.
        """
        url = (self._imgur._base_url + "/3/account/{0}/albums/{1}".format(self.name,
                                                                       '{}'))
        resp = self._imgur._send_request(url, limit=limit)
        return [Album(alb, self._imgur, False) for alb in resp]


Instruction:
Can you tell what is the following Python 3 function doing
def get_favorites(self):
        url = self._imgur._base_url + "/3/account/{0}/favorites".format(self.name)
        resp = self._imgur._send_request(url, needs_auth=True)
        return [_get_album_or_image(thing, self._imgur) for thing in resp]

Response: Return the users favorited images.


Instruction:
Can you tell what is the following Python 3 function doing
def get_gallery_favorites(self):
        url = (self._imgur._base_url + "/3/account/{0}/gallery_favorites".format(
               self.name))
        resp = self._imgur._send_request(url)
        return [Image(img, self._imgur) for img in resp]

Response: Get a list of the images in the gallery this user has favorited.


Instruction:
Can you tell what is the following Python 3 function doing
def get_gallery_profile(self):
        url = (self._imgur._base_url + "/3/account/{0}/"
               "gallery_profile".format(self.name))
        return self._imgur._send_request(url)

Response: Return the users gallery profile.


Instruction:
Make a summary of the following Python 3 code
def has_verified_email(self):
        url = (self._imgur._base_url + "/3/account/{0}/"
               "verifyemail".format(self.name))
        return self._imgur._send_request(url, needs_auth=True)

Response: Returns True if the user has verified that the email he has given is legit?


Instruction:
How would you explain what the following Python 3 function does
def get_images(self, limit=None):
        url = (self._imgur._base_url + "/3/account/{0}/"
               "images/{1}".format(self.name, '{}'))
        resp = self._imgur._send_request(url, limit=limit)
        return [Image(img, self._imgur) for img in resp]

Response: Return all of the images associated with the user.


Instruction:
Write a Python 3 function that can
return all messages sent to this user formatted as a notification.

Response:
def get_messages(self, new=True):
        """
        Return all messages sent to this user, formatted as a notification.

        :param new: False for all notifications, True for only non-viewed
            notifications.
        """
        url = (self._imgur._base_url + "/3/account/{0}/notifications/"
               "messages".format(self.name))
        result = self._imgur._send_request(url, params=locals(),
                                           needs_auth=True)
        return [Notification(msg_dict, self._imgur, has_fetched=True) for
                msg_dict in result]


Instruction:
Create a Python 3 function to
return all the notifications for this user.

Response:
def get_notifications(self, new=True):
        """Return all the notifications for this user."""
        url = (self._imgur._base_url + "/3/account/{0}/"
               "notifications".format(self.name))
        resp = self._imgur._send_request(url, params=locals(), needs_auth=True)
        msgs = [Message(msg_dict, self._imgur, has_fetched=True) for msg_dict
                in resp['messages']]
        replies = [Comment(com_dict, self._imgur, has_fetched=True) for
                   com_dict in resp['replies']]
        return {'messages': msgs, 'replies': replies}


Instruction:
Can you tell what is the following Python 3 function doing
def get_replies(self, new=True):
        url = (self._imgur._base_url + "/3/account/{0}/"
               "notifications/replies".format(self.name))
        return self._imgur._send_request(url, needs_auth=True)

Response: Return all replies for this user.


Instruction:
Write a Python 3 script to
return current settings. Only accessible if authenticated as the user.

Response:
def get_settings(self):
        """
        Returns current settings.

        Only accessible if authenticated as the user.
        """
        url = self._imgur._base_url + "/3/account/{0}/settings".format(self.name)
        return self._imgur._send_request(url)


Instruction:
Write a Python 3 script to
return a list of the images a user has submitted to the gallery.

Response:
def get_submissions(self, limit=None):
        """Return a list of the images a user has submitted to the gallery."""
        url = (self._imgur._base_url + "/3/account/{0}/submissions/"
               "{1}".format(self.name, '{}'))
        resp = self._imgur._send_request(url, limit=limit)
        return [_get_album_or_image(thing, self._imgur) for thing in resp]


Instruction:
Implement a Python 3 function for
sending a message to this user from the logged in user.

Response:
def send_message(self, body, subject=None, reply_to=None):
        """
        Send a message to this user from the logged in user.

        :param body: The body of the message.
        :param subject: The subject of the message. Note that if the this
            message is a reply, then the subject of the first message will be
            used instead.
        :param reply_to: Messages can either be replies to other messages or
            start a new message thread. If this is None it will start a new
            message thread. If it's a Message object or message_id, then the
            new message will be sent as a reply to the reply_to message.
        """
        url = self._imgur._base_url + "/3/message"
        parent_id = reply_to.id if isinstance(reply_to, Message) else reply_to
        payload = {'recipient': self.name, 'body': body, 'subject': subject,
                   'parent_id': parent_id}
        self._imgur._send_request(url, params=payload, needs_auth=True,
                                  method='POST')


Instruction:
Can you generate the documentation for the following Python 3 function
def send_verification_email(self):
        url = (self._imgur._base_url + "/3/account/{0}"
               "/verifyemail".format(self.name))
        self._imgur._send_request(url, needs_auth=True, method='POST')

Response: Send verification email to this users email address.


Instruction:
Write a Python 3 script to
hook the current excepthook to the backtrace.

Response:
def hook(reverse=False,
         align=False,
         strip_path=False,
         enable_on_envvar_only=False,
         on_tty=False,
         conservative=False,
         styles=None,
         tb=None,
         tpe=None,
         value=None):
    """Hook the current excepthook to the backtrace.

    If `align` is True, all parts (line numbers, file names, etc..) will be
    aligned to the left according to the longest entry.

    If `strip_path` is True, only the file name will be shown, not its full
    path.

    If `enable_on_envvar_only` is True, only if the environment variable
    `ENABLE_BACKTRACE` is set, backtrace will be activated.

    If `on_tty` is True, backtrace will be activated only if you're running
    in a readl terminal (i.e. not piped, redirected, etc..).

    If `convervative` is True, the traceback will have more seemingly original
    style (There will be no alignment by default, 'File', 'line' and 'in'
    prefixes and will ignore any styling provided by the user.)

    See https://github.com/nir0s/backtrace/blob/master/README.md for
    information on `styles`.
    """
    if enable_on_envvar_only and 'ENABLE_BACKTRACE' not in os.environ:
        return

    isatty = getattr(sys.stderr, 'isatty', lambda: False)
    if on_tty and not isatty():
        return

    if conservative:
        styles = CONVERVATIVE_STYLES
        align = align or False
    elif styles:
        for k in STYLES.keys():
            styles[k] = styles.get(k, STYLES[k])
    else:
        styles = STYLES

    # For Windows
    colorama.init()

    def backtrace_excepthook(tpe, value, tb=None):
        # Don't know if we're getting traceback or traceback entries.
        # We'll try to parse a traceback object.
        try:
            traceback_entries = traceback.extract_tb(tb)
        except AttributeError:
            traceback_entries = tb
        parser = _Hook(traceback_entries, align, strip_path, conservative)

        tpe = tpe if isinstance(tpe, str) else tpe.__name__
        tb_message = styles['backtrace'].format('Traceback ({0}):'.format(
            'Most recent call ' + ('first' if reverse else 'last'))) + \
            Style.RESET_ALL
        err_message = styles['error'].format(tpe + ': ' + str(value)) + \
            Style.RESET_ALL

        if reverse:
            parser.reverse()

        _flush(tb_message)
        backtrace = parser.generate_backtrace(styles)
        backtrace.insert(0 if reverse else len(backtrace), err_message)
        for entry in backtrace:
            _flush(entry)

    if tb:
        backtrace_excepthook(tpe=tpe, value=value, tb=tb)
    else:
        sys.excepthook = backtrace_excepthook


Instruction:
How would you implement a function in Python 3 that
extracts a traceback from the input text.

Response:
def _extract_traceback(text):
    """Receive a list of strings representing the input from stdin and return
    the restructured backtrace.

    This iterates over the output and once it identifies a hopefully genuine
    identifier, it will start parsing output.
    In the case the input includes a reraise (a Python 3 case), the primary
    traceback isn't handled, only the reraise.

    Each of the traceback lines are then handled two lines at a time for each
    stack object.

    Note that all parts of each stack object are stripped from newlines and
    spaces to keep the output clean.
    """
    capture = False
    entries = []
    all_else = []
    ignore_trace = False

    # In python 3, a traceback may includes output from a reraise.
    # e.g, an exception is captured and reraised with another exception.
    # This marks that we should ignore
    if text.count(TRACEBACK_IDENTIFIER) == 2:
        ignore_trace = True

    for index, line in enumerate(text):
        if TRACEBACK_IDENTIFIER in line:
            if ignore_trace:
                ignore_trace = False
                continue
            capture = True
        # We're not capturing and making sure we only read lines
        # with spaces since, after the initial identifier, all traceback lines
        # contain a prefix spacing.
        elif capture and line.startswith(' '):
            if index % 2 == 0:
                # Line containing a file, line and module.
                line = line.strip().strip('\n')
                next_line = text[index + 1].strip('\n')
                entries.append(line + ', ' + next_line)
        elif capture:
            # Line containing the module call.
            entries.append(line)
            break
        else:
            # Add everything else after the traceback.
            all_else.append(line)

    traceback_entries = []

    # Build the traceback structure later passed for formatting.
    for index, line in enumerate(entries[:-2]):
        # TODO: This should be done in a _parse_entry function
        element = line.split(',')
        element[0] = element[0].strip().lstrip('File').strip(' "')
        element[1] = element[1].strip().lstrip('line').strip()
        element[2] = element[2].strip().lstrip('in').strip()
        traceback_entries.append(tuple(element))
    return traceback_entries, all_else


Instruction:
Can you tell what is the following Python 3 function doing
def generate_backtrace(self, styles):
        backtrace = []
        for entry in self.entries:
            backtrace.append(self.rebuild_entry(entry, styles))

        # Get the lenght of the longest string for each field of an entry
        lengths = self.align_all(backtrace) if self.align else [1, 1, 1, 1]

        aligned_backtrace = []
        for entry in backtrace:
            aligned_backtrace.append(self.align_entry(entry, lengths))
        return aligned_backtrace

Response: Return the potentially aligned traceback for the current set of entries.


Instruction:
Write a Python 3 script for
classifying a list of sources and splits them according to their class.

Response:
def classify_catalog(catalog):
    """
    Look at a list of sources and split them according to their class.

    Parameters
    ----------
    catalog : iterable
        A list or iterable object of {SimpleSource, IslandSource, OutputSource} objects, possibly mixed.
        Any other objects will be silently ignored.

    Returns
    -------
    components : list
        List of sources of type OutputSource

    islands : list
        List of sources of type IslandSource

    simples : list
        List of source of type SimpleSource
    """
    components = []
    islands = []
    simples = []
    for source in catalog:
        if isinstance(source, OutputSource):
            components.append(source)
        elif isinstance(source, IslandSource):
            islands.append(source)
        elif isinstance(source, SimpleSource):
            simples.append(source)
    return components, islands, simples


Instruction:
Here you have a function in Python 3, explain what it does
def island_itergen(catalog):
    # reverse sort so that we can pop the last elements and get an increasing island number
    catalog = sorted(catalog)
    catalog.reverse()
    group = []

    # using pop and keeping track of the list length ourselves is faster than
    # constantly asking for len(catalog)
    src = catalog.pop()
    c_len = len(catalog)
    isle_num = src.island
    while c_len >= 0:
        if src.island == isle_num:
            group.append(src)
            c_len -= 1
            if c_len <0:
                # we have just added the last item from the catalog
                # and there are no more to pop
                yield group
            else:
                src = catalog.pop()
        else:
            isle_num += 1
            # maybe there are no sources in this island so skip it
            if group == []:
                continue
            yield group
            group = []
    return

Response: Iterate over a catalog of sources and return an island worth of sources at a time.


Instruction:
Can you write a function in Python 3 where it
sanitizes the attributes of the object so that they can print properly.

Response:
def _sanitise(self):
        """
        Convert attributes of type npumpy.float32 to numpy.float64 so that they will print properly.
        """
        for k in self.__dict__:
            if isinstance(self.__dict__[k], np.float32):  # np.float32 has a broken __str__ method
                self.__dict__[k] = np.float64(self.__dict__[k])


Instruction:
Write a Python 3 function for
returning an ordered list of the source attributes

Response:
def as_list(self):
        """
        Return an *ordered* list of the source attributes
        """
        self._sanitise()
        l = []
        for name in self.names:
            l.append(getattr(self, name))
        return l


Instruction:
Write a Python 3 function for
adding one or more circles to this region.

Response:
def add_circles(self, ra_cen, dec_cen, radius, depth=None):
        """
        Add one or more circles to this region

        Parameters
        ----------
        ra_cen, dec_cen, radius : float or list
            The center and radius of the circle or circles to add to this region.

        depth : int
            The depth at which the given circles will be inserted.

        """
        if depth is None or depth > self.maxdepth:
            depth = self.maxdepth
        try:
            sky = list(zip(ra_cen, dec_cen))
            rad = radius
        except TypeError:
            sky = [[ra_cen, dec_cen]]
            rad = [radius]
        sky = np.array(sky)
        rad = np.array(rad)
        vectors = self.sky2vec(sky)
        for vec, r in zip(vectors, rad):
            pix = hp.query_disc(2**depth, vec, r, inclusive=True, nest=True)
            self.add_pixels(pix, depth)
        self._renorm()
        return


Instruction:
Given the following Python 3 function, write the documentation
def add_poly(self, positions, depth=None):
        if not (len(positions) >= 3): raise AssertionError("A minimum of three coordinate pairs are required")

        if depth is None or depth > self.maxdepth:
            depth = self.maxdepth

        ras, decs = np.array(list(zip(*positions)))
        sky = self.radec2sky(ras, decs)
        pix = hp.query_polygon(2**depth, self.sky2vec(sky), inclusive=True, nest=True)
        self.add_pixels(pix, depth)
        self._renorm()
        return

Response: Adds a single polygon to this region.


Instruction:
Write a Python 3 function that can
add one or more HEALPix pixels to this region.

Response:
def add_pixels(self, pix, depth):
        """
        Add one or more HEALPix pixels to this region.

        Parameters
        ----------
        pix : int or iterable
            The pixels to be added

        depth : int
            The depth at which the pixels are added.
        """
        if depth not in self.pixeldict:
            self.pixeldict[depth] = set()
        self.pixeldict[depth].update(set(pix))


Instruction:
Can you create a Python 3 function that
calculates the total area of the region.

Response:
def get_area(self, degrees=True):
        """
        Calculate the total area represented by this region.

        Parameters
        ----------
        degrees : bool
            If True then return the area in square degrees, otherwise use steradians.
            Default = True.

        Returns
        -------
        area : float
            The area of the region.
        """
        area = 0
        for d in range(1, self.maxdepth+1):
            area += len(self.pixeldict[d])*hp.nside2pixarea(2**d, degrees=degrees)
        return area


Instruction:
Given the following Python 3 function, write the documentation
def _demote_all(self):
        # only do the calculations if the demoted list is empty
        if len(self.demoted) == 0:
            pd = self.pixeldict
            for d in range(1, self.maxdepth):
                for p in pd[d]:
                    pd[d+1].update(set((4*p, 4*p+1, 4*p+2, 4*p+3)))
                pd[d] = set()  # clear the pixels from this level
            self.demoted = pd[d+1]
        return

Response: Convert the multi - depth pixeldict into a single set of pixels at the deepest layer.


Instruction:
Implement a Python 3 function for
remaking the pixel dictionary, merging groups of pixels at level N into a single pixel at level N-1

Response:
def _renorm(self):
        """
        Remake the pixel dictionary, merging groups of pixels at level N into a single pixel
        at level N-1
        """
        self.demoted = set()
        # convert all to lowest level
        self._demote_all()
        # now promote as needed
        for d in range(self.maxdepth, 2, -1):
            plist = self.pixeldict[d].copy()
            for p in plist:
                if p % 4 == 0:
                    nset = set((p, p+1, p+2, p+3))
                    if p+1 in plist and p+2 in plist and p+3 in plist:
                        # remove the four pixels from this level
                        self.pixeldict[d].difference_update(nset)
                        # add a new pixel to the next level up
                        self.pixeldict[d-1].add(p/4)
        self.demoted = set()
        return


Instruction:
Can you tell what is the following Python 3 function doing
def sky_within(self, ra, dec, degin=False):
        sky = self.radec2sky(ra, dec)

        if degin:
            sky = np.radians(sky)

        theta_phi = self.sky2ang(sky)
        # Set values that are nan to be zero and record a mask
        mask = np.bitwise_not(np.logical_and.reduce(np.isfinite(theta_phi), axis=1))
        theta_phi[mask, :] = 0

        theta, phi = theta_phi.transpose()
        pix = hp.ang2pix(2**self.maxdepth, theta, phi, nest=True)
        pixelset = self.get_demoted()
        result = np.in1d(pix, list(pixelset))
        # apply the mask and set the shonky values to False
        result[mask] = False
        return result

Response: Test whether a given sky position is within this region.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def union(self, other, renorm=True):
        # merge the pixels that are common to both
        for d in range(1, min(self.maxdepth, other.maxdepth)+1):
            self.add_pixels(other.pixeldict[d], d)

        # if the other region is at higher resolution, then include a degraded version of the remaining pixels.
        if self.maxdepth < other.maxdepth:
            for d in range(self.maxdepth+1, other.maxdepth+1):
                for p in other.pixeldict[d]:
                    # promote this pixel to self.maxdepth
                    pp = p/4**(d-self.maxdepth)
                    self.pixeldict[self.maxdepth].add(pp)
        if renorm:
            self._renorm()
        return

Response: Add another Region by performing union on their pixlists.


Instruction:
Can you tell what is the following Python 3 function doing
def without(self, other):
        # work only on the lowest level
        # TODO: Allow this to be done for regions with different depths.
        if not (self.maxdepth == other.maxdepth): raise AssertionError("Regions must have the same maxdepth")
        self._demote_all()
        opd = set(other.get_demoted())
        self.pixeldict[self.maxdepth].difference_update(opd)
        self._renorm()
        return

Response: Subtract another Region from this one by performing a difference operation on their pixlists.


Instruction:
Given the following Python 3 function, write the documentation
def intersect(self, other):
        # work only on the lowest level
        # TODO: Allow this to be done for regions with different depths.
        if not (self.maxdepth == other.maxdepth): raise AssertionError("Regions must have the same maxdepth")
        self._demote_all()
        opd = set(other.get_demoted())
        self.pixeldict[self.maxdepth].intersection_update(opd)
        self._renorm()
        return

Response: Combine with another Region by performing intersection on their pixlists.


Instruction:
How would you explain what the following Python 3 function does
def symmetric_difference(self, other):
        # work only on the lowest level
        # TODO: Allow this to be done for regions with different depths.
        if not (self.maxdepth == other.maxdepth): raise AssertionError("Regions must have the same maxdepth")
        self._demote_all()
        opd = set(other.get_demoted())
        self.pixeldict[self.maxdepth].symmetric_difference_update(opd)
        self._renorm()
        return

Response: Combine with another Region by performing the symmetric difference of their pixlists.


Instruction:
Write a Python 3 script for
writing a ds9 region file that represents this region as a set of diamonds.

Response:
def write_reg(self, filename):
        """
        Write a ds9 region file that represents this region as a set of diamonds.

        Parameters
        ----------
        filename : str
            File to write
        """
        with open(filename, 'w') as out:
            for d in range(1, self.maxdepth+1):
                for p in self.pixeldict[d]:
                    line = "fk5; polygon("
                    # the following int() gets around some problems with np.int64 that exist prior to numpy v 1.8.1
                    vectors = list(zip(*hp.boundaries(2**d, int(p), step=1, nest=True)))
                    positions = []
                    for sky in self.vec2sky(np.array(vectors), degrees=True):
                        ra, dec = sky
                        pos = SkyCoord(ra/15, dec, unit=(u.degree, u.degree))
                        positions.append(pos.ra.to_string(sep=':', precision=2))
                        positions.append(pos.dec.to_string(sep=':', precision=2))
                    line += ','.join(positions)
                    line += ")"
                    print(line, file=out)
        return


Instruction:
How would you explain what the following Python 3 function does
def write_fits(self, filename, moctool=''):
        datafile = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data', 'MOC.fits')
        hdulist = fits.open(datafile)
        cols = fits.Column(name='NPIX', array=self._uniq(), format='1K')
        tbhdu = fits.BinTableHDU.from_columns([cols])
        hdulist[1] = tbhdu
        hdulist[1].header['PIXTYPE'] = ('HEALPIX ', 'HEALPix magic code')
        hdulist[1].header['ORDERING'] = ('NUNIQ ', 'NUNIQ coding method')
        hdulist[1].header['COORDSYS'] = ('C ', 'ICRS reference frame')
        hdulist[1].header['MOCORDER'] = (self.maxdepth, 'MOC resolution (best order)')
        hdulist[1].header['MOCTOOL'] = (moctool, 'Name of the MOC generator')
        hdulist[1].header['MOCTYPE'] = ('CATALOG', 'Source type (IMAGE or CATALOG)')
        hdulist[1].header['MOCID'] = (' ', 'Identifier of the collection')
        hdulist[1].header['ORIGIN'] = (' ', 'MOC origin')
        time = datetime.datetime.utcnow()
        hdulist[1].header['DATE'] = (datetime.datetime.strftime(time, format="%Y-%m-%dT%H:%m:%SZ"), 'MOC creation date')
        hdulist.writeto(filename, overwrite=True)
        return

Response: Write a FITS file representing the MOC of this region to a file.


Instruction:
Implement a function in Python 3 to
create a list of all the pixels that cover this region.

Response:
def _uniq(self):
        """
        Create a list of all the pixels that cover this region.
        This list contains overlapping pixels of different orders.

        Returns
        -------
        pix : list
            A list of HEALPix pixel numbers.
        """
        pd = []
        for d in range(1, self.maxdepth):
            pd.extend(map(lambda x: int(4**(d+1) + x), self.pixeldict[d]))
        return sorted(pd)


Instruction:
Implement a function in Python 3 to
convert ra dec to sky coordinates.

Response:
def radec2sky(ra, dec):
        """
        Convert [ra], [dec] to [(ra[0], dec[0]),....]
        and also  ra,dec to [(ra,dec)] if ra/dec are not iterable

        Parameters
        ----------
        ra, dec : float or iterable
            Sky coordinates

        Returns
        -------
        sky : numpy.array
            array of (ra,dec) coordinates.
        """
        try:
            sky = np.array(list(zip(ra, dec)))
        except TypeError:
            sky = np.array([(ra, dec)])
        return sky


Instruction:
How would you explain what the following Python 3 function does
def sky2ang(sky):
        try:
            theta_phi = sky.copy()
        except AttributeError as _:
            theta_phi = np.array(sky)
        theta_phi[:, [1, 0]] = theta_phi[:, [0, 1]]
        theta_phi[:, 0] = np.pi/2 - theta_phi[:, 0]
        # # force 0<=theta<=2pi
        # theta_phi[:, 0] -= 2*np.pi*(theta_phi[:, 0]//(2*np.pi))
        # # and now -pi<=theta<=pi
        # theta_phi[:, 0] -= (theta_phi[:, 0] > np.pi)*2*np.pi
        return theta_phi

Response: Convert ra dec coordinates to theta and phi coordinates.


Instruction:
Explain what the following Python 3 code does
def sky2vec(cls, sky):
        theta_phi = cls.sky2ang(sky)
        theta, phi = map(np.array, list(zip(*theta_phi)))
        vec = hp.ang2vec(theta, phi)
        return vec

Response: Convert the sky positions in to 3d - vectors on the unit sphere.


Instruction:
Can you tell what is the following Python 3 function doing
def vec2sky(cls, vec, degrees=False):
        theta, phi = hp.vec2ang(vec)
        ra = phi
        dec = np.pi/2-theta

        if degrees:
            ra = np.degrees(ra)
            dec = np.degrees(dec)
        return cls.radec2sky(ra, dec)

Response: Convert vector into sky coordinates ra dec


Instruction:
Write a Python 3 function for
creating a new WCSHelper object from the given header.

Response:
def from_header(cls, header, beam=None, lat=None):
        """
        Create a new WCSHelper class from the given header.

        Parameters
        ----------
        header : `astropy.fits.HDUHeader` or string
            The header to be used to create the WCS helper

        beam : :class:`AegeanTools.fits_image.Beam` or None
            The synthesized beam. If the supplied beam is None then one is constructed form the header.

        lat : float
            The latitude of the telescope.

        Returns
        -------
        obj : :class:`AegeanTools.wcs_helpers.WCSHelper`
            A helper object.
        """
        try:
            wcs = pywcs.WCS(header, naxis=2)
        except:  # TODO: figure out what error is being thrown
            wcs = pywcs.WCS(str(header), naxis=2)

        if beam is None:
            beam = get_beam(header)
        else:
            beam = beam

        if beam is None:
            logging.critical("Cannot determine beam information")

        _, pixscale = get_pixinfo(header)
        refpix = (header['CRPIX1'], header['CRPIX2'])
        return cls(wcs, beam, pixscale, refpix, lat)


Instruction:
Make a summary of the following Python 3 code
def from_file(cls, filename, beam=None):
        header = fits.getheader(filename)
        return cls.from_header(header, beam)

Response: Create a new WCSHelper class from a given FITS file.


Instruction:
Can you implement a function in Python 3 that
converts pixel coordinates into sky coordinates.

Response:
def pix2sky(self, pixel):
        """
        Convert pixel coordinates into sky coordinates.

        Parameters
        ----------
        pixel : (float, float)
            The (x,y) pixel coordinates

        Returns
        -------
        sky : (float, float)
            The (ra,dec) sky coordinates in degrees

        """
        x, y = pixel
        # wcs and pyfits have oposite ideas of x/y
        return self.wcs.wcs_pix2world([[y, x]], 1)[0]


Instruction:
How would you code a function in Python 3 to
convert sky coordinates into pixel coordinates.

Response:
def sky2pix(self, pos):
        """
        Convert sky coordinates into pixel coordinates.

        Parameters
        ----------
        pos : (float, float)
            The (ra, dec) sky coordinates (degrees)

        Returns
        -------
        pixel : (float, float)
            The (x,y) pixel coordinates

        """
        pixel = self.wcs.wcs_world2pix([pos], 1)
        # wcs and pyfits have oposite ideas of x/y
        return [pixel[0][1], pixel[0][0]]


Instruction:
Explain what the following Python 3 code does
def sky2pix_vec(self, pos, r, pa):
        ra, dec = pos
        x, y = self.sky2pix(pos)
        a = translate(ra, dec, r, pa)
        locations = self.sky2pix(a)
        x_off, y_off = locations
        a = np.sqrt((x - x_off) ** 2 + (y - y_off) ** 2)
        theta = np.degrees(np.arctan2((y_off - y), (x_off - x)))
        return x, y, a, theta

Response: Convert a vector from sky to pixel coordinates.


Instruction:
Write a Python 3 script for
giving and input position and vector in pixel coordinates calculate the equivalent position and vector in sky coordinates.

Response:
def pix2sky_vec(self, pixel, r, theta):
        """
        Given and input position and vector in pixel coordinates, calculate
        the equivalent position and vector in sky coordinates.

        Parameters
        ----------
        pixel : (int,int)
            origin of vector in pixel coordinates
        r : float
            magnitude of vector in pixels
        theta : float
            angle of vector in degrees

        Returns
        -------
        ra, dec : float
            The (ra, dec) of the origin point (degrees).
        r, pa : float
            The magnitude and position angle of the vector (degrees).
        """
        ra1, dec1 = self.pix2sky(pixel)
        x, y = pixel
        a = [x + r * np.cos(np.radians(theta)),
             y + r * np.sin(np.radians(theta))]
        locations = self.pix2sky(a)
        ra2, dec2 = locations
        a = gcd(ra1, dec1, ra2, dec2)
        pa = bear(ra1, dec1, ra2, dec2)
        return ra1, dec1, a, pa


Instruction:
Can you create a Python 3 function that
converts an ellipse from sky to pixel coordinates.

Response:
def sky2pix_ellipse(self, pos, a, b, pa):
        """
        Convert an ellipse from sky to pixel coordinates.

        Parameters
        ----------
        pos : (float, float)
            The (ra, dec) of the ellipse center (degrees).
        a, b, pa: float
            The semi-major axis, semi-minor axis and position angle of the ellipse (degrees).

        Returns
        -------
        x,y : float
            The (x, y) pixel coordinates of the ellipse center.
        sx, sy : float
            The major and minor axes (FWHM) in pixels.
        theta : float
            The rotation angle of the ellipse (degrees).
            theta = 0 corresponds to the ellipse being aligned with the x-axis.

        """
        ra, dec = pos
        x, y = self.sky2pix(pos)

        x_off, y_off = self.sky2pix(translate(ra, dec, a, pa))
        sx = np.hypot((x - x_off), (y - y_off))
        theta = np.arctan2((y_off - y), (x_off - x))

        x_off, y_off = self.sky2pix(translate(ra, dec, b, pa - 90))
        sy = np.hypot((x - x_off), (y - y_off))
        theta2 = np.arctan2((y_off - y), (x_off - x)) - np.pi / 2

        # The a/b vectors are perpendicular in sky space, but not always in pixel space
        # so we have to account for this by calculating the angle between the two vectors
        # and modifying the minor axis length
        defect = theta - theta2
        sy *= abs(np.cos(defect))

        return x, y, sx, sy, np.degrees(theta)


Instruction:
Can you implement a function in Python 3 that
converts an ellipse from pixel to sky coordinates.

Response:
def pix2sky_ellipse(self, pixel, sx, sy, theta):
        """
        Convert an ellipse from pixel to sky coordinates.

        Parameters
        ----------
        pixel : (float, float)
            The (x, y) coordinates of the center of the ellipse.
        sx, sy : float
            The major and minor axes (FHWM) of the ellipse, in pixels.
        theta : float
            The rotation angle of the ellipse (degrees).
            theta = 0 corresponds to the ellipse being aligned with the x-axis.

        Returns
        -------
        ra, dec : float
            The (ra, dec) coordinates of the center of the ellipse (degrees).

        a, b : float
            The semi-major and semi-minor axis of the ellipse (degrees).

        pa : float
            The position angle of the ellipse (degrees).
        """
        ra, dec = self.pix2sky(pixel)
        x, y = pixel
        v_sx = [x + sx * np.cos(np.radians(theta)),
                y + sx * np.sin(np.radians(theta))]
        ra2, dec2 = self.pix2sky(v_sx)
        major = gcd(ra, dec, ra2, dec2)
        pa = bear(ra, dec, ra2, dec2)

        v_sy = [x + sy * np.cos(np.radians(theta - 90)),
                y + sy * np.sin(np.radians(theta - 90))]
        ra2, dec2 = self.pix2sky(v_sy)
        minor = gcd(ra, dec, ra2, dec2)
        pa2 = bear(ra, dec, ra2, dec2) - 90

        # The a/b vectors are perpendicular in sky space, but not always in pixel space
        # so we have to account for this by calculating the angle between the two vectors
        # and modifying the minor axis length
        defect = pa - pa2
        minor *= abs(np.cos(np.radians(defect)))
        return ra, dec, major, minor, pa


Instruction:
How would you implement a function in Python 3 that
returns the beam in pixels at the given location in pixel coordinates.

Response:
def get_pixbeam_pixel(self, x, y):
        """
        Determine the beam in pixels at the given location in pixel coordinates.

        Parameters
        ----------
        x , y : float
            The pixel coordinates at which the beam is determined.

        Returns
        -------
        beam : :class:`AegeanTools.fits_image.Beam`
            A beam object, with a/b/pa in pixel coordinates.
        """
        ra, dec = self.pix2sky((x, y))
        return self.get_pixbeam(ra, dec)


Instruction:
Create a Python 3 function for
returning the beam object at the given sky location.

Response:
def get_beam(self, ra, dec):
        """
        Determine the beam at the given sky location.

        Parameters
        ----------
        ra, dec : float
            The sky coordinates at which the beam is determined.

        Returns
        -------
        beam : :class:`AegeanTools.fits_image.Beam`
            A beam object, with a/b/pa in sky coordinates
        """
        # check to see if we need to scale the major axis based on the declination
        if self.lat is None:
            factor = 1
        else:
            # this works if the pa is zero. For non-zero pa it's a little more difficult
            factor = np.cos(np.radians(dec - self.lat))
        return Beam(self.beam.a / factor, self.beam.b, self.beam.pa)


Instruction:
Can you generate the documentation for the following Python 3 function
def get_pixbeam(self, ra, dec):

        if ra is None:
            ra, dec = self.pix2sky(self.refpix)
        pos = [ra, dec]

        beam = self.get_beam(ra, dec)
        _, _, major, minor, theta = self.sky2pix_ellipse(pos, beam.a, beam.b, beam.pa)

        if major < minor:
            major, minor = minor, major
            theta -= 90
            if theta < -180:
                theta += 180
        if not np.isfinite(theta):
            theta = 0
        if not all(np.isfinite([major, minor, theta])):
            beam = None
        else:
            beam = Beam(major, minor, theta)
        return beam

Response: Returns the beam in pixels at the given location in sky coordinates.


Instruction:
Implement a function in Python 3 to
calculate the area of the synthesized beam in square degrees.

Response:
def get_beamarea_deg2(self, ra, dec):
        """
        Calculate the area of the synthesized beam in square degrees.

        Parameters
        ----------
        ra, dec : float
            The sky coordinates at which the calculation is made.

        Returns
        -------
        area : float
            The beam area in square degrees.
        """
        barea = abs(self.beam.a * self.beam.b * np.pi)  # in deg**2 at reference coords
        if self.lat is not None:
            barea /= np.cos(np.radians(dec - self.lat))
        return barea


Instruction:
Implement a Python 3 function for
calculating the beam area in square pixels at the given sky coordinates.

Response:
def get_beamarea_pix(self, ra, dec):
        """
        Calculate the beam area in square pixels.

        Parameters
        ----------
        ra, dec : float
            The sky coordinates at which the calculation is made
        dec

        Returns
        -------
        area : float
            The beam area in square pixels.
        """
        parea = abs(self.pixscale[0] * self.pixscale[1])  # in deg**2 at reference coords
        barea = self.get_beamarea_deg2(ra, dec)
        return barea / parea


Instruction:
Can you write a function in Python 3 where it
calculates the GCD sky separation between two pixels.

Response:
def sky_sep(self, pix1, pix2):
        """
        calculate the GCD sky separation (degrees) between two pixels.

        Parameters
        ----------
        pix1, pix2 : (float, float)
            The (x,y) pixel coordinates for the two positions.

        Returns
        -------
        dist : float
            The distance between the two points (degrees).
        """
        pos1 = self.pix2sky(pix1)
        pos2 = self.pix2sky(pix2)
        sep = gcd(pos1[0], pos1[1], pos2[0], pos2[1])
        return sep


Instruction:
Make a summary of the following Python 3 code
def get_psf_sky(self, ra, dec):
        # If we don't have a psf map then we just fall back to using the beam
        # from the fits header (including ZA scaling)
        if self.data is None:
            beam = self.wcshelper.get_beam(ra, dec)
            return beam.a, beam.b, beam.pa

        x, y = self.sky2pix([ra, dec])
        # We leave the interpolation in the hands of whoever is making these images
        # clamping the x,y coords at the image boundaries just makes sense
        x = int(np.clip(x, 0, self.data.shape[1] - 1))
        y = int(np.clip(y, 0, self.data.shape[2] - 1))
        psf_sky = self.data[:, x, y]
        return psf_sky

Response: Determine the local psf at a given sky location.


Instruction:
Explain what the following Python 3 code does
def get_psf_pix(self, ra, dec):
        psf_sky = self.get_psf_sky(ra, dec)
        psf_pix = self.wcshelper.sky2pix_ellipse([ra, dec], psf_sky[0], psf_sky[1], psf_sky[2])[2:]
        return psf_pix

Response: Returns the local psf at a given sky location.


Instruction:
How would you explain what the following Python 3 function does
def get_pixbeam(self, ra, dec):
        # If there is no psf image then just use the fits header (plus lat scaling) from the wcshelper
        if self.data is None:
            return self.wcshelper.get_pixbeam(ra, dec)
        # get the beam from the psf image data
        psf = self.get_psf_pix(ra, dec)
        if not np.all(np.isfinite(psf)):
            log.warn("PSF requested, returned Null")
            return None
        return Beam(psf[0], psf[1], psf[2])

Response: Get the beam at the location specified in pixel coordinates.


Instruction:
Can you write a function in Python 3 where it
returns the beam at the given sky position.

Response:
def get_beam(self, ra, dec):
        """
        Get the psf as a :class:`AegeanTools.fits_image.Beam` object.

        Parameters
        ----------
        ra, dec : float
            The sky position (degrees).

        Returns
        -------
        beam : :class:`AegeanTools.fits_image.Beam`
            The psf at the given location.
        """
        if self.data is None:
            return self.wcshelper.beam
        else:
            psf = self.get_psf_sky(ra, dec)
            if not all(np.isfinite(psf)):
                return None
            return Beam(psf[0], psf[1], psf[2])


Instruction:
Can you write a function in Python 3 where it
calculates the area of the beam in square pixels.

Response:
def get_beamarea_pix(self, ra, dec):
        """
        Calculate the area of the beam in square pixels.

        Parameters
        ----------
        ra, dec : float
            The sky position (degrees).

        Returns
        -------
        area : float
            The area of the beam in square pixels.
        """
        beam = self.get_pixbeam(ra, dec)
        if beam is None:
            return 0
        return beam.a * beam.b * np.pi


Instruction:
How would you implement a function in Python 3 that
calculates the area of the beam in square degrees.

Response:
def get_beamarea_deg2(self, ra, dec):

        """
        Calculate the area of the beam in square degrees.

        Parameters
        ----------
        ra, dec : float
            The sky position (degrees).

        Returns
        -------
        area : float
            The area of the beam in square degrees.
        """
        beam = self.get_beam(ra, dec)
        if beam is None:
            return 0
        return beam.a * beam.b * np.pi


Instruction:
Can you generate the documentation for the following Python 3 function
def find_start_point(self):
        for i, row in enumerate(self.data):
            for j, _ in enumerate(row):
                if self.data[i, j] != 0:  # or not np.isfinite(self.data[i,j]):
                    return i, j

Response: Find the first location in our array that is not empty


Instruction:
Here you have a function in Python 3, explain what it does
def step(self, x, y):
        up_left = self.solid(x - 1, y - 1)
        up_right = self.solid(x, y - 1)
        down_left = self.solid(x - 1, y)
        down_right = self.solid(x, y)

        state = 0
        self.prev = self.next
        # which cells are filled?
        if up_left:
            state |= 1
        if up_right:
            state |= 2
        if down_left:
            state |= 4
        if down_right:
            state |= 8

        # what is the next step?
        if state in [1, 5, 13]:
            self.next = self.UP
        elif state in [2, 3, 7]:
            self.next = self.RIGHT
        elif state in [4, 12, 14]:
            self.next = self.LEFT
        elif state in [8, 10, 11]:
            self.next = self.DOWN
        elif state == 6:
            if self.prev == self.UP:
                self.next = self.LEFT
            else:
                self.next = self.RIGHT
        elif state == 9:
            if self.prev == self.RIGHT:
                self.next = self.UP
            else:
                self.next = self.DOWN
        else:
            self.next = self.NOWHERE
        return

Response: Move from the current location to the next location.


Instruction:
Implement a Python 3 function for
determining if the pixel x y is nonzero.

Response:
def solid(self, x, y):
        """
        Determine whether the pixel x,y is nonzero

        Parameters
        ----------
        x, y : int
            The pixel of interest.

        Returns
        -------
        solid : bool
            True if the pixel is not zero.
        """
        if not(0 <= x < self.xsize) or not(0 <= y < self.ysize):
            return False
        if self.data[x, y] == 0:
            return False
        return True


Instruction:
How would you explain what the following Python 3 function does
def walk_perimeter(self, startx, starty):
        # checks
        startx = max(startx, 0)
        startx = min(startx, self.xsize)
        starty = max(starty, 0)
        starty = min(starty, self.ysize)

        points = []

        x, y = startx, starty

        while True:
            self.step(x, y)
            if 0 <= x <= self.xsize and 0 <= y <= self.ysize:
                points.append((x, y))
            if self.next == self.UP:
                y -= 1
            elif self.next == self.LEFT:
                x -= 1
            elif self.next == self.DOWN:
                y += 1
            elif self.next == self.RIGHT:
                x += 1
            # stop if we meet some kind of error
            elif self.next == self.NOWHERE:
                break
            # stop when we return to the starting location
            if x == startx and y == starty:
                break
        return points

Response: Walk the perimeter of a region and return the path taken.


Instruction:
Create a Python 3 function for
marching about and trace the outline of our object

Response:
def do_march(self):
        """
        March about and trace the outline of our object

        Returns
        -------
        perimeter : list
            The pixels on the perimeter of the region [[x1, y1], ...]
        """
        x, y = self.find_start_point()
        perimeter = self.walk_perimeter(x, y)
        return perimeter


Instruction:
Implement a function in Python 3 to
blank all the pixels within the given perimeter.

Response:
def _blank_within(self, perimeter):
        """
        Blank all the pixels within the given perimeter.

        Parameters
        ----------
        perimeter : list
            The perimeter of the region.

        """
        # Method:
        # scan around the perimeter filling 'up' from each pixel
        # stopping when we reach the other boundary
        for p in perimeter:
            # if we are on the edge of the data then there is nothing to fill
            if p[0] >= self.data.shape[0] or p[1] >= self.data.shape[1]:
                continue
            # if this pixel is blank then don't fill
            if self.data[p] == 0:
                continue

            # blank this pixel
            self.data[p] = 0

            # blank until we reach the other perimeter
            for i in range(p[1]+1, self.data.shape[1]):
                q = p[0], i
                # stop when we reach another part of the perimeter
                if q in perimeter:
                    break
                # fill everything in between, even inclusions
                self.data[q] = 0

        return


Instruction:
Make a summary of the following Python 3 code
def elliptical_gaussian(x, y, amp, xo, yo, sx, sy, theta):
    try:
        sint, cost = math.sin(np.radians(theta)), math.cos(np.radians(theta))
    except ValueError as e:
        if 'math domain error' in e.args:
            sint, cost = np.nan, np.nan
    xxo = x - xo
    yyo = y - yo
    exp = (xxo * cost + yyo * sint) ** 2 / sx ** 2 \
          + (xxo * sint - yyo * cost) ** 2 / sy ** 2
    exp *= -1. / 2
    return amp * np.exp(exp)

Response: Generate a 2d Gaussian model with the given parameters.


Instruction:
Given the following Python 3 function, write the documentation
def Cmatrix(x, y, sx, sy, theta):
    C = np.vstack([elliptical_gaussian(x, y, 1, i, j, sx, sy, theta) for i, j in zip(x, y)])
    return C

Response: Construct a correlation matrix corresponding to the data.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def Bmatrix(C):
    # this version of finding the square root of the inverse matrix
    # suggested by Cath Trott
    L, Q = eigh(C)
    # force very small eigenvalues to have some minimum non-zero value
    minL = 1e-9*L[-1]
    L[L < minL] = minL
    S = np.diag(1 / np.sqrt(L))
    B = Q.dot(S)
    return B

Response: Calculate a matrix which is effectively the square root of the correlation matrix C.


Instruction:
Can you tell what is the following Python 3 function doing
def jacobian(pars, x, y):

    matrix = []

    for i in range(pars['components'].value):
        prefix = "c{0}_".format(i)
        amp = pars[prefix + 'amp'].value
        xo = pars[prefix + 'xo'].value
        yo = pars[prefix + 'yo'].value
        sx = pars[prefix + 'sx'].value
        sy = pars[prefix + 'sy'].value
        theta = pars[prefix + 'theta'].value

        # The derivative with respect to component i doesn't depend on any other components
        # thus the model should not contain the other components
        model = elliptical_gaussian(x, y, amp, xo, yo, sx, sy, theta)

        # precompute for speed
        sint = np.sin(np.radians(theta))
        cost = np.cos(np.radians(theta))
        xxo = x - xo
        yyo = y - yo
        xcos, ycos = xxo * cost, yyo * cost
        xsin, ysin = xxo * sint, yyo * sint

        if pars[prefix + 'amp'].vary:
            dmds = model / amp
            matrix.append(dmds)

        if pars[prefix + 'xo'].vary:
            dmdxo = cost * (xcos + ysin) / sx ** 2 + sint * (xsin - ycos) / sy ** 2
            dmdxo *= model
            matrix.append(dmdxo)

        if pars[prefix + 'yo'].vary:
            dmdyo = sint * (xcos + ysin) / sx ** 2 - cost * (xsin - ycos) / sy ** 2
            dmdyo *= model
            matrix.append(dmdyo)

        if pars[prefix + 'sx'].vary:
            dmdsx = model / sx ** 3 * (xcos + ysin) ** 2
            matrix.append(dmdsx)

        if pars[prefix + 'sy'].vary:
            dmdsy = model / sy ** 3 * (xsin - ycos) ** 2
            matrix.append(dmdsy)

        if pars[prefix + 'theta'].vary:
            dmdtheta = model * (sy ** 2 - sx ** 2) * (xsin - ycos) * (xcos + ysin) / sx ** 2 / sy ** 2
            matrix.append(dmdtheta)

    return np.array(matrix)

Response: This function calculates the Jacobian of an elliptical gaussian model that contains multiple Gaussians and returns the Jacobian of the model.


Instruction:
How would you code a function in Python 3 to
wrap around the jacobian function to get the output of the lmfit. jacobian function.

Response:
def lmfit_jacobian(pars, x, y, errs=None, B=None, emp=False):
    """
    Wrapper around :func:`AegeanTools.fitting.jacobian` and :func:`AegeanTools.fitting.emp_jacobian`
    which gives the output in a format that is required for lmfit.

    Parameters
    ----------
    pars : lmfit.Model
        The model parameters

    x, y : list
        Locations at which the jacobian is being evaluated

    errs : list
        a vector of 1\sigma errors (optional). Default = None

    B : 2d-array
        a B-matrix (optional) see :func:`AegeanTools.fitting.Bmatrix`

    emp : bool
        If true the use the empirical Jacobian, otherwise use the analytical one.
        Default = False.

    Returns
    -------
    j : 2d-array
        A Jacobian.

    See Also
    --------
    :func:`AegeanTools.fitting.Bmatrix`
    :func:`AegeanTools.fitting.jacobian`
    :func:`AegeanTools.fitting.emp_jacobian`

    """
    if emp:
        matrix = emp_jacobian(pars, x, y)
    else:
        # calculate in the normal way
        matrix = jacobian(pars, x, y)
    # now munge this to be as expected for lmfit
    matrix = np.vstack(matrix)

    if errs is not None:
        matrix /= errs
        # matrix = matrix.dot(errs)

    if B is not None:
        matrix = matrix.dot(B)

    matrix = np.transpose(matrix)
    return matrix


Instruction:
Explain what the following Python 3 code does
def hessian(pars, x, y):
    j = 0  # keeping track of the number of variable parameters
    # total number of variable parameters
    ntvar = np.sum([pars[k].vary for k in pars.keys() if k != 'components'])
    # construct an empty matrix of the correct size
    hmat = np.zeros((ntvar, ntvar, x.shape[0], x.shape[1]))
    npvar = 0

    for i in range(pars['components'].value):
        prefix = "c{0}_".format(i)
        amp = pars[prefix + 'amp'].value
        xo = pars[prefix + 'xo'].value
        yo = pars[prefix + 'yo'].value
        sx = pars[prefix + 'sx'].value
        sy = pars[prefix + 'sy'].value
        theta = pars[prefix + 'theta'].value

        amp_var = pars[prefix + 'amp'].vary
        xo_var = pars[prefix + 'xo'].vary
        yo_var = pars[prefix + 'yo'].vary
        sx_var = pars[prefix + 'sx'].vary
        sy_var = pars[prefix + 'sy'].vary
        theta_var = pars[prefix + 'theta'].vary

        # precomputed for speed
        model = elliptical_gaussian(x, y, amp, xo, yo, sx, sy, theta)
        sint = np.sin(np.radians(theta))
        sin2t = np.sin(np.radians(2*theta))
        cost = np.cos(np.radians(theta))
        cos2t = np.cos(np.radians(2*theta))
        sx2 = sx**2
        sy2 = sy**2
        xxo = x-xo
        yyo = y-yo
        xcos, ycos = xxo*cost, yyo*cost
        xsin, ysin = xxo*sint, yyo*sint

        if amp_var:
            k = npvar  # second round of keeping track of variable params
            # H(amp,amp)/G =  0
            hmat[j][k] = 0
            k += 1

            if xo_var:
                # H(amp,xo)/G =  1.0*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t))/(amp*sx**2*sy**2)
                hmat[j][k] = (xsin - ycos)*sint/sy2 + (xcos + ysin)*cost/sx2
                hmat[j][k] *= model
                k += 1

            if yo_var:
                # H(amp,yo)/G =  1.0*(-sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*cos(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t))/(amp*sx**2*sy**2)
                hmat[j][k] = -(xsin - ycos)*cost/sy2 + (xcos + ysin)*sint/sx2
                hmat[j][k] *= model/amp
                k += 1

            if sx_var:
                # H(amp,sx)/G =  1.0*((x - xo)*cos(t) + (y - yo)*sin(t))**2/(amp*sx**3)
                hmat[j][k] = (xcos + ysin)**2
                hmat[j][k] *= model/(amp*sx**3)
                k += 1

            if sy_var:
                # H(amp,sy) =  1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))**2/(amp*sy**3)
                hmat[j][k] = (xsin - ycos)**2
                hmat[j][k] *= model/(amp*sy**3)
                k += 1

            if theta_var:
                # H(amp,t) =  (-1.0*sx**2 + sy**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))*((x - xo)*cos(t) + (y - yo)*sin(t))/(amp*sx**2*sy**2)
                hmat[j][k] = (xsin - ycos)*(xcos + ysin)
                hmat[j][k] *= sy2-sx2
                hmat[j][k] *= model/(amp*sx2*sy2)
                # k += 1
            j += 1

        if xo_var:
            k = npvar
            if amp_var:
                # H(xo,amp)/G = H(amp,xo)
                hmat[j][k] = hmat[k][j]
                k += 1

            # if xo_var:
            # H(xo,xo)/G =  1.0*(-sx**2*sy**2*(sx**2*sin(t)**2 + sy**2*cos(t)**2) + (sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t))**2)/(sx**4*sy**4)
            hmat[j][k] = -sx2*sy2*(sx2*sint**2 + sy2*cost**2)
            hmat[j][k] += (sx2*(xsin - ycos)*sint + sy2*(xcos + ysin)*cost)**2
            hmat[j][k] *= model/ (sx2**2*sy2**2)
            k += 1

            if yo_var:
                # H(xo,yo)/G =  1.0*(sx**2*sy**2*(sx**2 - sy**2)*sin(2*t)/2 - (sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*cos(t) - sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t)))/(sx**4*sy**4)
                hmat[j][k] = sx2*sy2*(sx2 - sy2)*sin2t/2
                hmat[j][k] -= (sx2*(xsin - ycos)*sint + sy2*(xcos + ysin)*cost)*(sx2*(xsin -ycos)*cost - sy2*(xcos + ysin)*sint)
                hmat[j][k] *= model / (sx**4*sy**4)
                k += 1

            if sx_var:
                # H(xo,sx) =  ((x - xo)*cos(t) + (y - yo)*sin(t))*(-2.0*sx**2*sy**2*cos(t) + 1.0*((x - xo)*cos(t) + (y - yo)*sin(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t)))/(sx**5*sy**2)
                hmat[j][k] = (xcos + ysin)
                hmat[j][k] *= -2*sx2*sy2*cost + (xcos + ysin)*(sx2*(xsin - ycos)*sint + sy2*(xcos + ysin)*cost)
                hmat[j][k] *= model / (sx**5*sy2)
                k += 1

            if sy_var:
                # H(xo,sy) =  ((x - xo)*sin(t) + (-y + yo)*cos(t))*(-2.0*sx**2*sy**2*sin(t) + 1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t)))/(sx2*sy**5)
                hmat[j][k] = (xsin - ycos)
                hmat[j][k] *= -2*sx2*sy2*sint + (xsin - ycos)*(sx2*(xsin - ycos)*sint + sy2*(xcos + ysin)*cost)
                hmat[j][k] *= model/(sx2*sy**5)
                k += 1

            if theta_var:
                # H(xo,t) =  1.0*(sx**2*sy**2*(sx**2 - sy**2)*(x*sin(2*t) - xo*sin(2*t) - y*cos(2*t) + yo*cos(2*t)) + (-sx**2 + 1.0*sy**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))*((x - xo)*cos(t) + (y - yo)*sin(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*sin(t) + sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*cos(t)))/(sx**4*sy**4)
                # second part
                hmat[j][k] = (sy2-sx2)*(xsin - ycos)*(xcos + ysin)
                hmat[j][k] *= sx2*(xsin -ycos)*sint + sy2*(xcos + ysin)*cost
                # first part
                hmat[j][k] += sx2*sy2*(sx2 - sy2)*(xxo*sin2t -yyo*cos2t)
                hmat[j][k] *= model/(sx**4*sy**4)
                # k += 1
            j += 1

        if yo_var:
            k = npvar
            if amp_var:
                # H(yo,amp)/G = H(amp,yo)
                hmat[j][k] = hmat[0][2]
                k += 1

            if xo_var:
                # H(yo,xo)/G = H(xo,yo)/G
                hmat[j][k] =hmat[1][2]
                k += 1

            # if yo_var:
            # H(yo,yo)/G = 1.0*(-sx**2*sy**2*(sx**2*cos(t)**2 + sy**2*sin(t)**2) + (sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*cos(t) - sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t))**2)/(sx**4*sy**4)
            hmat[j][k] = (sx2*(xsin - ycos)*cost - sy2*(xcos + ysin)*sint)**2 / (sx2**2*sy2**2)
            hmat[j][k] -= cost**2/sy2 + sint**2/sx2
            hmat[j][k] *= model
            k += 1

            if sx_var:
                # H(yo,sx)/G =  -((x - xo)*cos(t) + (y - yo)*sin(t))*(2.0*sx**2*sy**2*sin(t) + 1.0*((x - xo)*cos(t) + (y - yo)*sin(t))*(sx**2*((x - xo)*sin(t) - (y - yo)*cos(t))*cos(t) - sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t)))/(sx**5*sy**2)
                hmat[j][k] = -1*(xcos + ysin)
                hmat[j][k] *= 2*sx2*sy2*sint + (xcos + ysin)*(sx2*(xsin - ycos)*cost - sy2*(xcos + ysin)*sint)
                hmat[j][k] *= model/(sx**5*sy2)
                k += 1

            if sy_var:
                # H(yo,sy)/G =  ((x - xo)*sin(t) + (-y + yo)*cos(t))*(2.0*sx**2*sy**2*cos(t) - 1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*cos(t) - sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t)))/(sx**2*sy**5)
                hmat[j][k] = (xsin -ycos)
                hmat[j][k] *= 2*sx2*sy2*cost - (xsin - ycos)*(sx2*(xsin - ycos)*cost - sy2*(xcos + ysin)*sint)
                hmat[j][k] *= model/(sx2*sy**5)
                k += 1

            if theta_var:
                # H(yo,t)/G =  1.0*(sx**2*sy**2*(sx**2*(-x*cos(2*t) + xo*cos(2*t) - y*sin(2*t) + yo*sin(2*t)) + sy**2*(x*cos(2*t) - xo*cos(2*t) + y*sin(2*t) - yo*sin(2*t))) + (1.0*sx**2 - sy**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))*((x - xo)*cos(t) + (y - yo)*sin(t))*(sx**2*((x - xo)*sin(t) + (-y + yo)*cos(t))*cos(t) - sy**2*((x - xo)*cos(t) + (y - yo)*sin(t))*sin(t)))/(sx**4*sy**4)
                hmat[j][k] = (sx2 - sy2)*(xsin - ycos)*(xcos + ysin)
                hmat[j][k] *= (sx2*(xsin - ycos)*cost - sy2*(xcos + ysin)*sint)
                hmat[j][k] += sx2*sy2*(sx2-sy2)*(-x*cos2t + xo*cos2t - y*sin2t + yo*sin2t)
                hmat[j][k] *= model/(sx**4*sy**4)
                # k += 1
            j += 1

        if sx_var:
            k = npvar
            if amp_var:
                # H(sx,amp)/G = H(amp,sx)/G
                hmat[j][k] = hmat[k][j]
                k += 1

            if xo_var:
                # H(sx,xo)/G = H(xo,sx)/G
                hmat[j][k] = hmat[k][j]
                k += 1

            if yo_var:
                # H(sx,yo)/G = H(yo/sx)/G
                hmat[j][k] = hmat[k][j]
                k += 1

            # if sx_var:
            # H(sx,sx)/G =  (-3.0*sx**2 + 1.0*((x - xo)*cos(t) + (y - yo)*sin(t))**2)*((x - xo)*cos(t) + (y - yo)*sin(t))**2/sx**6
            hmat[j][k] = -3*sx2 + (xcos + ysin)**2
            hmat[j][k] *= (xcos + ysin)**2
            hmat[j][k] *= model/sx**6
            k += 1

            if sy_var:
                # H(sx,sy)/G =  1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))**2*((x - xo)*cos(t) + (y - yo)*sin(t))**2/(sx**3*sy**3)
                hmat[j][k] = (xsin - ycos)**2 * (xcos + ysin)**2
                hmat[j][k] *= model/(sx**3*sy**3)
                k += 1

            if theta_var:
                # H(sx,t)/G =  (-2.0*sx**2*sy**2 + 1.0*(-sx**2 + sy**2)*((x - xo)*cos(t) + (y - yo)*sin(t))**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))*((x - xo)*cos(t) + (y - yo)*sin(t))/(sx**5*sy**2)
                hmat[j][k] = -2*sx2*sy2 + (sy2 - sx2)*(xcos + ysin)**2
                hmat[j][k] *= (xsin -ycos)*(xcos + ysin)
                hmat[j][k] *= model/(sx**5*sy**2)
                # k += 1
            j += 1

        if sy_var:
            k = npvar
            if amp_var:
                # H(sy,amp)/G = H(amp,sy)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if xo_var:
                # H(sy,xo)/G = H(xo,sy)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if yo_var:
                # H(sy,yo)/G = H(yo/sy)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if sx_var:
                # H(sy,sx)/G = H(sx,sy)/G
                hmat[j][k] = hmat[k][j]
                k += 1

            # if sy_var:
            # H(sy,sy)/G =  (-3.0*sy**2 + 1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))**2/sy**6
            hmat[j][k] = -3*sy2 + (xsin - ycos)**2
            hmat[j][k] *= (xsin - ycos)**2
            hmat[j][k] *= model/sy**6
            k += 1

            if theta_var:
                # H(sy,t)/G =  (2.0*sx**2*sy**2 + 1.0*(-sx**2 + sy**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))**2)*((x - xo)*sin(t) + (-y + yo)*cos(t))*((x - xo)*cos(t) + (y - yo)*sin(t))/(sx**2*sy**5)
                hmat[j][k] = 2*sx2*sy2 + (sy2 - sx2)*(xsin - ycos)**2
                hmat[j][k] *= (xsin - ycos)*(xcos + ysin)
                hmat[j][k] *= model/(sx**2*sy**5)
                # k += 1
            j += 1

        if theta_var:
            k = npvar
            if amp_var:
                # H(t,amp)/G = H(amp,t)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if xo_var:
                # H(t,xo)/G = H(xo,t)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if yo_var:
                # H(t,yo)/G = H(yo/t)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if sx_var:
                # H(t,sx)/G = H(sx,t)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            if sy_var:
                # H(t,sy)/G = H(sy,t)/G
                hmat[j][k] = hmat[k][j]
                k += 1
            # if theta_var:
            # H(t,t)/G =  (sx**2*sy**2*(sx**2*(((x - xo)*sin(t) + (-y + yo)*cos(t))**2 - 1.0*((x - xo)*cos(t) + (y - yo)*sin(t))**2) + sy**2*(-1.0*((x - xo)*sin(t) + (-y + yo)*cos(t))**2 + ((x - xo)*cos(t) + (y - yo)*sin(t))**2)) + (sx**2 - 1.0*sy**2)**2*((x - xo)*sin(t) + (-y + yo)*cos(t))**2*((x - xo)*cos(t) + (y - yo)*sin(t))**2)/(sx**4*sy**4)
            hmat[j][k] = sx2*sy2
            hmat[j][k] *= sx2*((xsin - ycos)**2 - (xcos + ysin)**2) + sy2*((xcos + ysin)**2 - (xsin - ycos)**2)
            hmat[j][k] += (sx2 - sy2)**2*(xsin - ycos)**2*(xcos + ysin)**2
            hmat[j][k] *= model/(sx**4*sy**4)
            # j += 1

        # save the number of variables for the next iteration
        # as we need to start our indexing at this number
        npvar = k
    return np.array(hmat)

Response: Create a hessian matrix corresponding to the source model pars.


Instruction:
Create a Python 3 function to
calculate the hessian matrix empirically.

Response:
def emp_hessian(pars, x, y):
    """
    Calculate the hessian matrix empirically.
    Create a hessian matrix corresponding to the source model 'pars'
    Only parameters that vary will contribute to the hessian.
    Thus there will be a total of nvar x nvar entries, each of which is a
    len(x) x len(y) array.

    Parameters
    ----------
    pars : lmfit.Parameters
        The model
    x, y : list
        locations at which to evaluate the Hessian

    Returns
    -------
    h : np.array
        Hessian. Shape will be (nvar, nvar, len(x), len(y))

    Notes
    -----
    Uses :func:`AegeanTools.fitting.emp_jacobian` to calculate the first order derivatives.

    See Also
    --------
    :func:`AegeanTools.fitting.hessian`
    """
    eps = 1e-5
    matrix = []
    for i in range(pars['components'].value):
        model = emp_jacobian(pars, x, y)
        prefix = "c{0}_".format(i)
        for p in ['amp', 'xo', 'yo', 'sx', 'sy', 'theta']:
            if pars[prefix+p].vary:
                pars[prefix+p].value += eps
                dm2didj = emp_jacobian(pars, x, y) - model
                matrix.append(dm2didj/eps)
                pars[prefix+p].value -= eps
    matrix = np.array(matrix)
    return matrix


Instruction:
Can you generate the documentation for the following Python 3 function
def nan_acf(noise):
    corr = np.zeros(noise.shape)
    ix,jx = noise.shape
    for i in range(ix):
        si_min = slice(i, None, None)
        si_max = slice(None, ix-i, None)
        for j in range(jx):
            sj_min = slice(j, None, None)
            sj_max = slice(None, jx-j, None)
            if np.all(np.isnan(noise[si_min, sj_min])) or np.all(np.isnan(noise[si_max, sj_max])):
                corr[i, j] = np.nan
            else:
                corr[i, j] = np.nansum(noise[si_min, sj_min] * noise[si_max, sj_max])
    # return the normalised acf
    return corr / np.nanmax(corr)

Response:
Calculate the autocorrelation function of the noise image that contains nans
   .