示例#1
0
文件: main.py 项目: CleryFabien/lmfdb
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Galois Group:' + label
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if ZZ(order) == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(C, n, data['subs'])
        data['resolve'] = resolve_display(C, data['resolve'])
#    if len(data['resolve']) == 0: data['resolve'] = 'None'
        data['otherreps'] = otherrep_display(n, t, C, data['repns'])
        prop2 = [
            ('Order:', '\(%s\)' % order),
            ('n:', '\(%s\)' % data['n']),
            ('Cyclic:', yesno(data['cyc'])),
            ('Abelian:', yesno(data['ab'])),
            ('Solvable:', yesno(data['solv'])),
            ('Primitive:', yesno(data['prim'])),
            ('$p$-group:', yesno(pgroup)),
            ('Name:', group_display_short(n, t, C)),
        ]
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html", credit=GG_credit, title=title, bread=bread, info=info, properties2=prop2)
示例#2
0
文件: main.py 项目: CleryFabien/lmfdb
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Galois Group:' + label
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if ZZ(order) == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(C, n, data['subs'])
        data['resolve'] = resolve_display(C, data['resolve'])
        #    if len(data['resolve']) == 0: data['resolve'] = 'None'
        data['otherreps'] = otherrep_display(n, t, C, data['repns'])
        prop2 = [
            ('Order:', '\(%s\)' % order),
            ('n:', '\(%s\)' % data['n']),
            ('Cyclic:', yesno(data['cyc'])),
            ('Abelian:', yesno(data['ab'])),
            ('Solvable:', yesno(data['solv'])),
            ('Primitive:', yesno(data['prim'])),
            ('$p$-group:', yesno(pgroup)),
            ('Name:', group_display_short(n, t, C)),
        ]
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html",
                               credit=GG_credit,
                               title=title,
                               bread=bread,
                               info=info,
                               properties2=prop2)
