SHARE
TWEET

Untitled

a guest Nov 15th, 2017 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package o1.election
  2.  
  3. import scala.collection.mutable.Buffer
  4.  
  5.  
  6. /** The class `District` represents electoral districts (Finnish: ''vaalipiiri'').
  7.   * Each district has a certain number of seats for which a (larger) number of
  8.   * candidates compete in an election. Each district has its own candidates.  
  9.   *
  10.   * A district object is immutable.
  11.   *
  12.   * @param name        the name of the electoral district
  13.   * @param seats       the number of seats (elected positions) available
  14.   * @param candidates  the candidates vying for the seats in the district; there is always at least one candidate per district */
  15. class District(val name: String, val seats: Int, val candidates: Vector[Candidate]) {
  16.  
  17.  
  18.   /** Returns a textual description of the district. The description is of the
  19.     * form `Name: X candidates, Y seats`, where `Name` is the name of the district,
  20.     * and `X` and `Y` the numbers of candidates and seats, respectively.
  21.     * For instance, might return the string `Helsinki: 1064 candidates, 85 seats` */
  22.   override def toString = this.name + ": " + this.candidates.size + " candidates, " + this.seats + " seats"  
  23.  
  24.    
  25.   /** Prints (to the console) a description of each candidate in this district, each on
  26.     * a line of its own. A candidate's description is obtained by calling its `toString` method.
  27.     *
  28.     * NOTE TO STUDENTS: It's not usually a good idea to create "print some of your data"
  29.     * methods ("return some information" methods are better), but we're still making one
  30.     * as an exercise here. More about this in later chapters. */
  31.   def printCandidates() = {
  32.     for (candidate <- this.candidates) {
  33.       println(candidate)
  34.     }
  35.   }  
  36.  
  37.  
  38.   /** Returns all the candidates in this district that belong to the party named by the parameter. */
  39.   def candidatesFrom(party: String) = {
  40.     var fromParty = Buffer[Candidate]()
  41.     for (candidate <- this.candidates) {
  42.       if (candidate.party == party) {
  43.         fromParty += candidate
  44.       }  
  45.     }
  46.     fromParty.toVector
  47.   }
  48.  
  49.  
  50.   /** Returns the top candidate (Finnish: ''√§√§niharava'') of the district. That is, returns the
  51.     * candidate with the highest number of votes. If multiple candidates have the same number of
  52.     * votes, this method chooses one of them arbitrarily. It is assumed that every district always
  53.     * has at least one candidate. */
  54.   def topCandidate = {
  55.     var topSoFar = this.candidates.head
  56.     for (candidate <- this.candidates.tail) {
  57.       if (candidate > topSoFar) {
  58.         topSoFar = candidate
  59.       }
  60.     }
  61.     topSoFar
  62.   }
  63.  
  64.  
  65.   /** Returns the total number of votes received by all the candidates,
  66.     * that is, the total number of votes cast in this district. */
  67.   def totalVotes = this.countVotes(this.candidates)
  68.  
  69.  
  70.   /** Returns the total number of votes received by members of the party named by the parameter. */
  71.   def totalVotes(party: String) = this.countVotes(this.candidatesFrom(party))
  72.  
  73.  
  74.   /** Returns the total number of votes received by the given candidates. */
  75.    def countVotes(candidates: Vector[Candidate]) = {
  76.     var voteCount = 0
  77.     for (candidate <- candidates) {
  78.       voteCount += candidate.votes
  79.     }
  80.     voteCount
  81.   }
  82.  
  83.  
  84.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  85.     *
  86.     * Returns a mapping from parties to their candidates. That is, returns a `Map` whose keys
  87.     * are the names of all the parties that have candidates in this district. For each key,
  88.     * the value is a vector containing the candidates from that party in arbitrary order.
  89.     *
  90.     * @see [[rankingsWithinParties]] */
  91.   def candidatesByParty = { this.candidates.groupBy(_.party)
  92.     //Map[String, Vector[Candidate]]()
  93.   }
  94.  
  95.  
  96.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  97.     *
  98.     * Returns a mapping from parties to their top candidates. That is, returns a `Map` whose
  99.     * keys are the names of all the parties that have candidates in this district. For each
  100.     * key, the value is the candidate from that party with the most votes.
  101.     *
  102.     * If multiple candidates from a single party received the same number of votes, this method
  103.     * chooses one of them arbitrarily. */
  104.   def topCandidatesByParty = { candidatesByParty.mapValues(_.maxBy(_.votes))
  105.   }
  106.  
  107.  
  108.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  109.     *
  110.     * Returns a mapping from parties to their vote totals. That is, returns a `Map` whose keys
  111.     * are the names of all the parties that have candidates in this district. For each key, the
  112.     * value is the number of votes received in total by all the members of that party in this district. */
  113.   def votesByParty:Map[String, Int]  = { candidatesByParty.mapValues(candidate(_.votes))
  114.  
  115.     //Map[String, Int]()
  116.     }
  117.  
  118.  
  119.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  120.     *
  121.     * Returns a mapping from parties to ranking lists of those parties' candidates. That is,
  122.     * returns a `Map` whose keys are the names of all the parties that have candidates in this
  123.     * district. For each key, the value is a vector containing the candidates from that party
  124.     * ''in order by the number of votes they received, starting with the highest''.
  125.     *
  126.     * If multiple candidates from a single party received the same number of votes, this method
  127.     * orders them in an arbitrary way. */
  128.   def rankingsWithinParties = Map[String, Vector[Candidate]]() // this is a non-working dummy implementation; this method will be implemented later
  129.  
  130.  
  131.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  132.     *
  133.     * Returns a vector containing the names of all the parties that have candidates in this
  134.     * district, ordered by the total number of votes received by each party. Descending order
  135.     * is used, so the party with the most votes comes first.
  136.     *
  137.     * If multiple parties received the same number of votes, this method orders them in an arbitrary way. */
  138.   def rankingOfParties = { ???
  139.     //Vector[String]() = { ???
  140.   }
  141.  
  142.  
  143.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  144.     *
  145.     * Returns a mapping of candidates to their distribution figures (Finnish: ''vertailuluku'').
  146.     * That is, returns a `Map` whose keys are all the candidates in this district and whose
  147.     * values are the distribution figures of those candidates.
  148.     *
  149.     * The distribution figure of a candidate is obtained as follows. Take the position (rank) of
  150.     * the candidate in the ranking list within his or her own party (as defined by
  151.     * `rankingsWithinParties`). For instance, the most-voted-for candidate within a party has a
  152.     * rank of 1, the second-most-voted-for has a rank of two, and so on. Divide the total number
  153.     * of votes received by the candidate's party by the candidate's rank, and you have the
  154.     * candidate's distribution figure.
  155.     *
  156.     * If multiple candidates from a single party received the same number of votes, the arbitrary
  157.     * order chosen by `rankingsWithinParties` is used here, despite the fact that this is likely
  158.     * to be a undesirable feature in a real-world system.  
  159.     *
  160.     * @see [[votesByParty]]
  161.     * @see [[rankingsWithinParties]]
  162.     * @see [[electedCandidates]] */
  163.   def distributionFigures = Map[Candidate, Double]() // this is a non-working dummy implementation; this method will be implemented later
  164.  
  165.  
  166.   /** '''NOTE TO STUDENTS: THIS METHOD IS ONLY INTENDED FOR IMPLEMENTATION IN CHAPTER 9.4!'''
  167.     *
  168.     * Returns all the candidates who will be elected on the basis of the vote. The seats available
  169.     * are given to the candidates with the highest distribution figures.
  170.     *
  171.     * If multiple candidates happen to have the same distribution figure, an arbitrary order is used,
  172.     * despite the fact that this is likely to be a undesirable feature in a real-world system.  
  173.     *
  174.     * @return the elected candidates in descending order by distribution figure
  175.     * @see [[distributionFigures]] */
  176.   def electedCandidates = Vector[Candidate]() // this is a non-working dummy implementation; this method will be implemented later
  177.  
  178. }
RAW Paste Data
Top