1 '''
2 Created on Aug 26, 2011
3
4 @author: santtu
5 '''
6
8 '''
9 The class C{Excursion} represents excursions
10 that students can sign up for. Each excursion object has
11 a maximum number of "places" for students, a name and
12 a sequence number which indicates if the excursion is
13 a "re-run" of a previous one. An excursion object keeps
14 track of which students have signed up for the
15 excursion. There may be more students signed up for
16 an excursion than there are places, in the hopes that
17 places are freed by cancellations or more places are
18 added to the excursion. Such students are called "reserves".
19 See the method C{sign_up} for more details
20 about the signing up and queuing process.
21 '''
22
23 - def __init__(self, name, number, places):
24 '''
25 Creates a new excursion with the given name, sequence number
26 and number of places. No students are registered yet for
27 the new excursion.
28
29 @param name: the name of the excursion, e.g. "Nokian aula"
30 @param number: the sequence number of the excursion.
31 1 indicates that the excursion is organized for
32 the first time, a higher number indicates a
33 re-run of a previously organized excursion.
34 @param places: the number of students that can take part in
35 the excursion
36 '''
37 self.name = name
38 self.number = number
39 self.places = places
40 self.students = []
41
42
43
45 '''
46 Returns a string description of the excursion's main data. This description
47 is of the form "C{Name #Number (StudentCount/Places)}" where
48 C{StudentCount} is the total number of students who have signed up
49 for the excursion, including reserves. Examples:
50 - C{Nokia #1 (25/50)}- C{Nokia #3 (53/50)}</UL>
51
52 @return: a string description of the excursion
53 '''
54 return self.name + " #" + str(self.number) + " (" + str(len(self.students)) + "/" + str(self.places) + ")"
55
56
57
59 '''
60 Adds more places to the excursion.
61
62 @param increase: a positive number indicating how many more
63 students the excursion can now accommodate
64 '''
65 if increase > 0:
66 self.places += increase
67
68
69
70
72 '''
73 Returns the number of students that can take part in the
74 excursion.
75
76 @return: number of places
77 '''
78 return self.places
79
80
81
83 '''
84 Returns a boolean value indicating if, as matters currently
85 stand, the student will be able to take part
86 in the excursion. That is, a return value of C{True}
87 means that the student will be able to participate if
88 not too many younger students sign up later. A return value
89 of C{False} means that either the given student has not
90 even tried to sign up for the excursion, or that the student is
91 a "reserve" and will not be able to participate unless places are
92 freed due to cancellations or more places are added to the excursion.
93
94 @param student: a student
95 @return: a boolean value indicating the student's queuing status,
96 as described above
97 '''
98 if student not in self.students:
99 return False
100 index = self.students.index(student)
101 return index < self.places
102
103
104
106 '''
107 Determines if the given student is a "reserve", that is,
108 if the student has signed up but currently does not have
109 a place available. If so, determines the position of the
110 student in the queue of reserves. A positive return value
111 indicates the students position: 1 means the first of the
112 reserves (the one who will be the first to get a place if
113 someone cancels), 2 means the next reserve, and so on.
114
115 @param student: a student
116 @return: zero if the student is not a reserve, a positive number
117 indicating the student's position amongst the
118 reserves otherwise.
119 '''
120 if student not in self.students:
121 return 0
122 index = self.students.index(student)
123 if index < self.places:
124 return 0
125 else:
126 return index - self.places + 1
127
128
129
131 '''
132 Signs up the given student for the excursion.
133 If the given student was already signed up for the excursion,
134 nothing needs to be done. Otherwise, the excursion determines
135 the position in which the student is placed amongst other
136 students who have signed up. This is done according
137 to two rules:
138
139 - Younger students (in terms of years studied) always
140 have the preference over older students. That is,
141 a younger student will be able to "cut the line" and
142 get in before older ones.
143 - Of the students with the same year of study, the one
144 that signs up first will have the preference.
145
146 @param new_student: the student who is signing up
147 '''
148 if len(self.students) == 0:
149 self.students.append(new_student)
150 elif self.students[0].is_older_than(new_student):
151 self.students.insert(0, new_student)
152 elif not (new_student in self.students):
153 index = len(self.students)
154 while True:
155 index -= 1
156 current_student = self.students[index]
157 if index < 1 or not current_student.is_older_than(new_student):
158 break
159 self.students.insert(index + 1, new_student)
160
161
162
163
165 '''
166 Cancels the given students registration for the excursion.
167
168 @param student: the cancelling student
169 '''
170 self.students.remove(student)
171
172
173
175 '''
176 Returns a listing of the students who currently have places
177 on the excursion, in order. The listing is prefaced by a generic
178 description of the excursion obtained by calling
179 C{self.get_description()} The rest of the listing consists
180 of lines of the form " - StudentName (YearOfStudy)". E.g.::
181
182 MiniExqu #1 (5/3)
183 - Bob (1)
184 - Adam (1)
185 - Cecilia (3)
186
187 Note that students in reserve are not included in this listing.
188
189 @return: a multi-line participant listing
190 @see: #has_place(Student)
191 @see: Student#get_description()
192 '''
193 listing = self.get_description()
194 index = 0
195 while index < self.places and index < len(self.students):
196 listing += '\n - ' + self.students[index].get_description()
197 index += 1
198
199 return listing
200
201
202
204 '''
205 Returns the students who are in reserve for this excursion. That is,
206 returns a list containing the students who are queuing up in hopes of
207 cancellations or additional available places.
208
209 @return: a list of the reserves, in queueing order (if there are none, an empty list is returned)
210 '''
211 queue = []
212 for index in range(self.get_places(), len(self.students)):
213 queue.append(self.students[index])
214
215 return queue
216
217
218
219 - def redo(self, places):
220 '''
221 Creates and returns a new excursion which is a "re-run" of this
222 excursion. The new excursion has the same name as this one,
223 a sequence number which is higher by one than this one's, and the
224 given number of places available. Furthermore, all this excursion's
225 reserve students are moved (in the same order) to the newly created
226 re-run excursion. ("Moving" means that they are removed from the old
227 excursion and added to the new one.)
228
229 @param places:
230 @return: the new re-run excursion
231 '''
232 rerun = Excursion(self.name, self.number + 1, places)
233 reserves = self.get_reserves()
234 for student in reserves:
235 self.students.remove(student)
236 rerun.students.extend(reserves)
237 return rerun
238
239
240 if __name__ == '__main__':
241 pass
242