示例#3
0
文件: main.py 项目: am-github/lmfdb
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Galois Group: ' + label
        wgg = WebGaloisGroup.from_data(data)
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(C, n, data['subs'])
        data['resolve'] = resolve_display(C, data['resolve'])
        data['otherreps'] = wgg.otherrep_list()
        if len(data['otherreps']) == 0:
            data['otherreps']="There is no other low degree representation."
        query={'galois': bson.SON([('n', n), ('t', t)])}
        C = base.getDBConnection()
        intreps = C.transitivegroups.Gmodules.find({'n': n, 't': t}).sort('index', pymongo.ASCENDING)
        # turn cursor into a list
        intreps = [z for z in intreps]
        if len(intreps) > 0:
            data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']]
            for onerep in intreps:
                onerep['gens']=[list_to_latex_matrix(z[1]) for z in onerep['gens']]
            data['int_reps'] = intreps
            data['int_reps_complete'] = int_reps_are_complete(intreps)
            dcq = data['moddecompuniq']
            if dcq[0] == 0:
                data['decompunique'] = 0
            else:
                data['decompunique'] = dcq[0]
                data['isoms'] = [[mult2mult(z[0]), mult2mult(z[1])] for z in dcq[1]]
                data['isoms'] = [[modules2string(n,t,z[0]), modules2string(n,t,z[1])] for z in data['isoms']]
                print dcq[1]
                print data['isoms']

        friends = []
        one = C.numberfields.fields.find_one(query)
        if one:
            friends.append(('Number fields with this Galois group', url_for('number_fields.number_field_render_webpage')+"?galois_group=%dT%d" % (n, t) )) 
        prop2 = [
            ('Order:', '\(%s\)' % order),
            ('n:', '\(%s\)' % data['n']),
            ('Cyclic:', yesno(data['cyc'])),
            ('Abelian:', yesno(data['ab'])),
            ('Solvable:', yesno(data['solv'])),
            ('Primitive:', yesno(data['prim'])),
            ('$p$-group:', yesno(pgroup)),
        ]
        pretty = group_display_pretty(n,t,C)
        if len(pretty)>0:
            prop2.extend([('Group:', pretty)])
            info['pretty_name'] = pretty
        data['name'] = re.sub(r'_(\d+)',r'_{\1}',data['name'])
        data['name'] = re.sub(r'\^(\d+)',r'^{\1}',data['name'])
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html", credit=GG_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends)
示例#4
0
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        data['label_raw'] = label.lower()
        title = 'Galois Group: ' + label
        wgg = WebGaloisGroup.from_data(data)
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(C, n, data['subs'])
        data['resolve'] = resolve_display(C, data['resolve'])
        data['otherreps'] = wgg.otherrep_list()
        if len(data['otherreps']) == 0:
            data['otherreps'] = "There is no other low degree representation."
        query = {'galois': bson.SON([('n', n), ('t', t)])}
        C = base.getDBConnection()
        intreps = C.transitivegroups.Gmodules.find({
            'n': n,
            't': t
        }).sort('index', pymongo.ASCENDING)
        # turn cursor into a list
        intreps = [z for z in intreps]
        if len(intreps) > 0:
            data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']]
            for onerep in intreps:
                onerep['gens'] = [
                    list_to_latex_matrix(z[1]) for z in onerep['gens']
                ]
            data['int_reps'] = intreps
            data['int_reps_complete'] = int_reps_are_complete(intreps)
            dcq = data['moddecompuniq']
            if dcq[0] == 0:
                data['decompunique'] = 0
            else:
                data['decompunique'] = dcq[0]
                data['isoms'] = [[mult2mult(z[0]),
                                  mult2mult(z[1])] for z in dcq[1]]
                data['isoms'] = [[
                    modules2string(n, t, z[0]),
                    modules2string(n, t, z[1])
                ] for z in data['isoms']]
                print dcq[1]
                print data['isoms']

        friends = []
        one = C.numberfields.fields.find_one(query)
        if one:
            friends.append(
                ('Number fields with this Galois group',
                 url_for('number_fields.number_field_render_webpage') +
                 "?galois_group=%dT%d" % (n, t)))
        prop2 = [
            ('Order:', '\(%s\)' % order),
            ('n:', '\(%s\)' % data['n']),
            ('Cyclic:', yesno(data['cyc'])),
            ('Abelian:', yesno(data['ab'])),
            ('Solvable:', yesno(data['solv'])),
            ('Primitive:', yesno(data['prim'])),
            ('$p$-group:', yesno(pgroup)),
        ]
        pretty = group_display_pretty(n, t, C)
        if len(pretty) > 0:
            prop2.extend([('Group:', pretty)])
            info['pretty_name'] = pretty
        data['name'] = re.sub(r'_(\d+)', r'_{\1}', data['name'])
        data['name'] = re.sub(r'\^(\d+)', r'^{\1}', data['name'])
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html",
                               credit=GG_credit,
                               title=title,
                               bread=bread,
                               info=info,
                               properties2=prop2,
                               friends=friends)
