def profile(self, r, **attr):
        """
            Generate a Profile page

            @param r: the S3Request instance
            @param attr: controller attributes for the request
        """

        tablename = self.tablename
        get_config = current.s3db.get_config

        # Get the page widgets
        widgets = get_config(tablename, "profile_widgets")
        if not widgets:
            # Profile page not configured:
            if ("dl", "aadata") not in r.representation:
                # Redirect to the Read View
                redirect(r.url(method="read"))
            else:
                # No point redirecting
                r.error(405, current.ERROR.BAD_METHOD)

        # Index the widgets by their position in the config
        for index, widget in enumerate(widgets):
            widget["index"] = index

        if r.representation == "dl":
            # Ajax-update of one datalist
            index = r.get_vars.get("update", None)
            if index:
                try:
                    index = int(index)
                except ValueError:
                    datalist = ""
                else:
                    # @ToDo: Check permissions to the Resource & do
                    # something different if no permission
                    datalist = self._datalist(r, widgets[index], **attr)
            output = {"item": datalist}

        elif r.representation == "aadata":
            # Ajax-update of one datalist
            index = r.get_vars.get("update", None)
            if index:
                try:
                    index = int(index)
                except ValueError:
                    datalist = ""
                else:
                    # @ToDo: Check permissions to the Resource & do
                    # something different if no permission
                    datatable = self._datatable(r, widgets[index], **attr)
            return datatable

        else:
            # Default page-load

            # Page Title
            title = get_config(tablename, "profile_title")
            if not title:
                try:
                    title = r.record.name
                except:
                    title = current.T("Profile Page")
            elif callable(title):
                title = title(r)

            # Page Header
            header = get_config(tablename, "profile_header")
            if not header:
                header = H2(title, _class="profile-header")
            elif callable(header):
                header = header(r)

            output = dict(title=title, header=header)

            # Update Form, if configured
            update = get_config(tablename, "profile_update")
            if update:
                editable = get_config(tablename, "editable", True)
                authorised = self._permitted(method="update")
                if authorised and editable:
                    show = self.crud_string(tablename, "title_update")
                    hide = current.T("Hide Form")
                    form = self.update(r, **attr)["form"]
                else:
                    show = self.crud_string(tablename, "title_display")
                    hide = current.T("Hide Details")
                    form = self.read(r, **attr)["item"]

                if update == "visible":
                    hidden = False
                    label = hide
                    style_hide, style_show = None, "display:none"
                else:
                    hidden = True
                    label = show
                    style_hide, style_show = "display:none", None

                toggle = A(SPAN(label,
                                data = {"on": show,
                                        "off": hide,
                                        },
                                ),
                           ICON("down", _style=style_show),
                           ICON("up", _style=style_hide),
                           data = {"hidden": hidden},
                           _class="form-toggle action-lnk",
                           )
                form.update(_style=style_hide)
                output["form"] = DIV(toggle,
                                     form,
                                     _class="profile-update",
                                     )
            else:
                output["form"] = ""

            # Widgets
            response = current.response
            rows = []
            append = rows.append
            row = None
            cols = get_config(tablename, "profile_cols")
            if not cols:
                cols = 2
            row_cols = 0
            for widget in widgets:

                # Render the widget
                w_type = widget["type"]
                if w_type == "comments":
                    w = self._comments(r, widget, **attr)
                elif w_type == "datalist":
                    w = self._datalist(r, widget, **attr)
                elif w_type == "datatable":
                    w = self._datatable(r, widget, **attr)
                elif w_type == "form":
                    w = self._form(r, widget, **attr)
                elif w_type == "map":
                    w = self._map(r, widget, widgets, **attr)
                elif w_type == "report":
                    w = self._report(r, widget, **attr)
                elif w_type == "custom":
                    w = self._custom(r, widget, **attr)
                else:
                    if response.s3.debug:
                        raise SyntaxError("Unsupported widget type %s" %
                                          w_type)
                    else:
                        # ignore
                        continue

                if row is None:
                    # Start new row
                    row = DIV(_class="row profile")
                    row_cols = 0

                # Append widget to row
                row.append(w)
                colspan = widget.get("colspan", 1)
                row_cols += colspan
                if row_cols == cols:
                    # Close this row
                    append(row)
                    row = None

            if row:
                # We have an incomplete row of widgets
                append(row)
            output["rows"] = rows

            # Activate this if a project needs it
            #response.view = get_config(tablename, "profile_view") or \
            #                self._view(r, "profile.html")
            response.view = self._view(r, "profile.html")

        return output

    # -------------------------------------------------------------------------
dataset/ETHPy150Open sahana/eden/modules/s3/s3profile.py/S3Profile.profile/swapped operands of `not in`