Пример #1
0
def a():
    tracks = u.Grid(lines)
    carts = SortedDict({pos: (c, 0) for pos, c in tracks.items() if c in "v^><"})

    uncarts = str.maketrans("v^><", "||--")

    for pos, (c, _) in carts.items():
        track[pos] = c.translate(uncarts)

    corners = {
        ("\\", "<"): "^",
        ("\\", ">"): "v",
        ("\\", "v"): ">",
        ("\\", "^"): "<",
        ("/", "<"): "v",
        ("/", ">"): "^",
        ("/", "v"): "<",
        ("/", "^"): ">",
    }

    left = {
        '>': '^',
        '^': '<',
        '<': 'v',
        'v': '>',
    }
    right = {
        '^': '>',
        '>': 'v',
        'v': '<',
        '<': '^',
    }


    dirs = {
        '>': (1, 0),
        '<': (-1, 0),
        'v': (0, 1),
        '^': (0, -1),
    }

    while True:
        ncarts = SortedDict()
        for pos, (c, i) in carts.items()
            d = dirs[c]
            nc = c
            npos = (pos[0] + d[0], pos[1] + d[1])
            tr = tracks.grid[npos]
            if tr == '+':
                i += 1
                if i % 3 == 0:
                    nc = left[c]
                elif i % 3 == 2:
                    nc = right[c]
            elif tr in '\\/':
                nc = corners[tr,c]
            if npos in ncarts:
                return f'{npos[0]},{npos[1]}'
            ncarts
            ncarts.append((npos, nc, i))
