| Bob says: Not my brain. OK I corrected this to be whole number. See new sample page. |
| Bob says: M1 is mainly a chance to use smalltalk on a small part of the big problem you will work on as teams. I purposely tried to simplify it somewhat over the "real" team assignment. I recognize that through automatic reinvestment programs you can buy partial shares and you have to worry over capital gains and dividends. (and whether they are reinvested or payed to a third party) For M1 do not worry about this. For M3-7 you will have to worry over this) |
| Bob says: Man it would help if I could use a calculator. OK cleaned that up to 3100.06. |
| Bob says: No percent sign, should return 5.25. Corrected that in sample code. |
| Bob says: See above comments about limited scope of M1. Good point though and glad to see you are thinking about the domain. |
| Bob says: It is not the TA's fault. It's my fault. I wrote M1 and was supposed to be watching this page. I didn't realize that people would be working on it to this degree already. Sorry. If you don't get answers in a resonable time on the project, email me directly and I will make sure that I respond. |
| I've seen your post but need to talk to the professor about this. I actually recognized the same problem when I reformatted the Milestone's page, so you'll have to wait a bit until I can clear it up. I'll try and repost a better answer on Tuesday. For now, just do it the way it says in the milestone, ok? Chris Verges |
| Bob says: Cascading errors. Thanks, after correcting one error, I failed to check for downstream effects. Thanks. I've corrected the sample code. | |
| The last s balance above is actually incorrect, I just noticed the creditInterest message immmediately preceding the balance message is month not year, thus the interest is not 966, but 80.5 (966/12). I have updated the sample code to reflect the correct totals. Final balance should be 3343.31. |
| Bob says: Kyle, currency is tracked using decimal fixed arithmetic. Money (at least american money) is just decimal fixed where the precision is 2 decimal places. Any decimal arithmetic package will probably suffice. |
| actually... while it is *nice* to know who you're talking to, we have always had a policy in this class of not requiring people to sign their posts. we respect that some people may feel more comfortable asking questions in an anonyous way. see the Statement on Privacy for a longer explanation :) -ellie harmon |
| Bob says: For M1, you do not HAVE to check that these are unique. For the full project M3-M7, you will need to do more input validation to ensure the user doesn't try to create the same account twice and thus get a corrupted financial application. If you want to check that now, it just makes your code more reusable for the later part of the project. |
| Bob says: The output should be a string. When you design the full-up system (M3-7) you can then use this information to display in your GUI or on your reports. If you want to print it to the Transcript, you would use Transcript show: 'Type of account: '; show: s type; cr. |
| Bob says: The requirements say that interest is credited either by day, month or year and gives the appropriate numeric adjustments. It is a design decision about how you do it. In the sample code for M1 I show the method taking a symbol (#day, #month or #year) which represents the interest period to be computed. To me this is more self-documenting than passing .00274, .08333, or 1. Either way will get the same result. We will talk about design tradeoffs pretty soon, but this is obviously a tradeoff between maintainability and efficiency. It takes more internal logic, thus more code, thus longer execution time, to take in the symbols rather than direct numbers – but that faster time is at the cost of some poor maintainer 10 years from now who is trying to figure out what .00274 is supposed to be! |
| If you modify the Number class, then if you merge your code with one of your teammates in the future, you guys will have different pieces of code in fundamental classes... That s not advisable. It is then better to subclass the Number class and add your own modifications in the subclass. Maybe that subclass could be Currency or something like that. Christophe Levand (TA) |
| i think that would be helpful to other students. we certainly would not want you to post code/answers, but i think that links to helpful resources would be acceptable, and appreciated :) also, remember anything on the page is fair game for help with this semester's milestones -ellie harmon |
| Bob says: you may end up selling partial shares based upon the amount. For instance in the sample code, sellAmount:1000 would sell 1000/135.25 or 7.4 shares. I know this is not exactly realistic, but I am trying to keep M1 at least reasonable within its goal of getting you familiar with smalltalk and sunit. Clearly for the full project (M3-M7) there will be more sophisticated rules that will have to be followed. |
| Bob says: 25.5748 is a mistake. It should be 1+29-5=25. 18.0134 is a mistake. It should be 17.6 (25-(1000/135.25)). |
| Bob says: For M1, you can have it to 1 decimal place. I looked over my stock records, and they appear to keep it to 4 places, so M3-7 will probably require increased precision. |
| Bob says: If you do a search on squeak and decimal fixed you find the DecimalFixed.cs changeset you can bring in. It is possible, as someone pointed out, to do the problem without decimal math by some other manipulation mechanisms. If you can do this correctly, then that is also OK. The main thing about proper reuse is to use the smalltalk classes that already exist effectively. |
| Bob says: For M1, you can just buy/sell whole shares. For the full up system (M3-7) you will need to be able to handle partial share manipulation. |
| Bob says: I will defer here to a TA, but I believe they use email, so it is not the problem that you may have experienced in other classes using webwork or workon. |
| Lex Spoon: Actually, we normally use a turnin swiki. You cannot download your submission. The only thing you can do to check it is to press "attachments" and see if the file size is approximately correct. The benefits are that this is simple to operate and that students don't have to keep track of yet another password. Hardly ever does a submission get messed up, and if one does, the TA's are extremely forgiving. |
| Bob says: Not for this milestone. In M3-M7 you will need to design the system so that proper precision is maintained, but how you do this is a design decision. We won't mandate a particular algorithm or technique. |
| Bob Says: Think about how you would know that deposit works and what tests you would do to test all the different input partitions. We could start with a known balance, then do a deposit and check that the new balance is correct. We could try to do an invalid deposit and check that the proper action is taken. |
| Bob says: I mean that's the whole power of subclasses right? We want to factor common behavior and data into super classes. If you find yourself doing a lot of cut and pasting or repetitous coding in an OO language, that should be a warning that maybe something is wrong. We will talk more about this on Thursday when we start design. |
| Bob says, well I think I did answer your question. This is a design class. I am not going to tell you how to design your application. I am going to give you some information about how the program should function. Its up to you to decide the "best" way within the design principles for OO programming. |
| Bob says: Within the constraints of good OO design, you are free to design anyway you want. We recognize there are multiple acceptable answers, not just the one we came up with. On the other hand there are also really bad OO designs (like everything in one class) which are penalized. |
| Bob says: yes. Any method will somehow modify the state of the object or report on the state. It should be possible to check that the state changed to what you expect. This will be more of a problem once you have GUI's involved. One design constraint you have to deal with is making you application testable. |
| Bob says: This is a design decision about how you want your program to operate. Do want it to stop working, or do you want it to print an error message, set the balance to either zero or the current value if it is not nil, etc. Anything not specifically required is left up to you? |
| A single line will do for accessor/modifiers. Chris Verges |
| Yes. Chris Verges |
| I think accessors and modifiers may be passed over for testing. But if those accessors and modifies do anything other than saving/returning, they must be tested. So if your code say tests the input for nil or if the param is a kind of class, then you MUST test it. And now that the question has been posed, we will check for this. :-) Chris Verges |
| Lex Spoon When you run Sunit, it will show a list of methods that had an error. You can even debug into them if you select them from the list |
| Eh, not really, but we won't pass in more than 2 or 3. Chris Verges |
| Lex Spoon: Incidentally, if it was a real financial program, it would have to do its computations in decimal. "10.142" is not the same in Squeak (and most computer languages) as "10142 / 1000". Cobol does it "right" for financial apps, and uses true decimal arithmetic |
| Take a blank image. File in your code. Test it. Does it work? Import whatever else you need. Does it work now? Recurse as necessary. Now take whatever you had to file in and send that to your TA. Chris Verges |
| Bob says: If you look at the sample code for M1, you will see that I modified the 4000 after an earlier post so that it came out to an even number of shares. If you sell by shares, it has to be an integer amount, if you sell to get a specific amount of money, that is where the balance of the account may become a non-integer value (like the 17.6). Again I tried to make M1 easy so you get a feel for smalltalk. Later milestones will deal with a more realistic view of the purchase of stocks. |
| Bob says: You can. In the next milestone, we will introduce transaction histories for each account. In that case, the more error handling you detect now, the less you have to do later. |
| If you've sent a self error: call, you don't have to return anything. Otherwise, return whatever your code needs to handle the error properly. This is a design course, so we try not to place restrictions on how to do things. Chris Verges |
| Their main job is to perform operations, but returning a value may be useful for future extension of the application. Christophe Levand |
| Yes. Chris Verges |
| Bob says: If I understand your question, Yes. |
| Bob says: Yes. Take a look at page 71 of the required text. It involves the creation of an initialization method. |
| Bob says: Yes, as long as they are logically related. You would not want to test selling and buying in the same method, but setting/getting are often done together since they are so closely related. |
| Bob says: I know it seems over the top, but in general everything should be commented. Sometimes an accessor does more than just return an instance variable. Often it has to process collections or perform other calculations or adjustments. Comments make it clear exactly what is happening. Plus as we used to say in pilot training – It develops positive habit transferrence. |
| Bob Says: For future milestones, you will have to worry about where the cash comes from (i.e. trading accounts). For M1, you can assume the money comes from an inexhaustible supply somewhere. |
| Bob Says: It is the balance 3100.06 times the interest rate .0525 (5.25%) |
| Bob says: If you can find a classmate who has successfully installed squeakmap, it puts the .st and .cs files into the image directory, so you should be able to get these files and manually files them in. |
| It is considered better style to give as much information in the error message as possible. Just to put it into perspective, I was using a certain microsoft product the other day and suddenly got a message box saying something like "Critical Error, quitting now." When I pushed ok, the whole machine went into blue screen of death. At that point, I would have appreciated a more explicit error message... |
| Bob says: Because you are subtracting two Float numbers. If you downloaded the decimal class try (365.65 asDecimal:2) - (345.56 asDecimal:2) |
| Bob says: tried this and there appears to be a bug in the asInteger method. I can do 9.54100 and get 954, but if I do the asInteger I get the incorrect answer. I will have to look into this more. You won't be penalized for errors caused by the environment. I need to check more and be sure I fully understand what asInteger is doing. |
| Banks normally use 2 after the main percent. 1.07, 2.35, etc. |
| For future expandibility, returning the calculated amount will make future requirements easier |
| For M1 it doesn't matter 1-4 would be OK. For future applications the standard is 4 decimal places. |
| Yes to all, Clearly you can zero dollars in an account and still be legal. |
| Bob says: For M1, we only require purchase of whole shares. |
| Bob says: For M1, there are 2 ways to sell shares: if we sell shares directly then we only sell whole shares. If we sell to achieve a specific dollar amount, we may have to sell partial shares |
| Bob says: For M1, you can makeup prices, In the real application we will get stock price from the internet via information feeds |
| Bob says: I am not sure you actually want to do it this way. Look at Chris Verges discussion of isKindOf: message on class newsgroup. Basically smalltalk allows you to test the class of an object with the isKindOf: message. This is more powerfull because you check for whether it is an Account class in general (isKindOf: Account) or a more specific type (isKindOf: EquityBond). |
| Bob says: creditInterestTo: message doesn't trigger any money actions, it just tells the object what account should get the interest when it does get credited. The creditInterest message is the one that actually changes the balance. |
| Bob says: For M1, it doesn't matter. If you are thinking ahead to the full application, shares are kept to 4 decimal place precision. |
| Bob says: Yes, that is kind of a bad variable name. Your name is more accurate for its purpose. Even instructors pick bad names sometimes. |
| Bob says: Return values may appear useless in M1, but they will become valuable for future expansion of these classes for the full application |
| Check if the return value of "value" is what you would expect it to be for a given situation. |
| Did you make sure that your new method is a class method and your initialize method is an instance method? Christophe Levand |
| Bob says: There is something strange going on under certain conditions of values in smalltalk. For instance the asInteger method also incorrectly represents certain integer values. You will not be penalized for screwy behavior of the environment, only screwy behavior of your application. |
| - 'name: aString' takes aString as an input argument, whereas 'name' does not take any argument and returns the name in the instance Christophe Levand |
| Bob says: The example code is correct. For M1, you should give an amount and purchase that number of shares. It is also the case for M1 that we assume the amount is always an even number of shares. For later milestones you will need to support buying a certain number of shares (gimme 100 shares of Coke) or an arbitrary number of shares given money (gimme $1000 of Coke). |
| Bob says: Sorry, in trying to make M1 as easy as possible, I lopped off requirements from the full system you will need to build in M3-7. This resulted in a lot more inconsistencies than I had anticipated. I am beginning to think if I had not tried to make M1 easy, I would have in fact made it less difficult to understand! |
| Bob says: creditInterestTo method just tells the object where the intrest payment is supposed to go. creditInterest actually generates the interest. While in real life stocks generate dividends and captial gains, for M1 we are ignoring this |
| Bob says: For M1, assume the three valid entries are day, month or year for the interest period to be calculated. It is up to your design as to how you pass the parameter and what the parameters type is. |
| you turn your work in here: http://coweb.cc.gatech.edu/cs2340turnin since everyone has their own turnin page, you don't need to include your gt number/name in the actual project anywhere :) -ellie harmon |
| The best way is to use the printOut ability of squeak on your class category. In the system browser right click on the category that houses classes for m1. Then select "printOut". If your category was called "m1" then it will create a file in your squeak directory called m1.html. Print that html file out... it's the hardcopy of your source code. -T. Scott Saponas |
| Bob says: For M1, the money just drifts away. We will worry about there the money goes in the later milestones. |
| Bob says: For later milestones we will worry about correct compounding interest calculations. For M1 assume interest is simple interest over either a day, a month or a year. How you pass the parameter to signal the appropriate interval is up to you. |
| Bob says: Think about how an object sends a message to another object. It needs a reference to that object. It then uses that reference to send the message. creditInterestTo: is going to give you the object you need to later reference. Instance variables are a way to save important information about data you will need later. If you save the object reference in an instance variable, then when you creditInterest you will know who to send a deposit message to. |
| Use "self should: [block] raise: Error" for this. There is also self shouldnt:raise: as well. Something like this should be appropriate: "self should: [ aFixedSavings balance: -50. ] raise: Error." Zachary Crowell |