示例#5
0
文件: main.py 项目: jwbober/lmfdb
def render_group_webpage(args):
    data = None
    info = {}
    if "label" in args:
        label = clean_input(args["label"])
        label = label.replace("t", "T")
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({"label": label})
        if data is None:
            bread = get_bread([("Search error", url_for(".search"))])
            info["err"] = "Group " + label + " was not found in the database."
            info["label"] = label
            return search_input_error(info, bread)
        title = "Galois Group: " + label
        wgg = WebGaloisGroup.from_data(data)
        n = data["n"]
        t = data["t"]
        data["yesno"] = yesno
        order = data["order"]
        data["orderfac"] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data["ordermsg"] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data["ordermsg"] = "$1$"
        if ZZ(order).is_prime():
            data["ordermsg"] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ("10000000000"):
            ctable = chartable(n, t)
        else:
            ctable = "Group too large"
        data["gens"] = generators(n, t)
        if n == 1 and t == 1:
            data["gens"] = "None needed"
        data["chartable"] = ctable
        data["parity"] = "$%s$" % data["parity"]
        data["cclasses"] = conjclasses(G, n)
        data["subinfo"] = subfield_display(C, n, data["subs"])
        data["resolve"] = resolve_display(C, data["resolve"])
        data["otherreps"] = wgg.otherrep_list()
        if len(data["otherreps"]) == 0:
            data["otherreps"] = "There is no other low degree representation."
        query = {"galois": bson.SON([("n", n), ("t", t)])}
        C = base.getDBConnection()
        intreps = C.transitivegroups.Gmodules.find({"n": n, "t": t}).sort("index", pymongo.ASCENDING)
        # turn cursor into a list
        intreps = [z for z in intreps]
        if len(intreps) > 0:
            data["int_rep_classes"] = [str(z[0]) for z in intreps[0]["gens"]]
            for onerep in intreps:
                onerep["gens"] = [list_to_latex_matrix(z[1]) for z in onerep["gens"]]
            data["int_reps"] = intreps
            data["int_reps_complete"] = int_reps_are_complete(intreps)
            dcq = data["moddecompuniq"]
            if dcq[0] == 0:
                data["decompunique"] = 0
            else:
                data["decompunique"] = dcq[0]
                data["isoms"] = [[mult2mult(z[0]), mult2mult(z[1])] for z in dcq[1]]
                data["isoms"] = [[modules2string(n, t, z[0]), modules2string(n, t, z[1])] for z in data["isoms"]]
                print dcq[1]
                print data["isoms"]

        friends = []
        one = C.numberfields.fields.find_one(query)
        if one:
            friends.append(
                (
                    "Number fields with this Galois group",
                    url_for("number_fields.number_field_render_webpage") + "?galois_group=%dT%d" % (n, t),
                )
            )
        prop2 = [
            ("Order:", "\(%s\)" % order),
            ("n:", "\(%s\)" % data["n"]),
            ("Cyclic:", yesno(data["cyc"])),
            ("Abelian:", yesno(data["ab"])),
            ("Solvable:", yesno(data["solv"])),
            ("Primitive:", yesno(data["prim"])),
            ("$p$-group:", yesno(pgroup)),
        ]
        pretty = group_display_pretty(n, t, C)
        if len(pretty) > 0:
            prop2.extend([("Group:", pretty)])
            info["pretty_name"] = pretty
        data["name"] = re.sub(r"_(\d+)", r"_{\1}", data["name"])
        data["name"] = re.sub(r"\^(\d+)", r"^{\1}", data["name"])
        info.update(data)

        bread = get_bread([(label, " ")])
        return render_template(
            "gg-show-group.html",
            credit=GG_credit,
            title=title,
            bread=bread,
            info=info,
            properties2=prop2,
            friends=friends,
        )
