Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007
Questions on Fall 2003 Milestone 1
Got questions on Fall 2003 Milestone 1? Enter them here.
for everyone with questions about who their ta is, you will find that information here: http://coweb.cc.gatech.edu/cs2340turnin
For fileOut, do we need to overwrite existing files, or can we just open them with fileNamed: ?
fileOut: should save a single copy of the instructions (and name and description). So if the specified file already exists, make sure you don't just append on to it.
So... all we have to do for the second part is make these classes and write the methods specified? It doesn't actually have to function as a full system?
Presuming that by "function as a full system" you mean "actually let the user choose a task to get instructions for and have the system walk him through the instructions, the answer is no, it doesn't have to function as a full system. We'll test your code by creating instances of the classes and making sure that the methods provide the expected functionality.
As a reminder, it will help us learn who you are by linking your "Who's Who" page to you questions, like so:
Since a format for the fileOut was not specified, should our fileIn just read that format (used by our fileOut) or are we expected to read in a set of predefined tasks that the TAs will have? (i ask because if we include the title or description as well as the steps then we'll have to compensate for that when we read in a file)
Your fileIn only has to read the file created by your fileOut; we won't have a stock file that we test everyone's code on. However, as part of saving the instructions you should be saving both the task name and task description. I've modified the Milestone to hopefully make that requirement a little clearer.
The following description seems to imply that none of the strings that will be written will have newline characters. Am I correct in assuming this?
- fileIn: aFileName
- Reads the instructions, including the name and description, in from the specified file as strings with one information item (e.g. instruction) per line.
Jeff Pierce's response:
Excellent question. For now you can safely assume that none of your instructions will have newline characters (you'll be writing the instructions, so you can enforce this). Note that you can write your code to support newlines in your instruction steps; all you have to do is convert the newline characters to something else (e.g. 'XXXX') before saving and convert them back after loading the file.
For milestone 6 you'll be changing your fileIn: / fileOut: code to work with XML, so eventually your code will be able to support more complex instruction formatting.
Nirmal Patel's reply:
Then you just have to worry about 'XXXX' being in the instructions somehow.
Well, yeah, but the goal is to pick something you're fairly sure won't appear, like XYZZY (a reference that hopefully at least someone will get).
Unfortunately, I got it. ;-)
as did I
Once we have compiled our list of 10 tasks, are we supposed to create instances of those in our TaskInstructions class? I guess I'm just a little confused on how we create a list of instructions to test our code with.
Jeff Pierce's response:
You don't have to start creating instructions for tasks until the next milestone (for Milestone 2 we'll have you choose two tasks from a "professor-blessed" list and write instructions for them). However, creating some simple instructions on your own (e.g. How To Open a Door. Step 1: Locate handle. Step 2: Extend hand to grasp handle. etc.) could certainly help you test your code.
1. fileOut: "make sure the file name is valid" What exactly do we need to check for here?
2. In TaskInstructions there is a modifier for the steps collection (so a user could set this to nil). Is is reasonable to check to make sure that the collection class variable is not nil in all neccesary methods (stepAt, fileOut)? Or is stuff like this not needed?
3. contentsWithDescriptions: I am just returning a Set that would look something like this: a Set('Name - Description' 'Name2 - Description'). So, concatinating name with description - reasonable?
4. removeInstructions: has been clarified to actually remove the TaskInstructions...should we still return the TaskInstructions too...or just return the default, self?
5. We have a method called 'steps', and another called 'steps:'. We can't create 'testSteps' and 'testSteps' to test each because they would have the same name. Should we just test accessors/modifers in one test method...or is there some other convention for handling this? In addition - is there a convention for naming the test method for something like stepAt:put:? testStepAtPut?
6. Is it bad to have Transcript show: output in testMethods? I like to watch the test cases run through with debug statements - makes me feel all warm inside. =)
Thanks for the help.
Jeff Pierce's response:
1. The file name is valid if you can create the file.
2. Checking for nil would be a perfectly valid thing to do. For something like stepAt: it's not necessary (we didn't write it into the specification), so like at: it's ok to throw an "index out of bounds" error. However, a method like fileOut: should be able to successfully file out the instructions if steps is nil; the resulting file just won't contain any steps (although it might contain a name and description).
3. You could do it that way (it fits the specification), but keep in mind that for milestone 2 you might want to return both but then access them separately. Concatenating the two means you might have to pull them apart later.
4. removeInstructions: doesn't have to return anything.
5. For accessor methods (like steps and steps:), it's ok to have a single method (testSteps) that tests both. There are no fixed rules for naming the test method for something like stepsAt:Put:, but I would probably call it testStepsAtPut (it'll make it easier for us to figure out what it's testing).
6. It's fine with me.
When I download the Muppet.st file you posted, how do I fileIn so that it appears in my browser? Sorry just don't remember.
See the answer to question 2 at http://minnow.cc.gatech.edu/squeak/946.
That's one way to do it. That approach will save the filed in code in a different change set (which will hopefully make more sense when we talk about change sets 2-3 lectures from now). You can also follow the instructions to open a file list (World Menu -> open... -> file list), select the .st file, and just click the "file in" button that appears in the upper right. That approach should, if I remember correctly, save the code in the current change set for the project you're in.
1- In stepAt: anInteger, what do we need to do if anInteger is bigger than the size of the collection? Return just nil and print an error to the Transcript? Also what if anInteger is a valid index, but that index in the collection has nil in it? Do we just return nil?
2- Since there is now type checking in squeak, do we need to take care of that? For example what if the user passes to the taskName: an integer instead of a String? Or it passes a collection instead of a String?
3- I am having trouble printing to the outFile. Whenever I want to print in a new line, instead of going to the new line this "^M" appears, which I guess that is the string representation of cr? So how do I actually print in a new line?
4- How can I make sure the fileOut is valid? If it is not null after opening it?
5- So the fileIn method should read the contents of the entire file and return just that? Also what do we do when a file is non-existen?
1- Should this class have a collection of TaskInstructions in it? So we can add the instructions to it and do everything else that is asked?
2- For example, in the method contents, I can return whatever I want right? Like a collection of Strings with the names in it?
1. stepAt: should return that step if the instructions. If that step is nil, return nil. If the instructions don't have that many steps, returning nil and printing an error to the Transcript is fine.
2. You don't need to do type-checking for this milestone, although you can.
3. What operating system are you using? ^M's tend to appear along with or instead of newlines when working across OSes, so I'd bet you're using Linux/Unix. Are you getting newlines along with the ^M's, or just the ^M's? And how are you creating your newlines?
4. The fileOut is valid if it rejects invalid names and correctly saves the file when given a valid name.
5. fileIn doesn't have to return anything. It does have to fill the instance of TaskInstructions with the information contained in the file.
1. That's what I'd do.
2. Well, within reason. You can't return the number 5, for example. =) But returning a collection of Strings that are the task names would be fine.
3. I am using Linux. It prints something like:
I tried creating the new lines by using, "String cr", and also, "Character cr". Both gives exactly the same thing. I concatenate that to what I am printing with ",". How do I get around this? Also only the taskName and taskInstruction should be printed right? What about the steps?
Let's say that the Name of the task or the description are not set yet. So if we try to fileOut and error will appear, because the name and description are not initialized. Do we need to take care about this?
Ok, my suspicion is that this is happening because of the different ways OSes handle newlines. Unless Lex or one of our other TAs experienced in Linux Squeaking know of a workaround, we'll accept ^M's in place of newlines provided the file both saves and loads correctly. And fileOut: should output the instructions (which are made up of steps), description, and name.
You do need to handle the case where the name or task aren't set yet.
I am using FileStream, and using nextPutAll to print to the file. It seems that I am doing something wrong and that is why is printing ^M instead of the new lines. Because I went to the states clusters and tried on windows an another wierd character appeared. Something like NameDescription.
This is what I am doing:
aFile := FileStream fileNamed: 'hola.txt'.
aFile nextPutAll: taskName , String cr.
aFile nextPutAll: taskDescription , String cr.
What is the problem then?
Ah, I tried this out and discovered that I get the same phenomenon if I use something stupid to look at the file like Notepad. However, if I look at the file using XEmacs it looks fine. More importantly, the following code appended to yours does what you'd expect:
aFile := FileStream fileNamed: 'hola.txt'.
aFile contentsOfEntireFile. "PrintIt"
Do we need to write test methods for fileIn and fileOut? If yes what functionality should we test for? Thank you!
Yes, you do. You need to test that fileOut and fileIn save and load the file correctly (testing them in a single method might make that easier...), and that they handle the cases where the file name is invalid ("x:\non-existent-directory\instructions") and the specified file does not exist (respectively).
Cross-platform file names.
I am running a Unix system which uses forward slashes for file names. How can I create my Unit texts involving fileIn and fileOut so they will work on both Unix and Windows systems (forward slash / vs backward slash \).
Good question. I'd run your SUnit tests using only local file names (e.g. fileOut: 'SampleInstructions.txt') so that you don't have to specify a full path (if you don't specify a path Squeak puts the files in the current directory).
fileIn: Reads the instructions, including the name and description, in from the specified file as strings with one information item (e.g. instruction) per line. Make sure to handle the case where the file is non-existent.
I just wanted to if we are only allowed to read one line at the time or we cant just read the whole file at once or read one character at the time like the example in the book? I have read the System-Files classes but wasn't that helpfull for reading one line at the time and google was that helpful either.
fileIn: Please disregard my post about fileIn
I'm going to leave it up because other people might be wondering the same thing (and it gives me a chance to reiterate the point). fileIn:, viewed as a black box, should read the entire file and store the contents in the TaskInstructions instance. However, within that black box we don't care if you read the contents all at once, character by character, or through some unique method of your own design.
Since I'm a fan of the uber-coolness that is the regular expression, I was kind of upset to find regex only available as a plugin to Squeak. I'd very much like to be able access these plugin functions, but I was wondering if I was even able to use a plugin with a turnin. What sort of restrictions are there on using external code with our Milestones? Or, is there any way I can automate the install of this plugin for my TA?
Regex Plugin: http://minnow.cc.gatech.edu/squeak/558
You can draw on external code, but you need to make sure that you include that external code when you turnin your code. The simplest way to do this is to turn in both at once using a ChangeSet. You can read up on ChangeSets either in the white book or online, but a simple overview is that they give you a way of bundling up changes (like installing / typing new code) to a project. So you could open a new project, install the plug-in, enter your code, and save the resulting ChangeSet. The TA would then load your ChangeSet and, ideally, everything would work. Of course, it's a good idea to check with a clean image to make sure it does.
1. When writing my fileIn: function I used the example from the 'Exceptions' slides. My problem is, if a file doesn't exist, instead of printing out the exception description to the Transcript, it creates a blank file with the filename being the string passed in (but I wrote it just like the slides example). Any ideas?
2. In the slides it says for every class 'X' make a 'TestX', but in the Milestone 1 instructions it says make 'TaskInstructionsTest'. Which one do you want or will either work?
3. fileIn: says to read the file, which I'm assuming means to the Transcript, so when we SUnit test fileIn, is there a way to test that it printed the correct thing to the Transcript?
1. Trying searching for implementors of fileExists:.
2. Either will work. Calling the class XTest is actually more the convention, but since that mistake slipped into the slides we'll accept either.
3. fileIn: should read the contents of the file and store them in the instance variables of that instance of TaskInstructions; it doesn't have to print the contents to the Transcript or return them to the message sender.
1. What should be the parent class of TaskInstructions and HelpRepository? Does it matter?
2. I went through the instructions in the book on how to create a new class, but it doesn't seem to work. Is there anything I need to do other than running the object subclass template from the system browser?
[Edit: ignore 2nd question, I found my mistake]
3. In the method steps:, is there an actual class called aCollectionOfStrings ? If so, what is it under for me to find the methods associated with it, and if not, how do I know what to use to get the strings out?
1. Making them subclasses of Object is fine.
3. aCollectionOfStrings was meant to communicate that the method should accept an object that is an (ordered) instance of some subclass of Collection and contains 0+ strings. For example
steps: #('Twist' 'Shout')
The messages size and at: should really be all you need to get at contents. Or you could possibly just slap the collection into an instance variable...
What should we be returning if steps isn't initialized? And what should we be returning if the give an invalid integer to access a step? A lot of this seems a bit vague.
And is there some way we can initialized variables to some default values that is acceptable? As i have it now i'm checking for nil every third line jsut about everywhere.
If the TaskInstructions steps aren't initialized, you could return an empty list (e.g. #( )). And I think I gave an answer to a previous question that discussed how you could handle an invalid integer handed to stepAt:.
It's perfectly valid to initalize TaskInstructions instance variables to default values that make sense (e.g. set the name to 'Unnamed', set the description to 'No description available', and set the steps to #()). There was a description on the class newsgroup of how to do this, and the Muppet-Classes.st file on the class schedule page contains example code for the class Muppet.
I am having a lot of trouble checking if a file exists.
This is what I am doing:
aFile := FileStream fileNamed: 'juan.txt'
dFile := FileDirectory new.
dFile fileExists: 'juan.txt'. (returns false)
Why is this returning false?
Something wierd also is that:
dFile pathName. (returns nil)
What is it that I am missing?
FileDirectory new probably isn't the instance creation message you want. Take a look at the CLASS instance creation protocol (category of methods) for FileDirectory. See, for example, FileDirectory default.
For the list of 10 things we wanted to know how to do or had trouble doing, does it have to be stuff we learned doing this milestone or can it be things like "I would like to know how to grab data from the web using Squeak"?
Things you'd like to learn how to do (e.g. grab a picture from the web, retrieve and parse HTML from the web) are perfectly fine.
Link to this Page