You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: source/exercises/list_lab.rst
+12-15Lines changed: 12 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,9 +29,9 @@ to query the user for info at the command line, you use:
29
29
Procedure
30
30
---------
31
31
32
-
In your student dir in the class repo, create a ``lesson03`` dir and put in a new ``list_lab.py`` file.
32
+
In the github classroom repo for this exercise, you will find a``list_lab.py`` file (if it not there, you can create it and add it to git yourself).
33
33
34
-
The file should be an executable Python script. That is to say that one
34
+
The file should be made an executable Python script. That is to say that one
35
35
should be able to run the script directly like so:
36
36
37
37
.. code-block:: bash
@@ -50,11 +50,11 @@ should be able to run the script directly like so:
50
50
51
51
The file will also need this on the first line::
52
52
53
-
#!/usr/bin/env python3
53
+
#!/usr/bin/env python
54
54
55
-
This is known as the "she-bang" line -- it tells the shell how to execute that file -- in this case, with ``python3``
55
+
This is known as the "she-bang" line -- it tells the shell how to execute that file -- in this case, with ``python``
56
56
57
-
NOTE: on Windows, there is a python launcher which, if everything is configured correctly will look at that line to know you want python3 if there is more than one python on your system.
57
+
NOTE: on Windows, there is a python launcher which, if everything is configured correctly will look at that line to know you want python if there is more than one python on your system.
58
58
59
59
If this doesn't work on Windows, just run the file some other way:
60
60
@@ -63,14 +63,11 @@ If this doesn't work on Windows, just run the file some other way:
63
63
- from your IDE or editor is you are using one
64
64
65
65
66
-
Add the file to your clone of the repository and commit changes frequently
66
+
Make sure the file is added to your clone of the repository and commit changes frequently
67
67
while working on the following tasks. When you are done, push your changes to
68
-
GitHub and issue a pull request.
68
+
GitHub and issue a pull request to let the instructors know it is ready for review.
69
69
70
-
(if you are still struggling with git -- just write the code for now).
71
-
72
-
When the script is run, it should accomplish the following four series of
73
-
actions:
70
+
When the script is run, it should accomplish the following four series of actions:
74
71
75
72
Series 1
76
73
--------
@@ -79,8 +76,8 @@ Series 1
79
76
- Display the list (plain old ``print()`` is fine...).
80
77
- Ask the user for another fruit and add it to the end of the list.
81
78
- Display the list.
82
-
- Ask the user for a number and display the number back to the user and the
83
-
fruit corresponding to that number (on a 1-is-first basis). Remember that Python uses zero-based indexing, so you will need to correct.
79
+
- Ask the user for a number and display the number back to the user
80
+
and the fruit corresponding to that number (on a 1-is-first basis). Remember that Python uses zero-based indexing, so you will need to correct for that.
84
81
- Add another fruit to the beginning of the list using "+" and display the
85
82
list.
86
83
- Add another fruit to the beginning of the list using ``insert()`` and display the list.
@@ -105,8 +102,8 @@ Again, using the list from series 1:
105
102
106
103
- Ask the user for input displaying a line like "Do you like apples?" for each fruit in the list (making the fruit all lowercase).
107
104
- For each "no", delete that fruit from the list.
108
-
- For any answer that is not "yes" or "no", prompt the user to answer with one
109
-
of those two values (a while loop is good here)
105
+
- For any answer that is not "yes" or "no", prompt the user to answer
106
+
with one of those two values (a while loop is good here)
Copy file name to clipboardExpand all lines: source/exercises/mailroom/mailroom-oo.rst
+51-31Lines changed: 51 additions & 31 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,9 +8,7 @@ Making Mailroom Object Oriented.
8
8
9
9
**Goal:** Refactor the mailroom program using classes to help organize the code.
10
10
11
-
The functionality is the same as the earlier mailroom:
12
-
13
-
:ref:`exercise_mailroom_part1`
11
+
The functionality is the same as the earlier mailroom(s).
14
12
15
13
But this time, we want to use an OO approach to better structure the code to make it more extensible.
16
14
@@ -32,6 +30,9 @@ As you design appropriate classes, keep in mind these three guidelines for good
32
30
33
31
There should be no use of the ``input()`` function in the classes that hold the data! Nor any use of ``print()`` -- these are for user interaction, and you want the data handling code to be potentially usable with totally different user interaction -- such as a desktop GUI or Web interface.
34
32
33
+
In the spirit of separation of concerns, you also want keep your Command Line Interface code in a separate file(s), as they already should be in your mailroom-as-a-package version. In fact, you should be able to keep the structure of your package pretty much the same -- simply replacing the model code with classes.
34
+
35
+
35
36
3) As always: **DRY** (Don't Repeat Yourself): Anywhere you see repeated code; refactor it!
36
37
37
38
@@ -52,34 +53,47 @@ For this simple problem, simple tuples could work fine. However, in order for th
52
53
53
54
So now you have to think about using a dict or class. Again for flexibility, a dict is a bit easier; you can add fields to it very easily. However, with a class, you can build some functionality in there, too. This is where encapsulation comes in. For instance, one thing you might want to do is get the total of all donations a donor has made in the past. If you add a method to compute that (or a property!), then the rest of the code doesn't need to know how the donations are stored.
54
55
55
-
Consider ``data[0]`` vs ``data["name"]`` vs ``data.name``. Which one is more readable? Keep in mind that another benefit of using OO for data encapsulation is ability of modern IDEs to provide auto-completion, which reduces the number of bugs and helps to produce code faster.
56
+
Consider ``data[0]`` (stored in a tuple) vs ``data["name"]`` (stored in a dict) vs ``data.name`` (a class).
57
+
Which one is more readable?
58
+
Keep in mind that another benefit of using OO for data encapsulation is ability of modern IDEs to provide auto-completion, which reduces the number of bugs and helps to produce code faster.
59
+
60
+
Another way to think about it is "data" vs "code" -- dicts are for data, classes are for code.
61
+
Sometimes it's not totally clear which is which, but if you think about how static is, that can be be a guide.
62
+
In this example, every donor is going to have a name, and a donation history, and maybe in the future a bunch of other information (address, email, phone number ....).
63
+
Whatever it is, every donor will have the same set -- so it's good to use code to manage it.
56
64
57
65
Below are more detailed suggestions on breaking down your existing code into multiple modules that will be part of a single mailroom program.
58
66
59
67
60
68
Modules and Classes
61
69
...................
62
70
63
-
You may organize your code to your preference and keep it simple by having all of the code in a single file.
71
+
You may organize your code to your preference and keep it simple by having all of the model code in a single file. But you should at least separate the code that manipulates data (the "model" code) from the command line interface code, as you did for mailroom-as-a-package.
64
72
65
-
Optionally, you could organize your code into modules, which helps to keep code organized and re-usable.
73
+
Optionally, you could further organize your model code into separate modules: maybe one for the Donor object, one for the DonorCollection object.
66
74
67
75
What is a module? A module is a python file with a collection of code that can be imported into other python files.
68
76
69
77
Modules can contain functions, classes, and even variables (constants).
70
78
71
-
Here is an example file structure for ``mailroom_oo`` package that contains 3 modules:
79
+
Here is an example file structure for ``mailroom_oo`` package -- it should be similar to what you already have:
72
80
73
-
.. code-block:: bash
81
+
::
74
82
75
-
└── mailroom_oo
76
-
├── cli_main.py
77
-
├── donor_models.py
78
-
└── test_mailroom_oo.py
83
+
└── mailroom
84
+
├── __init__.py
85
+
├── cli.py
86
+
├── model.py
87
+
└── tests
88
+
├── __init__.py
89
+
├── test_cli.py
90
+
└── test_model.py
79
91
80
-
The module ``donor_models.py`` can contain the ``Donor`` and ``DonorCollection`` classes.
81
92
82
-
The module ``cli_main.py`` would include all of your user interaction functions and main program flow.
93
+
The module ``model.py`` can contain the ``Donor`` and ``DonorCollection`` classes.
94
+
95
+
The module ``cli.py`` would include all of your user interaction functions and main program flow (and a ``main()`` function that can be called to start up the program (and used as an entry_point).
96
+
83
97
84
98
``Donor`` Class
85
99
...............
@@ -117,25 +131,25 @@ This design allows you to quickly look up donor by their name and get a donor ob
117
131
118
132
Another option is to simply use a list of donor objects. You get to choose which you think is more appropriate.
119
133
120
-
Remember that you should use `self.donors` attribute any time you want to work with data about a single donor, most of your methods in this class will utilize it in some way. This is really what classes are desined for.
134
+
Remember that you should use `self.donors` attribute in any methods that need access the individual donors. Most of your methods in this class will utilize it in some way. This is really what classes are designed for.
135
+
136
+
Note that external code probably shouldn't access the ``.donors`` list (or dict, or ...) directly but rather ask the DonorCollection class for the information it needs: e.g. if you need to add a new donation to a particular donor, calla method like ``find_donor()`` to get the donor you want, and then work with that Donor object directly.
121
137
122
138
**Examples:**
123
139
124
140
Generating a thank you letter to a donor only requires knowledge of that one donor -- so that code belongs in the ``Donor`` class.
125
141
126
142
Generating a report about all the donors requires knowledge of all the donors, so that code belongs in the ``DonorCollection`` class.
127
143
128
-
Hint:
129
-
You've previously sorted simple data structures like list and dictionaries, but here we're dealing with objects - not to worry that is a really simple thing to do with python!
130
-
You can use `operator.attrgetter` with a sorted function (review python docs for usage documentation).
144
+
.. note:: You've previously sorted simple data structures like list and dictionaries, but here we're dealing with objects -- not to worry, that is a really simple thing to do with python! You can use ``operator.attrgetter`` with the ``sorted`` function (review the python docs for usage documentation) to make it easy to sort based on various attributes of a Donor.
145
+
131
146
132
147
Command Line Interface
133
148
.......................
134
149
135
150
**Module responsible for main program flow (CLI - Command Line Interface)**
136
151
137
-
Let's call this module ``cli_main.py`` to represent the entry point for the mailroom program.
138
-
This module will be using the classes we defined: ``Donor`` and ``DonorCollection``.
152
+
Let's call this module ``cli.py``. This module will be using the classes we defined: ``Donor`` and ``DonorCollection``.
139
153
It will also handle interaction with the user via the ``input`` function calls that gather user input and to provide the output to the console.
140
154
141
155
What should go into this module?
@@ -152,6 +166,10 @@ The idea here is that we should be able to fairly easy replace this CLI program
152
166
such as a GUI (Graphical User Interface), without having to make any changes to our data classes.
153
167
If that was the case, then you would implement the GUI elements and use your data classes the same way as they are used in CLI.
154
168
169
+
Note that this arrangement is a one-way street: the CLI code will need to know about the Donor and DonorCollection classes, but the model code shouldn't need to know anything about the CLI code: it manages the information, and returns what's asked for (like a donor letter or report), but it doesn't know what is done with that information.
170
+
171
+
In short: the cli.py module will import the model module, but the model module shouldn't import the cli module.
172
+
155
173
156
174
Test-Driven Development
157
175
-----------------------
@@ -170,15 +188,15 @@ That is, rather than take a non-OO function and try to make it a method of a cla
170
188
171
189
You should expect to re-use a lot of the command line interface code, while refactoring most of the logic code.
172
190
173
-
If you are not sure at the start what functionality you data classes will need, you can start with the CLI code, and as you find the need for a function, add it to your data classes (after writing a test first, of course).
191
+
If you are not sure at the start what functionality you data classes will need, you can start with the CLI code, and as you find the need for a function, add it to your model classes (after writing a test first, of course).
174
192
175
193
176
194
Exercise Guidelines
177
195
===================
178
196
179
-
OO mailroom is the final project for the class.
197
+
OO mailroom is the final step in the mailroom project. And you are near the end of the class.
180
198
181
-
So this is your chance to really do things "right". Strive to make this code as good, by every definition, as you can.
199
+
So this is your chance to really do things "right". Strive to make this code as good, by every definition, as you can. If you have gotten feedback from your instructors, now is the chance to incorporate recommended changes.
182
200
183
201
With that in mind:
184
202
@@ -209,9 +227,9 @@ Functionality
209
227
210
228
- You should be able to re-use all the logic code with a different UI -- Web App, GUI, etc.
211
229
212
-
- There should be no ``input()`` or ``print`` functions in the logic code.
230
+
- There should be no ``input()`` or ``print()`` functions in the logic code.
213
231
214
-
- The logic code should be 100% testable (without mocking input() or any fancy stuff like that)
232
+
- The logic code should be 100% testable (without mocking ``input()`` or any fancy stuff like that)
215
233
216
234
.. rubric:: Testing
217
235
@@ -231,23 +249,25 @@ Functionality
231
249
.. rubric:: The "soft" stuff:
232
250
233
251
Style:
234
-
- conform to PEP8! (or another consistent style)
235
-
236
-
- You can use 95 or some other reasonable number for line length
252
+
- Conform to PEP8! (or another consistent style)
253
+
(You can use 95 char or some other reasonable number for line length)
237
254
238
255
Docstrings:
239
256
Functions and classes should all have good docstrings. They can be very short if the function does something simple.
240
257
241
258
Naming:
242
259
All classes, functions, methods, attributes, variables should have appropriate names: meaningful, but not too detailed.
243
260
261
+
244
262
Extra Ideas:
245
263
------------
246
264
247
265
In case you are bored -- what features can you add?
248
266
249
-
* How about an html report using your html_render code?
250
-
251
267
* Fancier reporting
252
268
253
-
* The sky's the limit
269
+
* More error checking -- does the user really want to create a new donor? or was it a typo in the donor name?
270
+
271
+
* The next project is an html renderer -- maybe use it to make a nice html report?
Copy file name to clipboardExpand all lines: source/topics/01-setting_up/git_workflow.rst
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,7 @@
1
1
:orphan:
2
2
3
3
.. NOTE: This is the "old" version, before we adopted gitHub Classroom
4
+
.. It is not currently published.
4
5
5
6
.. _git_workflow:
6
7
@@ -9,7 +10,7 @@ git Workflow
9
10
10
11
Git is a very flexible system that can be used in a lot of different ways to manage code development. This page describes the workflow we are using for this class -- about as simple a workflow as you can have with git.
11
12
12
-
We start with an overview of the usual process. This overview may be all you need for future work, once you have created your home directory within the students directory.
13
+
We start with an overview of the usual process. This overview may be all you need for future work, once you have set up git on your workstation.
13
14
14
15
The instructions following the overview are very explicit for those new to git and the command line.
15
16
@@ -18,6 +19,7 @@ The usual process
18
19
19
20
This is the usual series of steps you will want to go through when you do a new project / assignment.
20
21
22
+
21
23
First make sure you are on the command line "in" your copy of the class repo.
22
24
23
25
Remember that ``git status`` is your friend -- when in doubt, run that command to see what's going on in your repo.
0 commit comments