 Welcome back, in the last segment we defined the new marks display problem. In this segment we are going to come up with a program inspired by manual algorithms. So first let us define how the user will communicate with our program, how will the user issue commands. So we can try something simple. So let us say we will use single word codes for each of our commands and then the codes are followed by the arguments for the command. So for example we might have a command which looks like m, roll number, subject code and what this means is tell me the marks obtained by the student with the given roll number in the given subject or instead of the roll number the user may type in the name. So for example the user may type in something like this. So the user may type in m followed by roll number followed by subject code or m followed by name followed by the subject code and likewise we might have a command r followed by roll number which says give me the rank for the student with the given roll number or r followed by name which says give me the rank for the student with the given name and you could have a command just a single letter q which says quit or exit the program. So now let us talk about how we might design the algorithm to respond to such queries and as we have said several times in this course let us start by thinking about how we might solve this problem manually. So after we do that we should consider what is the equivalent of the manual steps on a computer and that will allow us to write the code. While doing this we will also continuously keep in mind that we want the program to be easy to understand and this is something that becomes quite important when you write large or even medium size programs like the one we are going to write. Usually this strategy of manual designing a program by thinking about how you solve the problem manually gives us a reasonable solution but we will try to improve upon what we get as well. So specifically we will ask well can we improve the execution speed and we will also keep in mind that we also want the understandability of the program to be good and so we will think about that as well. So let us think about solving the problem manually first. So suppose the data is given to us in two notebooks instead of two files and what appears in the notebook is say in the first notebook is lines of this form. So roll number followed by name. In the second file we are expecting to see roll number followed by subject code followed by marks so it will contain lines of this form. So these were the lines which were appearing in files but instead of this let us say they appear in notebooks so that we can think of a manual algorithm. So what is the simplest possible solution? Well suppose you want to translate from the name to the roll number we should go through the first notebook to find the roll number if we were given the name. So that is simple enough and then if we are given the marks query that is m followed by roll number or name followed by the subject code well we have to go through the second notebook so which contains lines of this form and we should look for the roll number and the subject being present in the same line and then we should just report the marks. The rank query well we have to find the average of the average marks for each student. What I mean by this is for every student we want to find an average over all the subjects in which the student has marks. So if a student has say 90 marks in physics and 80 marks in mathematics then there will be two lines in the second notebook corresponding to that student. So we have to find those two lines and we have to take the average which in this case is going to be 90 plus 80 or 85. So that is going to be the first step for every student we must look at the subjects he or she has taken and find the average marks obtained by that student. So this is going to be a somewhat involved task then we will have a table so to say of the average marks obtained by every student and then in this table we have to figure out how many students have higher average than the one whose rank we want to know. So that will tell us exactly the rank. So these those were the manual steps. How do we translate the manual steps into computer steps? So what does it mean to say go through the notebooks? Well, nominally it would mean read through the file but usually on a computer our idea is we read the file just once we do not read it repeatedly because reading files is often too slow. So what we do is we read the files and then we put the data into some array or something like that in our computer. So we will read the data from the file into an array or informally we can think of table associated with the array and say we designate an array R and tab to hold all the data from the file Rn file. If you remember Rn file was holding rule number and name data. So we will have an array Rn tab which will have which will consist which will be an array of structures and the first member in the structure will hold the rule number and the second member will hold the name. Then we also have an RSM file which contains lines of the form rule number subject marks. So we will designate an array let us call it RSM tab, tab for table RSM for rule number subject marks and this will be an array of structures each structure containing three data members, rule number, subject and marks. And the subsequent actions that we perform will refer to the arrays rather than the files. So let us think about writing the code since we have a fairly clear understanding of what we are going to do manually. And now when we write the code we have to keep some broad principles in mind. And we have talked about these principles earlier. So basically we would like to represent important entities using structures. So the tables that we defined should really be put into structures. I mean something slightly different than what I said earlier. What I said earlier was that each entry in the table or each element of the array will be a structure. Now I am saying that the entire array should in addition be put in a bigger struct. So that is sort of the general idea that we are going to put important entities inside a struct because the struct kind of encapsulates that entity and we can put member functions now more easily. So we can associate member functions with that entire entity. So RN tab and RSM tab are going to be important entities. So although they contain inside them other structures we will put the whole thing also inside a structure of an appropriate type. So we will see this in a minute. And we will use functions or member functions to represent important actions. The main program should indicate high level program structure. So what I mean by that is the main program should contain function calls which say cause a query, a mark's query to be processed or another function call to process say the rank query. But the main program should not contain details. So the details should be implemented in function calls or member function calls associated with the structures which are holding our important entities. So let us look at the main program first. So the main program should create the major entities. In our case the major entities are the tables. So these should get created by the main program. Then the main program should execute the main loop and the main loop should receive commands from the users and the main loop should execute the commands by invoking the services offered by the major entities. So when I say invoking services I mean just a function call. The main program should not contain details. The details should be in the member function or the function calls. The main program should not be too long and should not contain too much detail. So I said that the main program should create the tables but the creation should really happen in the constructors associated with the entities. So the details of how the tables or how the major entities are constructed should also be hidden and the main program should really contain the high level aspects. Why is this? Well if we put the details in the main program then the high level organization will not become obvious. If you do want to write down the details of course. But we also want to indicate what the high level organization is and therefore we should have the main program sort of spell out the high level organization and from the main program if you want to know the details about something then you just have to follow up that function call or member function call and the details and then the body of the member function call or the function call will tell you how exactly that function is going to be implemented. So next we are going to view the code of main to see how the main program is going to be written to follow these principles. So here is our marks program, marks display program and here is our main program. So the way we are going to organize the main program is that it is going to receive the names of the files as command line arguments. So the first, so the 0th command line argument will be simply dot slash a dot out. And the 1st command line argument following that will be the name of the rm file. So rv is the first command line argument and then the 2nd command line argument rv 2, so rv1 is the first command line argument, rv2 is the 2nd command line argument, and the 2nd command line argument would give the name of the rsm file. Now as we have said earlier, to read the files themselves, we have to associate streams with the files. So we are going to do that and this is how it is done. So we are going to define I of streams for an, we are going to define an I of stream called rn file and this rn file is going to be an I of stream and the actual file will be in this argv1, what the user types in when the program is invoked as the first argument, the one after the zeroth argument and rsm file is going to be the stream which will be used inside the program and this rsm file will get data from argv2 which is the second name, the second file name which is typed in by the user. So the user will type the dot slash a dot out followed by the first file name and then the second file name. Then we said, so then we said that the main program should create the major entities. So the major entities are rntab and rsm tab and rntab if you remember is the table which contains information about role numbers and associated names and for that we need rn file. So the way we initialize this is by calling the constructor for rntab and we pass the file rn file to it. So the details of this we will see soon but notice that over here we are simply calling the constructor and we are supplying to the constructor whatever information is needed in order for that entity to be constructed. So the information needed is the stream associated with that file. So inside that rntab constructor the data will be read from the stream and the table will be created. Similarly the second important entity is this rsm tab, the role number subject marks tab and for this we need the rsm file. So again we are calling the constructor and to that constructor we are passing the stream which is associated with the actual file that the user has typed in on the command name. So that was the first thing we said that the main program should do and then the main program should have a loop. So let us see what this loop is doing. So the loop runs indefinitely until an appropriate command is typed. So let us see that. So we have a string variable command and we will read into that variable. So what do we read? Well we are going to read first the command codes or our command codes were M, Q and R. But if you remember the user can also type in control D to indicate end of the standard input and so what this is saying is that after this reading have you found that CN has ended or was the command Q? So if the command was Q or if the CN had ended then we should just break out and that is how the loop is going to be terminated and we come out of the loop and then the program is itself terminated. Otherwise we check if the command is an M. So if the command is an M then we know that it is a mark query. So if it is a mark query then we are supposed to get in a roll number and a subject name. So this is how we get that. Now here we are simply reading in whatever the user types into the variables roll or name and subject. So if you remember our marks command could be marks followed by name or the roll number followed by subject. So we are just reading in one word into name and the next word into the subject and here we are making a compromise. We are simplifying our problem a little bit. So we are saying here that the name if the user types a name it consists of a single word. Otherwise what we will need to do is we will need to do something else. We will need to read in the entire line and we will need to extract the name and the subject from it. So this is something that can be easily done but as it is our program is reasonably complicated as we will see and therefore we are going to skip this business about reading in names which contain spaces. So I will leave it as an exercise for you to modify this and I will also present the solution for it. So you will eventually get the code for doing this as well but just to keep today's discussion simple we will assume that the name or the roll number that is given to us is just one word. So we get the roll number or name into a single string, we get the subject. So this is where we do it, so from the keyboard and then we will use our table R n tab and we will look up in it to get the roll number if this was a name. So we are going to send whatever it is the roll number or the name to our roll number name table and then we will get a roll number for it. So this roll or name could either be a roll number or name in which case so if it is a roll number then look up has to do nothing it just returns it back. If it is a name then this look up will have to return back the corresponding roll number and then we are going to invoke the look up function this time in RSM tab which will give us the student with the specified roll number in the specified subject and that we are directly going to print out. So that is how this marks query will get processed. If the command was a rank query then the processing is very similar except that there is no subject code needed. So we are just going to get the roll number or name following the R and again we are making this compromise assumption that it is going to be a single word and then we are going to pass that roll number or name and get the roll number as we said if it is already the roll number then we will stay with it and then we will find the rank of this given roll number and then we will print it out. If the first word typed in by the user is neither Q nor M nor R then we are going to print out a message saying that you typed in an invalid command and we will continue the loop but we will give the indication given indication to the user saying that look you printed out you typed in an invalid command. So let us get back to our presentation. So we have looked at the code of main. Next comes the major entity that we created R n tab. So as we said it contains vectors of pairs, roll number and name. So each element is itself going to be a struct and we are going to create this directly from R n file and the construction code is in the constructor not in the main program. The main function of this table is to return the roll number given the name and this is performed by the member function lookup. So what does function lookup do? It returns the roll number if the argument is a valid name. So for this we are just going to look through all the names which are stored in this vector and it is going to return a roll number if the argument is a valid roll number. This is slightly tricky in the sense that the name could either be a roll number or a name and so we are going to have a parameter R or n to indicate this possibility. So let us now look at the code for this entity the struct R n tab. So this is our structure R n tab. So what does it contain? So it is a vector of structures and the vector itself internally is going to be called a tab. So R n tab is the name of the structure which contains this whole thing and in the main program small R n tab will be the name of the actual object. But inside this we will use tab to indicate the actual table which contains the roll number name pairs. So what is the R n structure? Well it is just simply is a roll number name pair. And first we have the construction code over here. So what happens over here? We are simply going to read from this stream R n file which has been passed to the constructor and we are going to read into an R n type object small R n. So we will read in the roll number and we will read in the name and we discussed this earlier. We are going to assume over here that the name is a single word for simplicity. And the multi-word name aspect we will worry about a little bit, we will worry about in the exercise. And let me just point out right now that to get the multi-word names you will have to use get line rather than the input redirection operator. So we are going to get the roll number and if the file ended we then break, we have done the whole thing. Otherwise we get the name and then the name and the roll number are stored in this structure R n. So we just push back this structure at the end of our vector. So we keep reading lines and we construct these R n objects and we keep pushing them on our vector which is tab. So that is how we initialize or we construct this table. Then there is the lookup part. So how does the lookup part work? Here it is sent a roll number or a name and we are going to go through the entire table or the entire vector and we are going to check is the name equal to the roll number. If it is then we return this the corresponding roll number. If the roll number is itself supplied then we just return it. In this we are going through the entire table. When we go through the entire table if we do not return anything then that means this R or n is not found either as the roll number or as the name. So in that case we are going to return the empty string. So that is what this R n tab is and we have seen how it is implemented. So we will take a quick break here before we look at the major data structure which is the RSM tab.