 So, good morning everybody and welcome back. A very similar description about scanf function is available also on the open source book. So, I will just pass these, I have included these slides for the sake of completeness and for as for indicating how exactly one might want to expose our students to the details of scanf and printf. So, scanf for example, the contents of the format string for input would be these wide space ordinary character conversion specification and so on. What is most important about scanf is that when scanf reads a stream of characters on your input, it actually identifies values and it completely ignores wide spaces between values. What is a wide space? A blank is a wide space or tab is a wide space. So, for example, if you have a new line character that means the line ends and some input value comes on the next slide. These wide spaces are actually ignored. Yesterday somebody was asking me about the EOF whether what is the ASCII code for EOF. As I mentioned EOF is not an ASCII code. So, if you are typing your values to indicate end of file that means to indicate to scanf that there is no more input available, you actually press control D on your terminal. That means end of input in a unique environment. However, if you want to insert control D as a value as a character for example, in a character string, you have to escape it appropriately. Such nuances not perhaps at the beginning time of the subject teaching, but somewhere in between should be told to our students. More importantly, there are other functions than scanf and printf. So, that is why scanf and printf are not called just functions, but family of functions. Get care and put care or get see and put see are such functions. These functions read one character at a time and print one character at a time. Consequently there is no formatting per se is associated with these functions because they print one character. We have to make sure what character is to be printed in order to use it for a put care. Similarly, since it reads get care, reads one character except for EOF, it will read every character whether it is white space or not and it is up to us to decide as to what to do with that character. So, we can test for that character, we can take actions based on that value, we can wait for input end and look for specific values. In short, we can be far more flexible in analyzing the input characters as they come from a stream or we can be far more flexible in deciding how we want to put our output doing an internal formatting if necessary and putting out characters one at a time. In general, however get care and put care are almost always associated with reading character strings and printing character strings or reading individual characters and printing individual characters. In so far as other numerical values are concerned whether integer, real that is floating point, double etcetera. Invariably, we would use formatted input output. To illustrate the use of this get care function, here is an example. This example declares a CH as int and then allocates to CH a character rate from the input stream by get care function. Here is an interesting thing that we should tell our students pretty early in life. Ordinarily, we would have declared CH as care, but we have declared it as an int. With get care actually the value that you get is always allocated to an integer variable and that is why CH is int. In fact, C language uses integer and character almost indistinguishably. If at all there is a distinction, the distinction is that if you have declared a care variable as CH, then generally it will contain an ASCII code of a value. Whereas an integer being a much larger value container can contain things even outside the ASCII code and that is the importance. However, for all practical purposes an integer is converted to character and a character is converted to integer almost automatically and implicitly in most cases in C programming language. Since ASCII code are nothing but internal numbers, if we put an integer value and output that value what goes out actually is a equivalent character whose ASCII code is equal to that value. Here is an example of what is being done here. If you see here, here is a loop while CH not equal to small a, then do the following. What is being done? If CH is not equal to new line character, print CH was %C value %D backslash n, CH, CH. What does it mean? I am printing CH twice, but notice that first time I am printing it as %C because this is the first format specifier. Please note that CH is an integer value and it can be legally and properly printed as a character. All that she does is it converts it into an appropriate ASCII code or rather interprets it as an appropriate ASCII code and prints it out. The second CH is printed as a numerical value. In short, if this print of statement is executed you will get a character printed and you will get its ASCII value printed. When will this be executed? As long as CH is not equal to new line, if CH is equal to new line you are coming out here and you are looking at the next gate. What this program will do is keep reading characters and keep printing those characters. It will not print a backslash n. That means if you type a new line it will ignore that. It will keep printing otherwise all characters it will not print except when you input a character A. If you input a character A then this while loop will break. Notice that the first character itself if it is A you will print nothing and come out because this while initially will not be satisfied and you will come out. Now this loop will print all characters till it finds an A and after that you keep going even if you find an A it will not print it but it will get another character go back again. Check if it is not equal to A it will print it. If it is A again it will skip this while again it will take the next character. Is it an infinite loop? Technically yes. However because it is an infinite loop built around a gate care any time you type an EOF how do you type an EOF? You press control D on your terminal which is interpreted as an EOF. Notice that what is being taken in is not a character really but an integer value. As we explained in answer to the previous question an integer value other than 0 to 255 which is the possible ASCII code of a character is what is sent to the computer whenever you press a control D on your keyboard. So EOF therefore I repeat EOF does not have an ASCII code. Actually there is an ASCII code called control D but if you want to insert control D into some array or something you have to escape it and send it. Ordinarily you have a mechanism of sending EOF which is other than ASCII code and the moment that EOF is detected the whole program stops any which way because there is no input to update. Here is another example dealing with character arrays. This shows you remember I told you that apart from standard input output library which is included when you say include STDIO.H there is another library which has extremely powerful and useful functions dealing with character strings and these functions are all part of string dot H. I had listed some of these functions earlier. A larger description and comprehensive description is available both on web and in standard library definition. So there are books on standard libraries and there are of course internet resources. What this program does is very interesting. It defines two arrays first name and last name. Then it defines an array called full name and assigns a constant value to it. Notice that this is the only place where a regular string as we know it enclosed in double quote marks can be assigned to an array. Ordinarily this assignment would not make any sense because a character array cannot be assigned values. It is not treated as a string. It is artificially interpreted as a string which is null terminated string etc. But either you have to take responsibility that you put some characters in a character array then you put a backslash null yourself or alternately you let some input operation put that backslash null. But otherwise there is no way of assigning a string to a particular character array ordinarily. This is the only exception at the time of definition because this is treated as an initial fixed value. So this value is fixed it is known and that is being assigned to an array called full name. Observe that this name itself is very short really. However this is a care that you must advise your students to take namely names of people, names of subjects in a course, names of whatever should ordinarily be long enough that means the array bound should be long enough so that no overflow occurs and proper name can be contained within the declared arrays. In this context it would be useful to remind our students that array bounds are not checked. So unless we are very careful we may actually overstep the array limits and try to push a larger string into a smaller place. So that is why you will notice that first name and last name are individually 30 characters long which is 29 characters long actually because one character is left in backslash 0 whereas the full name is 39 characters long. This is to ensure that either the first name or the last name could be longer. In fact it is not uncommon in some cases to have a single name. So there is no first name there is only last name or there is only first name there is no last name there is only one name basically. Anyway what does this program illustrate? This program first of all assigns this constant to the string to ensure that this assignment actually works there is a print statement name is percent s full name this is a string without any bit specification. So whatever is the actual string will be printed please note that full name is an array. So what it represents is the index to the first character and the printf statement is capable of going through successive characters in this array determine when backslash 0 comes which would have been inserted by the assignment statement and once the backslash 0 comes it knows that the string has ended so that is what it will print. In short it will print none law blank SARA. There is another useful function in string.h called s length. So I define s length as an integer variable and assign it as a value str length full name. Notice that full name has already been assigned a value and therefore length of this string should automatically be calculated by this str length function and that value should be assigned to s length or string length. Can we make an assignment to full name other than none law SARDA? Here is an example which has been subsequently commented full name equal to some other SARDA. If you actually try it in your program since this assignment is not permitted you will get a compilation error. To indicate to our students I thought it may not be a bad idea to include this as command a multi-line command saying please don't do such stupid thing it will not work. However suppose now I want to separate out this full name none law SARDA into two names first name as none law last name as SARDA. What are the different ways of doing it? This is illustrated by this small sample program here. First I look at all positions of that array starting from the first position. I note that the first name and last name are separated out by blank. In this particular case there is one blank but there could be more blanks. However we consider a situation where the names are separated out by single blank. In this case I put a file loop and I look for a blank. So I set in pos equal to 0 and while posth position of full name is not equal to blank I do the following. I take that character and put it in first name. This is obvious. For example let's go back to the previous slide. The name in the full name is none law SARDA. The first character is a blank no. So this qualifies to be the first character of first name. This would be the second character of second name. So I will keep transferring all these characters into first name till I come to the space. When I come to the space I have finished the collection of first name and therefore if I go to the next slide you will find what it does is that within the iteration it keeps allocating this name keeps incrementing position keeps looking at the next position whether that is blank and so on and when it finds a blank at that time the pointer pos is pointing to a blank. So that means pos minus 1 is the position of the last value character of the first name and therefore the position at pos should be filled up with backslash 0 for the first name which is what is done here. So first name pos is set to backslash 0. Just to verify we print the first name as first name and we print the length of the string as S length for the original string and we also print at the end the first name and this was one way of finding out the first name. Here there is a problem. The problem is that suppose there is only one name. There is no first name and last name there is only one name and that name happens to be such that in that line you do not have any blank at all. This particular program segment will continue looking at pos almost indefinite and it will therefore exceed the length of the full name string. That should not be permitted. That is why I have said that perhaps a better way of doing this is to define an integer variable i and look at i from 0 to S length. Remember S length is returned at the length of the character string by the previous statement. Please note that if the character string actually contains 15 characters 16th position will be backslash 0 but S length will return you 15 the correct length of the string. Not 16th position but position 15 will be backslash 0 because it starts with 0 anyway. What does this segment do? It does the same thing. It checks if ith position of full name is a blank. If it is not a blank it will take the ith position of full name and put it into first name and it will continue doing exactly what we were doing previously. However, if I exceeds S length then this full loop will break. On the other hand if I find a blank which will happen if the ith statement gets executed then I know that ith position there is a blank so I insert the backslash 0 in the first name and this break statement will get me out of this full loop. When I come out of this full loop I will print the name which is the first name. Notice here that because I would have inserted a backslash 0 the first name would be printed exactly as the first name is the subsequent blanks etc won't be printed and the length of the first name is also printed for good measure. So I will have two lengths first length of the full name and the second length of the first name. Here is a sample output of the program which I have included again in the same file which contains the program. So the name is Nanlal Sardar first name is Nanlal length of string is 13 name is Nanlal this is the second method of finding out the name it gets both but you try giving to this program an input which contains only one name and does not have a blank till the very end or it contains a very long first name you will find the program will break down. Here the length of name is 7 means length of first name and you will notice that Nanlal has actually 7 characters. So this is a simple example which can be used to illustrate to our students both the use of scan f print f in the normal circumstances and the use of gate care in the special circumstances when you are dealing with character strings. It also illustrates the use of several the powerful functions which permit us to handle strings. String handling by the way is required very extensively and therefore those functions are used very extensively. In today's lab in the afternoon you will be trying to solve a problem which will sort of help you try and use many of these programs many of these functions which handle strings effectively. What I want to discuss in the remaining time up to the T break is A the lab assignment today and in that context what kind of things we should be doing. This lab assignment is about character string handling. I will also use this opportunity to introduce all of you to a different programming paradigm a modern programming paradigm which can be used to solve the problem that I am describing. I will tell you the purpose in describing that it is called AUK programming language but we shall see that in a due course. Consider this problem. I actually had this problem last semester when I taught a CS 101 in IIT Bombay as I told you I had more than 810 or 820 students in my course and they were distributed in various divisions and the mid semester papers were corrected by different teaching assistants. All that they did is they put all these marks and other information in a spreadsheet. Now you know the regular spreadsheet most of you would be familiar with Microsoft spreadsheet. The Microsoft spreadsheet typically will have a serial number and various other fields. In the spreadsheet the fields would not look like this but what we did is after entering the data and I will describe to you shortly what the data was we wanted to analyze this data. So instead of using it in spreadsheet we said convert that into a text file and let us write C programs to analyze this data. So we actually use C++ program, whatever. Now how does that data look like? Many of you are familiar with Microsoft Excel or for that matter any other spreadsheet will know that data in a spreadsheet can be exported in terms of a file which can have different formats. One of the formats is called CSV or comma-separated values. So what we did is we converted the data into a comma-separated value. We could also have converted into a blank-separated value which would have been more natural. Why don't we do that? Well, very obvious. Look at some of these names which appear here Guru Rao Shaileshwar or Rawal Namit Lalit or Shailendra Sraaf. Now these names themselves have blanks in between. So if I separate out all the data that I get I will get multiple fields. Instead of a single name I will get sort of three different distinct values separated by blanks. And notice that scanf and such other functions have a problem with blank. The moment the blank comes they assume one value as ended. Consequently, ordinarily there is no mechanism for me to read Rawal, blank, Namit, blank, Lalit as a single string in my program. I have to do some Godagari to do that work. And that is the reason why I choose to include an additional symbol which is a comma in this case. Note that when I put the values in excel sheet a comma doesn't exist inside an excel sheet. Different cells of the excel sheet will contain different values. Let us first see what are these values. The first value is a artificial serial number. This serial number by the way is generated by spreadsheet itself. So I add some 820, 500, these are sample things. I add some 810 or 820, I don't remember number of stores. So what is the data that we have? First we have a raw number. Then we have the name. After the name we have the batch code. This batch code is based on our own internal distribution of people and the batch codes are 0A, 0B, 0C, 0D, 1A, 1B, 1C, 1D, etc. Right up to 9A, 9B, 9C, 9D. So there are 40 batches that I had. Roughly of 20 students each some less some more. And the last value is actually marks in the mid-semester. These marks are by the way out of 45. We are curiously a 45 mark mid-semester not 50 or something. Because the percentage was only 15 percent and it would have been easier to divide this value by 3 and get the thing. Whatever be the reason, they are marks out of 45. But there were complications. When we look at the spreadsheet, not all cells within the spreadsheet would have been filled out. For example, somebody's batch is not known. Then look at this cell in the sheriff. There should have been a value here like 8D or 7A. But there is no batch. It was blank. So what does spreadsheet do when it converts data into a comma-separated form? It just put two consecutive commas. Somebody's name itself has not been entered. Of course the mistake of the teaching assistant was handling that batch. But that means instead of name, I will have two consecutive commas. Somebody has not appeared in the test. Now not appeared is very dangerous. Not appeared if I have a blank instead of a numerical value, I have a problem in my computation. So the instructions were that people who did not appear, they should be given negative marks. We did not have negative marking in the test. So any mark which is 0 or more was considered a present student and any negative mark meant that the student was not present. This was our data and we got this data converted into a CSV format or comma-separated value form. Now here is the challenge. We have to find not only average marks for the whole class. That is relatively easier. You just read the last value, ignore the negatives, add up all the total values, count the total number of students who are present, divide one by the other, you get a class-wise total. We wanted a batch-wise total. There is a reason for that. The batches here are not assigned as per increasing, decreasing order of roll numbers, nor they are assigned as per the branch of the student. You know that even at your place the programming course is taught to all students. Students of electrical, mechanical, metallurgical, engineering, physics, chemistry, maths, everybody takes this course. So what I did instead is I divided the whole set of students into 10 divisions based on the last digit of their roll number. Since the last digit can be 0, 1, 2, 3, 4, 5, 6, up to 9, all students got randomly distributed across different branches. This helped me to ensure that in every batch there are some students from computer science, some students from electrical, some students from metallurgical engineering, some students from maths, some students from physics, some students from geosciences and whatever. This actually helps in order to tell our students that look when you form teams for doing your projects such as a lab batch, you may not have a choice on who should be your partner. In general, in real life, not only in programming but in any other field of activity, when you join an organization, the organization tells you that you go and join this team and you actually have to learn to work with people who are completely unknown to you. And there is no harm I thought in giving our young students and time to experience this kind of phenomena. So this is what we had done. Anyway, what was therefore important for us to find out not only the total class averages and so on, but batch-wise averages. What is the average for batch 0a? What is the average for batch 0b? What is the average for batch 1b? Why are these averages important? Because we wanted to know that by randomly distributing these students across, I was hoping to have the batch talent sort of equalized. What do you mean by batch talent? Well, there are some students as I mentioned who would have studied programming earlier and they would always know much more than others. There would be some students who have no clue to the programming. Random distribution might ensure that both the innate talent of the students as well as their prior exposure gets distributed across the branches. In any case, this was our reason for doing it. The point I am making is that in any programming application you might be required to write an application which precisely does similar kind of things. The data may be different. So, stated very simply, we have this data and we want to analyze this data so which means we have to read this data and we want to calculate the batch-wise average marks and the class average. Now you can already sense that this is not going to be very easy because now you have comma-separated fields, you have to take care of commas. The point is that our roll numbers are not completely numerical values. So, there is a zero at the beginning. This zero means 0, 8 is the year of entry. But here I have a number which is 9, 0, 0, 2, 0, 4, 0. So, one digit is missing in this because the first digit was zero. This happens because this particular string was taken to be a string by a spreadsheet whereas this was interpreted as a numerical value. The teaching assistant who was making the final spreadsheet forgot to stipulate the format for the spreadsheet, whatever be the reason. We have a character D here. So, we have in short an 8 character roll number code rather than a numerical value. I already mentioned about the names with blanks in between and so on and I already mentioned about the fact that sometimes the name may be missing, sometimes the batch may be missing and so on. Later on I will upload a program which was written by our students to solve this problem to identify the commas and whatever, whatever. But and you would of course be attempting that in the lab today afternoon. What I wanted to show you quickly is a different programming paradigm as I mentioned. So, in the next 15 minutes we will learn a new programming language from start to finish except of course for those who already know this. Now a simple method to find out or analyze these Mr. and Mr. Marks and to find out lab batch average is to use a programming language called AUK. There is also a very old programming language. It is actually called a scripting language. It was invented in 1970 and you will notice that Alfred Aho, Bitter Weinberger and Brian Kernigan were the people who invented this language or who designed this language. Out of them Weinberger, Kernigan all three of them were deeply associated with UNIXE and the similar kind of work that was going on. What this language does is it has very simplistic instructions, extremely simple as we shall see. It makes heavy use of string data type. It makes very heavy use of associative arrays. You remember in histogram we talked about associative array. That means if we want a value histogram or let us say pixel value, intensity value of 127 then we go to 127. The element of that array itself that becomes an associative array anyway and it also makes use of regular expressions. Of course I am not using this material to tell my colleague, teachers here how to teach programming. But I did introduce these slides in my own course and this helped me kindle the curiosity of several students. So the students were enamored by the power of AUG and they understood that in a regular programming language what kind of lengthy effort is required here. There are of course some adequacies in AUG which later on, this is a historical fact, later on lead to a language called PIRL. The PIRL programming language is very heavily used by a large community which develops sort of software products or software code for solving specific applications, all of which generally have to do with text processing. Without further ado let me go over to the AUG language fundamentals. It is primarily a language for processing text files and a file is treated as a sequence of records and by default each line is a record. So you see how easy the definition is. The data it deals with is set of lines. Each line is a record. Further each line is broken up into a sequence of fields so that we can think of the first word in the line as first field, second word as second field and so on. This is ordinarily this will be the case. In the file that we looked at we have comma as separating fields. So our field separation is defined by comma. When it is defined by comma we have exactly five fields in our particular record and we know that we have 820 odd records. Now what is an AUG program? AUG program is nothing but a sequence of pattern action statements. What AUG does is it looks at this file 820 people and 820 records. So first we just understood that each record is supposed to contain fields. The AUG program specifies what is to be done by describing patterns. So a line is scanned if a pattern is matched then the action corresponding to that pattern is taken. If an action is not matched then the other action is taken. So there is a default action and there is an action to be matched because of the pattern matching. A question was asked from Trichaud as to what is the field length and so on. So here is the beauty. AUG does not believe in any fixing of length. So this is how the AUG will treat our records. Each record of our file is like this. This is a sample record I have shown here. Number 13, some roll number, name, batch and marks. This is one record where there are all five fields present. What AUG does is we have to prescribe of course how the fields are separated. In this case comma is the separator. Ordinarily by default AUG uses blank as a separator. As I already mentioned blank is not a good separator because it will separate a single name into two names. That is why I got commas to be inserted. But now what AUG does is very simple. When it reads the line it will automatically snap up all the commas and between two commas it will allocate every field to an automatic variable which gets created and which gets allocated values every time a line is read. The first field is referred to as dollar 1, second as dollar 2, third as dollar 3, fourth as dollar 4 and dollar 5. So it is very interesting. When an AUG program starts executing by definition it is supposed to read lines of text. The first line it reads it automatically breaks it up into fields. What is the field like? Nothing like that. All characters up to a comma is a field. From that comma to the second comma is second field. From that comma to third comma is third field. And therefore the allocation internally for memory that AUG must be making would be solved of a large variable storage depending on the maximum length of a line wire. The whole line may contain just a single field. However this is the action that it does. It reads a record breaks it up into fields. Now what do we want to do for every record? Simple thing. If a record has a negative value for marks we want to treat that as upset and therefore we do not want to count that record for our average calculation. Now how do we describe that a marks is negative? We describe that by a pattern. What is the pattern? If dollar 5 is 0 is the pattern less than 0. So dollar 5 is this. If the marks here are less than 0 remember we said negative marks means upset. Then action to be taken is increment a count for absenteeism. However for all other patterns namely whatever we value of dollar 3, whatever we value of dollar 2, whatever we value of dollar 1 etc etc. What are the actions to be taken? A, I have to maintain batch counts and update batch counts. I have to maintain mark totals for individual batches and update those mark totals. And at the end I have to print accumulated results. In short I need to maintain 4 different entities. 2 of them are simple variables. What is that? The total count of students who are present and the total marks. The total marks will be simply summation of these dollar 5. They are the 2 simple variables. But I also want to maintain the count and the marks individually for each batch. Since I have 40 batches I should get an array of 40 elements which should start with 0. And every time that batch is found here the marks should be added to that particular element of that batch. We will notice that some batches do not have a value. So there could be a blank batch also which I will have to determine. Ordinarily I would not be able to do that. Look at the simplistic way in which the C program can be written. This is the off program. No declarations, no nothing, nothing. The program just begins. When the program begins it is known that program will start getting filled with those lines. Each line broken into multiple fields automatically. This is the pattern written here. Dollar 5 less than 0. What is to be done? Absent count is to be added. Absent count plus plus. Notice there is no declaration, no initialization. Any time I use a variable at the beginning of the program it automatically initializes to 0. If it pertains to numerical value. Whether it is numerical or text is determined from the context. So this action will automatically mean that when I run all the data through this program absent count would be counted correctly. What I have to do for others who are not absent? That is for a pattern dollar 5 greater than equal to 0. Remember I said I have to update 4 counters. 2 counters are simple to understand. How Ock handles after last record. Good question you are anticipating the program. Just wait for 2 minutes and you will see that actually. So this entire program of these 2 patterns and associated actions. This program will apply to every record that is read. We have not yet reached end of the 5. So every line which is read Ock is handling this like that. So every line is either contains an absent student or a present student. If a student is absent, absent count is incremented. If a student is present then what is incremented? Count plus plus. So every student is counted. Top marks plus equal to dollar 5. Remember dollar 5 is marks in the test actually. So every mark is added and the top marks therefore at the end will contain the total marks obtained by the total students represented by count. Remember that absentees are not being counted. Because dollar 5 greater than equal to 0 will the pattern which will not match those lines which are absent students. Those are being counted separately. So every student who is present in short the marks are added to the top marks and the count of such students is added to the count. As I said in absent counts here also count is automatically initialised to 0. Top marks is automatically defined, location allocated and is initialised to 0. The most interesting thing is the other counts. Remember we have to make batch wise counting. The batches could be 0A, 0B, 0D etc. Imagine in some case the batch has been wrongly entered as ZA. There will be one odd student whose batch will be ZA. But we cannot assume that in a normal C program we would be giving the batch numbers hours less and so on. However in actual data there is ZA. So ZA also must be counted. There should be a count for one student. Look at what these two statements do simply. Batch taught dollar 4 plus equal to dollar 5. Imagine the first record which is read. Dollar 4 by the way is the batch code. Suppose the first record is 0C. Then what odd does is in the array of batch code which has been allocated arbitrary space initially it will create an element whose index will be 0A if the first record is 0A. And it will add to that 0 the value of marks. Suppose the fifth record again is 0A. The dollar 4 will be 0A. So that addition will go to that particular element only. Consequently if there are 40 batches 40 counts will get created one by one. They will get initialized to 0. And once they are initialized they will keep getting added by the corresponding marks obtained by the student of that batch. In exactly the same way the count is incremented by one for that batch. This is an extremely powerful example of associative array. The value of the element that you are checking itself is acting as an index. And that is how you update this. So batch count and batch dot is updated. A question was asked from Trishu. How does Okno whether file has ended or not? Well it will because end of file will come to Okno also. When end of file comes this program terminates. This program consists of only two statements. The other file less than 0 do this. The other file greater than 0 do this. But when the file terminates program ends I have to print out all the statistics. How is it printed? There is a third pattern end. This pattern matches only end of file. So this also defined as a pattern. This pattern will not match anything else. And when end pattern is matched that means the file has ended. It says for I in batch notice that batch indices are not 0, 1, 2, 3, 4. They are actually in alphabetical value. So I actually is varied over this set of alphabetical value. And for each value in that set it will print the type. That is it will print the branch. It will print batch count. It will print batch dot divided by batch count. So it will print batch average as well. And finally after the end nothing else. This is this is the after end you will execute this follow and you will execute this print statement. Print total students are these absent count. Print number absent absent count. This is count plus absent count is the total number. And print class average dot marks by count. This is the most simple program arguably to create such a statistics. This is the kind of output that you will get to execute. I have put that entire program in a file called analyze midsame.org. And I have given here minus capital F comma this becomes the field separator. And to this how do I feed the file? Ordinarily I will give input. But here I can use unix redirection. And saying midsemester marks dot text is the file. This file should be fed to the op program. And all that it does is it tells me 0A, 0B, 0C, 0D etc. Notice that there is a blank here. This corresponds to a student whose batch was blank. There is one student he got 22.5 marks so the average is 22.5. This continues for all students. And at the end it says total students are 819. Number absent is 10. Class average is 12. This is a discussion on org programming language. Very simply stated it is operationally less efficient. It is super for problems such as such text record processing. But it is not good for other computations. And therefore while it is good to use such things for such purposes. It is also not a compiled language. And therefore we have to use complicated programming languages. Because we want a efficient code. And we want the ability to handle what you call numerical data. The non-numeric non-text data such as digital images and so on. There are however a large number of people who use org and pearl very effectively. It solves all kinds of problems. However we go back to our CC++ Java and such things. So we will have a tea break. Thank you very much.