Пример #2
0
class Mathecamp():
    """
    This is the main class representing all the data that a mathecamp comprises at any time of the planning
    """

    # <editor-fold desc="Constructor">
    def __init__(self,
                 startDate=datetime.min,
                 endDate=datetime.max,
                 nextHumanId=1,
                 nextRoomId=1,
                 nextActivityId=1,
                 nextMathCircleId=1,
                 nextExpenseId=1,
                 nextSpaceTimeSlotId=1,
                 generalRooms=None,
                 privateRooms=None,
                 activities=None,
                 spacetimeSlots=None,
                 mathCircles=None,
                 expenses=None,
                 participants=None,
                 counselors=None,
                 guests=None,
                 schedule=None):
        """
        The main constructor of a mathecamp instance
        :param startDate: the start date time of the camp
        :param endDate: the end date time of the camp
        :param nextHumanId: the next used Id for a human
        :param nextRoomId: the next used Id for a room
        :param nextActivityId: the next used Id for an activity
        :param nextMathCircleId: the next used Id for a math circle
        :param nextExpenseId: the next used Id for an expense
        :param nextSpaceTimeSlotId: the next used Id for a space-time slot
        :param generalRooms: general rooms in the camp as a dictionary
        :param privateRooms: private rooms in the camp as a dictionary
        :param activities: activities in the camp as a dictionary
        :param spacetimeSlots: spacetime slots in the camp as a dictionary
        :param mathCircles: math circles in the camp as a dictionary
        :param expenses: expenses in the camp as a dictionary
        :param participants: participants in the camp as a dictionary
        :param counselors: counselors in the camp as a dictionary
        :param guests: guests in the camp as a dictionary
        """

        if guests is None:
            guests = SortedDict({})
        if counselors is None:
            counselors = SortedDict({})
        if participants is None:
            participants = SortedDict({})
        if expenses is None:
            expenses = SortedDict({})
        if mathCircles is None:
            mathCircles = SortedDict({})
        if activities is None:
            activities = SortedDict({})
        if spacetimeSlots is None:
            spacetimeSlots = SortedDict({})
        if generalRooms is None:
            generalRooms = SortedDict({})
        if privateRooms is None:
            privateRooms = SortedDict({})
        if schedule is None:
            schedule = Schedule(SortedList([]))

        self.dates = SortedDict({"start": startDate, "end": endDate})
        self.nextIds = SortedDict({
            "Human": nextHumanId,
            "Room": nextRoomId,
            "Activity": nextActivityId,
            "MathCircle": nextMathCircleId,
            "Expense": nextExpenseId,
            "SpaceTimeSlot": nextSpaceTimeSlotId
        })
        self.generalRooms = SortedDict(generalRooms)
        self.privateRooms = SortedDict(privateRooms)
        self.activities = SortedDict(activities)
        self.mathCircles = SortedDict(mathCircles)
        self.expenses = SortedDict(expenses)
        self.participants = SortedDict(participants)
        self.counselors = SortedDict(counselors)
        self.guests = SortedDict(guests)
        self.schedule = schedule
        self.spacetimeSlots = SortedDict(spacetimeSlots)

    # </editor-fold>

    # <editor-fold desc="Serialization">
    def toDict(self):
        """
        Serializes the state of the mathecamp such that it can be easily written to CSV files.
        :return: a dictionary containing the following data:
        generalData : a list of dictionaries each having an entry "parameter" and an entry "value" which represent
        the general settings and data of the mathecamp
        privateRooms, generalRooms, activities, mathCircles, expenses, participants, counselors, guests and schedule: dictionaries with IDs
        as keys and dictionaries with their respective data as values
        """

        generalDataDict = SortedDict({})
        privateRoomDict = SortedDict({})
        generalRoomDict = SortedDict({})
        activityDict = SortedDict({})
        mathCircleDict = SortedDict({})
        expenseDict = SortedDict({})
        participantDict = SortedDict({})
        counselorDict = SortedDict({})
        guestDict = SortedDict({})
        spacetimeSlotDict = SortedDict({})

        generalDataDict["startDate"] = self.dates["start"]
        generalDataDict["endDate"] = self.dates["end"]
        generalDataDict["nextHumanId"] = self.nextIds["Human"]
        generalDataDict["nextActivityId"] = self.nextIds["Activity"]
        generalDataDict["nextRoomId"] = self.nextIds["Room"]
        generalDataDict["nextExpenseId"] = self.nextIds["Expense"]
        generalDataDict["nextSpaceTimeSlotId"] = self.nextIds["SpaceTimeSlot"]
        generalDataDict["nextMathCircleId"] = self.nextIds["MathCircle"]

        for (k, v) in self.generalRooms.items():
            generalRoomDict[k] = SortedDict(v.toDict())

        for (k, v) in self.privateRooms.items():
            privateRoomDict[k] = SortedDict(v.toDict())

        for (k, v) in self.activities.items():
            activityDict[k] = SortedDict(v.toDict())

        for (k, v) in self.mathCircles.items():
            mathCircleDict[k] = SortedDict(v.toDict())

        for (k, v) in self.expenses.items():
            expenseDict[k] = SortedDict(v.toDict())

        for (k, v) in self.participants.items():
            participantDict[k] = SortedDict(v.toDict())

        for (k, v) in self.counselors.items():
            counselorDict[k] = SortedDict(v.toDict())

        for (k, v) in self.guests.items():
            guestDict[k] = SortedDict(v.toDict())

        for (k, v) in self.spacetimeSlots.items():
            spacetimeSlotDict[k] = SortedDict(v.toDict())

        return (SortedDict({
            "generalData": generalDataDict,
            "generalRooms": generalRoomDict,
            "privateRooms": privateRoomDict,
            "activities": activityDict,
            "mathCircles": mathCircleDict,
            "expenses": expenseDict,
            "participants": participantDict,
            "counselors": counselorDict,
            "guests": guestDict,
            "spacetimeSlots": spacetimeSlotDict,
            "schedule": self.schedule.toDict()
        }))

    @classmethod
    def fromDict(cls, dictionary):
        """
        opposite of 'toDict", deserializes a dictionary of dictionaries to a new instance of mathecamp
        :param dictionary: data to deserialize
        :return: a new instance of a mathecamp
        """

        return (Mathecamp(
            dictionary["generalData"]["startDate"],
            dictionary["generalData"]["endDate"],
            dictionary["generalData"]["nextHumanId"],
            dictionary["generalData"]["nextRoomId"],
            dictionary["generalData"]["nextActivityId"],
            dictionary["generalData"]["nextMathCircleId"],
            dictionary["generalData"]["nextExpenseId"],
            dictionary["generalData"]["nextSpaceTimeSlotId"], {
                k: GeneralRoom.fromDict(v)
                for (k, v) in dictionary["generalRooms"].items()
            }, {
                k: PrivateRoom.fromDict(v)
                for (k, v) in dictionary["privateRooms"].items()
            }, {
                k: Activity.fromDict(v)
                for (k, v) in dictionary["activities"].items()
            }, {
                k: SpaceTimeSlot.fromDict(v)
                for (k, v) in dictionary["spacetimeSlots"].items()
            }, {
                k: MathCircle.fromDict(v)
                for (k, v) in dictionary["mathCircles"].items()
            }, {
                k: Expense.fromDict(v)
                for (k, v) in dictionary["expenses"].items()
            }, {
                k: Participant.fromDict(v)
                for (k, v) in dictionary["participants"].items()
            }, {
                k: Counselor.fromDict(v)
                for (k, v) in dictionary["counselors"].items()
            },
            {k: Guest.fromDict(v)
             for (k, v) in dictionary["guests"].items()},
            Schedule.fromDict(dictionary["schedule"])))

    @classmethod
    def fromDictOfStrings(cls, dictionary):
        """
        creates a Mathecmap instance from a dictionary of strings as is created by deserializing csv tables

        :param dictionary: the dictionary to parse
        :return: a new instance of a Mathecamp
        """

        return (Mathecamp(
            datetime.strptime(dictionary["generalData"]["startDate"],
                              "%Y-%m-%d %H:%M:%S"),
            datetime.strptime(dictionary["generalData"]["endDate"],
                              "%Y-%m-%d %H:%M:%S"),
            int(dictionary["generalData"]["nextHumanId"]),
            int(dictionary["generalData"]["nextRoomId"]),
            int(dictionary["generalData"]["nextActivityId"]),
            int(dictionary["generalData"]["nextMathCircleId"]),
            int(dictionary["generalData"]["nextExpenseId"]),
            int(dictionary["generalData"]["nextSpaceTimeSlotId"]), {
                k: GeneralRoom.fromDictOfStrings(v)
                for (k, v) in dictionary["generalRooms"].items()
            }, {
                k: PrivateRoom.fromDictOfStrings(v)
                for (k, v) in dictionary["privateRooms"].items()
            }, {
                k: Activity.fromDictOfStrings(v)
                for (k, v) in dictionary["activities"].items()
            }, {
                k: SpaceTimeSlot.fromDictOfStrings(v)
                for (k, v) in dictionary["spacetimeSlots"].items()
            }, {
                k: MathCircle.fromDictOfStrings(v)
                for (k, v) in dictionary["mathCircles"].items()
            }, {
                k: Expense.fromDictOfStrings(v)
                for (k, v) in dictionary["expenses"].items()
            }, {
                k: Participant.fromDictOfStrings(v)
                for (k, v) in dictionary["participants"].items()
            }, {
                k: Counselor.fromDictOfStrings(v)
                for (k, v) in dictionary["counselors"].items()
            }, {
                k: Guest.fromDictOfStrings(v)
                for (k, v) in dictionary["guests"].items()
            }, Schedule.fromDictOfStrings(dictionary["schedule"])))

    # </editor-fold>

    # <editor-fold desc="Helper methods">

    def __str__(self):
        return (
            "Mathecamp(" + self.dates["start"].__str__() + ", " +
            self.dates["end"].__str__() + ", " +
            self.nextIds["Human"].__str__() + ", " +
            self.nextIds["Room"].__str__() + ", " +
            self.nextIds["Activity"].__str__() + ", " +
            self.nextIds["MathCircle"].__str__() + ", " +
            self.nextIds["Expense"].__str__() + ", " +
            self.nextIds["SpaceTimeSlot"].__str__() + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.generalRooms.items()
            }).__str__()[11:-1] + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.privateRooms.items()
            }).__str__()[11:-1] + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.activities.items()
            }).__str__()[11:-1] + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.spacetimeSlots.items()
            }).__str__()[11:-1] + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.mathCircles.items()
            }).__str__()[11:-1] + ", " + SortedDict(
                {k.__str__(): v.__str__()
                 for (k, v) in self.expenses.items()}).__str__()[11:-1] +
            ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.participants.items()
            }).__str__()[11:-1] + ", " + SortedDict({
                k.__str__(): v.__str__()
                for (k, v) in self.counselors.items()
            }).__str__()[11:-1] + ", " + SortedDict(
                {k.__str__(): v.__str__()
                 for (k, v) in self.guests.items()}).__str__()[11:-1] + ", " +
            self.schedule.__str__() + ")")

    def isDuringCamp(self, time):
        """
        returns a Boolean stating whether the given date time is during the Mathecamp or not
        :param time: datetime to check
        :return: a Boolean
        """
        if (self.dates["start"] <= time and time <= self.dates["end"]):
            return True
        else:
            return False

    def isConsistent(self):
        """
        checks if all referenced IDs exist in the mathcamp
        :return: a Boolean expressing whether the mathcamp is consistent or not
        """
        # TODO implement isConsistent method
        return True

    # </editor-fold>

    # <editor-fold desc="Add data methods">

    def addRoom(self, room):
        """
        method for adding a room to the project
        :param room: a room of type Room
        :return:
        """

        nextId = self.nextIds["Room"]
        if (isinstance(room, GeneralRoom)):
            self.generalRooms.append((nextId, room))
        if (isinstance(room, PrivateRoom)):
            self.privateRooms.append((nextId, room))
        self.nextIds["Room"] += 1

    def addActivity(self, activity):
        """
        method for adding an activity to the project
        :param activity: an activity of type Activity
        :return:
        """

        self.activities.append((self.nextIds["Activity"], activity))
        self.nextIds["Activity"] += 1

    def addMathCircle(self, mathCircle):
        """
        method for adding a math circle to the project
        :param mathCircle: a mathcircle of type MathCircle
        :return:
        """

        self.mathCircles.append((self.nextIds["MathCircle"], mathCircle))
        self.nextIds["MathCircle"] += 1

    def addHuman(self, human):
        """
        method for adding an arbitrary human
        :param human: the person to be added of type either Participant, Counselor or Guest
        :return:
        """

        nextId = self.nextIds["Human"]
        if isinstance(human, Participant):
            self.participants.append((nextId, human))
        elif isinstance(human, Counselor):
            self.counselors.append((nextId, human))
        elif isinstance(human, Guest):
            self.guests.append((nextId, human))
        self.nextIds["Human"] += 1

    def addExpense(self, expense):
        """
        method for adding an expense
        :param expense: the expense to add of type Expense
        :return:
        """

        self.expenses.append((self.nextIds["Expense"], expense))
        self.nextIds["Expense"] += 1

    def addRoomWithID(self, room, id):
        """
        method for adding a room to the project
        :param room: a room of type Room
        :return:
        """

        nextId = self.nextIds["Room"]
        if (isinstance(room, GeneralRoom)):
            self.generalRooms.append((nextId, room))
        if (isinstance(room, PrivateRoom)):
            self.privateRooms.append((nextId, room))
        self.nextIds["Room"] += 1

    def addActivityWithID(self, activity, id):
        """
        method for adding an activity to the project
        :param activity: an activity of type Activity
        :return:
        """

        self.activities.append((self.nextIds["Activity"], activity))
        self.nextIds["Activity"] += 1

    def addMathCircleWithID(self, mathCircle, id):
        """
        method for adding a math circle to the project
        :param mathCircle: a mathcircle of type MathCircle
        :return:
        """

        self.mathCircles.append((self.nextIds["MathCircle"], mathCircle))
        self.nextIds["MathCircle"] += 1

    def addHumanWithID(self, human, id):
        """
        method for adding an arbitrary human
        :param human: the person to be added of type either Participant, Counselor or Guest
        :return:
        """

        nextId = self.nextIds["Human"]
        if isinstance(human, Participant):
            self.participants.append((nextId, human))
        elif isinstance(human, Counselor):
            self.counselors.append((nextId, human))
        elif isinstance(human, Guest):
            self.guests.append((nextId, human))
        self.nextIds["Human"] += 1

    def addExpenseWithID(self, expense, id):
        """
        method for adding an expense
        :param expense: the expense to add of type Expense
        :return:
        """

        self.expenses.append((self.nextIds["Expense"], expense))
        self.nextIds["Expense"] += 1
