CSSE7030 – Introduction to Software Engineering

In my first semester back at The University of Queensland I learnt Python as part of a course called “Introduction to Software Engineering”. There were 3 assignments each more complex than the last.

Assignment 1

The  first one was a simple command line interface tool to help solve a puzzle.

A selection of the code:

def interact():

"""
runs the app

interact() -> Null (output)
"""

userInput = ""
numOfSupporters = int(input("How many supporters from each team? "))
state = make_initial_state(numOfSupporters)
states = [state]
while str(userInput) != "q":
show_current_state(states)
userInput = input("? ")
if userInput == "b":
states.pop(-1)

if userInput != "q" and userInput != "b":
# states.append(make_move(states[-1], int(userInput)))
# while consise, the above line is hard to read - let's break it out
new_move = make_move(states[-1], int(userInput))
states.append(new_move)

Assignment 2

The second assignment served as an introduction to Object Oriented Programming and Model-View-Controller. Using the teaching staff provided GUI (View) our task was to implement the Model and some of the Controller.

 

class Animal(Organism):
    """
    Animal class. A type of Organism
    Preconditions:  needs a [position (dict), time]
    and name (string) when instantiating it
    """

    def __init__(self, position, name, gender, tracker_id):
        super().__init__(position, name)
        self._gender = gender
        self._tracker_id = tracker_id
        
        self._position = position

    def __str__(self):
        if self._tracker_id is not "":
            return TRACKER_ANIMAL_FORMAT.format(self._name,
                                                self._gender,
                                                self._position[-1][0][0],
                                                self._position[-1][0][1],
                                                time_to_time_string(self._position[-1][1]),
                                                self.get_id(),
                                                self._tracker_id)
        else:
            return BASIC_ANIMAL_FORMAT.format(self._name,
                                              self._gender,
                                              self._position[-1][0][0],
                                              self._position[-1][0][1],
                                              self.get_id())

    def to_dictionary(self):
        d = super().to_dictionary()
        d.update({'type': 'animal', 'tracker_id': self._tracker_id,
                 'gender': self._gender})
        return d

    def get_position(self):
        # print(self._position)
        return self._position[-1][0]

    def add_location(self, position):
        
        self._position.append([position, time.time()])
        
    def get_track(self):
        track = []
        if len(self._position) > 1:
            for i, each in enumerate(self._position):
                track.append(self._position[i][0])

        return track

Assignment 3

The third assignment proved the most difficult, but overall rewarding. It was to build a Python implementation of a breakout-style video game using the native GUI framework, TKInter. The teaching staff provided some helper code to handle collision detection and the math-heavy speed and direction control which was beyond the scope of the exercise.

Screenshot of the Third Assignment

Following is a sample of the code to save the high scores when the player looses or wins.

    def write_high_scores(self):
        """
        writes highscores back to JSON
        :return:
        """
        # print(self._high_scores)
        with open("highscores.json", 'w') as f:
            f.write(json.dumps(self._high_scores, sort_keys=True,
                               indent=4, separators=(',', ':')))

    def get_high_scores(self):
        """
        returns just the highscores - the keys in the dict
        Highscores.get_high_scores(object) -> list
        """
        keyList = []
        # print(list(self._high_scores.keys()))
        for each in list(self._high_scores.keys()):
            keyList.append(int(each))

        if list(self._high_scores.keys()) != []:
            return sorted(keyList, reverse=True)
        else:
            return ["0"]

    def get_lowest_score(self):
        """
        retuns the lowest score as an int
        Highscores.get_lowest_score(object) -> int
        Precondition: assuming the result of get_high_scores is list of ints
        :return:
        """
        return int(self.get_high_scores()[-1])

    def is_score_already_high(self):
        """
        Returns true is score in list
        :return:
        """
        if self._score in self.get_high_scores():
            return True
        else:
            return False

    def add_score(self, score, name):
        """
        adds score to dictionary of highscores
        Highscores.add_score(object, int, str)
        Preconditions self._high_scores can only ever have 6, hopefully
        """
        self._high_scores[score] = name
        if len(self.get_high_scores()) > 5:
            self._high_scores.pop(str(self.get_high_scores()[-1]))

    def name_prompt(self):
        """
        asks for name
        Highscore.name_prompt(object) -> str
        :return:
        """
        name = tk.simpledialog.askstring("You Got a High Score!",
                                         "Enter Your Name: ")
        if name is None or name == "":
            name = "Anon"
        return name

    def show_high_scores(self):
        """
        shows the actual highscores in a dialog
        :return:
        """
        if len(self._high_scores) > 0:
            highscores_string = ""
            for each in self.get_high_scores():
                highscores_string += \
                    HIGHSCORE_FORMAT.format(each, self._high_scores[str(each)])
        else:
            highscores_string = "No scores at all yet. Keep playing!"

        messagebox.showinfo("Highscores", highscores_string)

    def highscores(self, score):
        """
        does highscore stuff
        Preconditions: max length of high scores dict is 5
        :param score:
        :return:
        """
        self._score = score
        # print(self.is_score_already_high(), self.get_lowest_score())
        # score already high - skip following code block
        if not self.is_score_already_high():
            # then check the leaderboard isn't full
            if (len(self._high_scores) == 5 and
                        score > int(self.get_lowest_score()) or
                        (len(self._high_scores) < 5)):
                name = self.name_prompt()
                self.add_score(str(score), name)
                # print(self._high_scores)
                self.write_high_scores()
                # self.show_high_scores()

        self.show_high_scores()
        # print("exiting")