![]() |
.. (לתיקייה המכילה) | |
Could you please explain again what's the difference between a "set" and a "list"? | |
A set and a list are two different ADTs defined by their interfaces.
A list interface should include the following (roughly): add(where, what), get(from where), remove(from where). This means that when you interface with the list, you care about where you put your stuff, i.e. whether your new item will go in its end or a different spot. Since a list doesn't care about the values of the items, you can store several items in a list. For example, a dynamic string (string in which you can insert/remove characters) is a good example for a usage of a list. As its user will care what is in each index, and where does he put his new characters. A set, on the other hand, has the following in its interface (again, narrow for simplicfication): add(what), contains(what), remove(what). A set can only have an item once, and it does not care about "where" you want it. You use a set to just check if something exists (and perhaps retrieve it). Please note, that you can implement a set using a list, and vice versa. However, this will result in longer, less clear and less robust code. We expect you to choose the right ADT for the job in this exercise by considering this. |
Can we change mtm_ex2.h or set.h (or any other file supplied by you)? | |
No. (Aside ileisuredatabase.h which was given as a starting template) |
Should | |
No. Sure, returning a copy sounds safer but it will make the user's life a living hell. For each change on one of the elements in the set he will need to get a copy, remove it, make a change and add it. In addition, the problems which can be caused by the user from mistreatment of his elements is just as probably to occur on the copies he gets. So while in general it's good to copy elements where possible. This is not one of these cases. (And indeed, the set_example_test.c forces you to return the element itself) |
Where should we print error messages to? | |
You should print them to the standard error channel. |
Can we use the list you gave to implement the set? | |
No. |
What should | |
They should return SET_NULL_ARGUMENT . NULL cannot be kept in the set. |
Can the key for | |
Yes. Some filtering conditions do not need extra information and therefore sending a NULL as key should be fine. |
How come | |
A set, unlike a list, does not save an order on its elements even if the iteration over the set is done by some predefined order. To understand this, consider a list, which is an example of an ADT that does keep an order. In a list, when we insert a new element into it, we need to say where we want to put this element in the list - whether we want to add it to the start or the end of the list for example. We can always change our mind and move the element around the list, and the list will remember where asked each element to be put. A set, however, cannot do this. Even if there's some predefined order over its elements the user cannot ask to move the "first" element to be the "last", unlike he could do in a list. |
What is the error code | |
Sorry, it's a leftover from previous versions. You will probably have no use for it, and that is fine. |
Where should the iterator of a set point after creating a new set with | |
It's undefined. (Both the iterator of the original set and the newly created one) (Again: 'undefined' means you can do whatever you wish in this case) |
It seems we're only using | |
You're probably using a set as a list somewhere, i.e. you're using some kind of a "trick" to keep an order which you wouldn't need in a list. |
In out set, can we assume that the user won't change an element in a way that changes the order between elements? | |
Yes. If the user changes the order between element already in the set the behavior is undefined. (This means you can keep the set's linked list sorted if you wish to) |
If two businesses are in the same distance from the user in | |
You can assume this will not happen. (i.e. the order is undefined between two such businesses) |
Should we check for errors in the internal ADTs or in | |
The best solution, is to check in the internal ADTs. As this avoid future bugs when reusing the code or changing it. However, since there's an explicit order of which error to report before which. If you check the errors internally you might still need to add checks in ILeisureDatabase to get the correct order. Because of that, it's acceptable to either check the errors internally and also in ILeisureDatabase (but you do need to avoid duplicating logic when possible) or you can check the errors in ILeisureDatabase and settle for an assert in the internal ADT. In any case, if an error can be checked in the internal ADT and handled this way, you should prefer that option. |
Can we print the error messages directly from | |
No, ILeisureDatabase must return an error code and only the main parsing program may turn that into a message. |
Can we print the reports directly from | |
Yes. The difference from the previous question is that if you have a function with "print" or similar in its name. It's reasonable to have that function print into a stream. But a function that fails in your ADT, shouldn't print by surprise, but tell its caller that it has failed. |
Can we use test_utilities.h in our tests? | |
Yes. In fact you should. list_test.c and test_utilities.h were supplied with the intention that you will copy their style and write similar tests. |
Should we check for NULLs? In all of our ADTs? | |
Yes. You should always check a pointer is not NULL. Even in internal ADTs, this is critical for code readability and reuse later on. If you have a function that does not return an error code, and cannot fail in any way but a user sending it NULL, you may use an assertion. (That is, use the assert macro)In any way, if a user of the ADT sends a NULL, it should not cause a segmentation fault. (The message given by an assert is mush more useful and saves a lot of time on debugging) |
Is it possible for one of our ADTs not to have an result type for reporting errors? | |
Yes, if none of your ADT's functions has errors to report (Aside being sent a NULL) then it's possible. Otherwise, you should have such a type and report the correct error to the ADT's user. |
The error codes order for | |
As stated in the exercise, you should follow the order in the definition of MtmErrorCode in mtm_ex2.h.For example, in the case mentioned above, an error about a non-existing user should be reported if both the user and business are invalid. Please make sure your error reporting conforms to the order in mtm_ex2.h , we will be checking for it.
|
Can we use | |
No, you may not use exit at all.
|
What do you mean by avoiding duplication in the makefile? | |
It means you need to use macros. For example, it should be easy to add a flag to the compilation commands. You do not have to use default rules (as shown on the last makefile slide). |
In the dry part, in the second question. Does | |
Yes, when sending an array of unknown size to a function in C you always need to send its size as well. |