Пример #3
0
def transform_teragon_csv(teragon_csv, transpose=False, indexed=False):
    """transform Teragon's CSV response into a python dictionary,
    which mirrors the JSON response we want to provide to API clients

    Arguments:
        teragon_csv {reference} -- reference to a CSV table on disk
        or in memory
        transpose {boolean} -- transpose Teragon table
        indexed {boolean} -- return dictionary in indexed format or as records

    Returns:
        {dict} -- a dictionary representing the Terragon table, transformed
        for ease of use in spatial/temporal data vizualation
    """

    petl_table = etl.fromcsv(teragon_csv)
    # print(petl_table)
    # get iterable of column pairs (minus 'Timestamp')
    # this is used to group the double columns representing a single
    # data point in Teragon's CSV

    h = list(etl.header(petl_table))
    xy_cols = zip(*[iter(h[1:])] * 2)

    # make a new header row
    new_header = ['Timestamp']
    fields_to_cut = []
    for each in xy_cols:
        # print(each)
        # correct id, assembled from columns
        id_col, note_col = each[0], each[1]
        # assemble new id column, to replace of PX column (which has data)
        # id_col = "{0}{1}".format(px[:3], px[4:])
        # assemble new notes column, to replace of PY column (which has notes)
        notes_col = "{0}-n".format(id_col)
        # add those to our new header (array)
        new_header.extend([id_col, notes_col])
        # track fields that we might want to remove
        fields_to_cut.append(notes_col)

    # transform the table
    table = etl \
        .setheader(petl_table, new_header) \
        .cutout(*tuple(fields_to_cut))  \
        .select('Timestamp', lambda v: v.upper() != 'TOTAL')  \
        .convert('Timestamp', lambda t: parse(t).isoformat())  \
        .replaceall('N/D', None)

    # transpose the table, so that rows are cells/gauges and columns are times
    # (note that this operation can take a while)
    if transpose:
        table = etl.transpose(table)

    # if indexed: format data where cells/gauges or times are keys, and
    # rainfall amounts are values
    # otherwise, format as nested records (arrays of dicts)

    if indexed:
        data = SortedDict()
        for row in etl.dicts(table):
            inside = SortedDict()
            for d in row.items():
                if d[0] != 'Timestamp':
                    if d[1]:
                        v = float(d[1])
                    else:
                        v = d[1]
                    inside[d[0]] = v
            data[row['Timestamp']] = inside
        return data

    else:
        rows = []
        # create a nested dictionary from the table
        for row in etl.dicts(table):
            data = []
            for d in row.items():
                if d[0] != 'Timestamp':
                    if d[1]:
                        v = float(d[1])
                    else:
                        v = d[1]
                    data.append({'id': d[0], 'v': v})
            rows.append({"id": row['Timestamp'], "d": data})
        # print(rows)
        # print(json.dumps(rows, indent=2))
        return rows