示例#6
0
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        data = db.gps_transitive.lookup(label)
        if data is None:
            bread = get_bread([("Search Error", ' ')])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        data['label_raw'] = label.lower()
        title = 'Galois Group: ' + label
        wgg = WebGaloisGroup.from_data(data)
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(n, data['subs'])
        data['resolve'] = resolve_display(data['resolve'])
        if data['gapid'] == 0:
            data['gapid'] = "Data not available"
        else:
            data['gapid'] = small_group_display_knowl(int(data['order']),
                                                      int(data['gapid']),
                                                      str([int(data['order']), int(data['gapid'])]))
        data['otherreps'] = wgg.otherrep_list()
        ae = wgg.arith_equivalent()
        if ae>0:
            if ae>1:
                data['arith_equiv'] = r'A number field with this Galois group has %d <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.'% ae
            else:
                data['arith_equiv'] = r'A number field with this Galois group has exactly one <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> field.'
        else:
            data['arith_equiv'] = r'A number field with this Galois group has no <a knowl="nf.arithmetically_equivalent", title="arithmetically equivalent">arithmetically equivalent</a> fields.'
        if len(data['otherreps']) == 0:
            data['otherreps']="There is no other low degree representation."
        intreps = list(db.gps_gmodules.search({'n': n, 't': t}))
        if len(intreps) > 0:
            data['int_rep_classes'] = [str(z[0]) for z in intreps[0]['gens']]
            for onerep in intreps:
                onerep['gens']=[list_to_latex_matrix(z[1]) for z in onerep['gens']]
            data['int_reps'] = intreps
            data['int_reps_complete'] = int_reps_are_complete(intreps)
            dcq = data['moddecompuniq']
            if dcq[0] == 0:
                data['decompunique'] = 0
            else:
                data['decompunique'] = dcq[0]
                data['isoms'] = [[mult2mult(z[0]), mult2mult(z[1])] for z in dcq[1]]
                data['isoms'] = [[modules2string(n,t,z[0]), modules2string(n,t,z[1])] for z in data['isoms']]
                #print dcq[1]
                #print data['isoms']

        friends = []
        if db.nf_fields.exists({'degree': n, 'galt': t}):
            friends.append(('Number fields with this Galois group', url_for('number_fields.number_field_render_webpage')+"?galois_group=%dT%d" % (n, t) ))
        prop2 = [('Label', label),
            ('Order', '\(%s\)' % order),
            ('n', '\(%s\)' % data['n']),
            ('Cyclic', yesno(data['cyc'])),
            ('Abelian', yesno(data['ab'])),
            ('Solvable', yesno(data['solv'])),
            ('Primitive', yesno(data['prim'])),
            ('$p$-group', yesno(pgroup)),
        ]
        pretty = group_display_pretty(n,t)
        if len(pretty)>0:
            prop2.extend([('Group:', pretty)])
            info['pretty_name'] = pretty
        data['name'] = re.sub(r'_(\d+)',r'_{\1}',data['name'])
        data['name'] = re.sub(r'\^(\d+)',r'^{\1}',data['name'])
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html", credit=GG_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends)
示例#7
0
def render_group_webpage(args):
    data = None
    info = {}
    if 'label' in args:
        label = clean_input(args['label'])
        label = label.replace('t', 'T')
        C = base.getDBConnection()
        data = C.transitivegroups.groups.find_one({'label': label})
        if data is None:
            bread = get_bread([("Search error", url_for('.search'))])
            info['err'] = "Group " + label + " was not found in the database."
            info['label'] = label
            return search_input_error(info, bread)
        title = 'Galois Group:' + label
        wgg = WebGaloisGroup.from_data(data)
        n = data['n']
        t = data['t']
        data['yesno'] = yesno
        order = data['order']
        data['orderfac'] = latex(ZZ(order).factor())
        orderfac = latex(ZZ(order).factor())
        data['ordermsg'] = "$%s=%s$" % (order, latex(orderfac))
        if order == 1:
            data['ordermsg'] = "$1$"
        if ZZ(order).is_prime():
            data['ordermsg'] = "$%s$ (is prime)" % order
        pgroup = len(ZZ(order).prime_factors()) < 2
        if n == 1:
            G = gap.SmallGroup(n, t)
        else:
            G = gap.TransitiveGroup(n, t)
        if ZZ(order) < ZZ('10000000000'):
            ctable = chartable(n, t)
        else:
            ctable = 'Group too large'
        data['gens'] = generators(n, t)
        if n == 1 and t == 1:
            data['gens'] = 'None needed'
        data['chartable'] = ctable
        data['parity'] = "$%s$" % data['parity']
        data['cclasses'] = conjclasses(G, n)
        data['subinfo'] = subfield_display(C, n, data['subs'])
        data['resolve'] = resolve_display(C, data['resolve'])
#    if len(data['resolve']) == 0: data['resolve'] = 'None'
        data['otherreps'] = wgg.otherrep_list()
        query={'galois': bson.SON([('n', n), ('t', t)])}
        C = base.getDBConnection()
        intreps = C.transitivegroups.Gmodules.find({'n': n, 't': t})
        # turn cursor into a list
        intreps = [z for z in intreps]
        data['int_reps'] = [galois_module_knowl(n, t, z['index'], C) for z in intreps]
        data['int_reps_complete'] = int_reps_are_complete(intreps)

        friends = []
        one = C.numberfields.fields.find_one(query)
        if one:
            friends.append(('Number fields with this Galois group', url_for('number_fields.number_field_render_webpage')+"?galois_group=%dT%d" % (n, t) )) 
        prop2 = [
            ('Order:', '\(%s\)' % order),
            ('n:', '\(%s\)' % data['n']),
            ('Cyclic:', yesno(data['cyc'])),
            ('Abelian:', yesno(data['ab'])),
            ('Solvable:', yesno(data['solv'])),
            ('Primitive:', yesno(data['prim'])),
            ('$p$-group:', yesno(pgroup)),
            ('Name:', group_display_short(n, t, C)),
        ]
        info.update(data)

        bread = get_bread([(label, ' ')])
        return render_template("gg-show-group.html", credit=GG_credit, title=title, bread=bread, info=info, properties2=prop2, friends=friends)