Um, yes, I could make it "simpler" and perhaps more efficient. Who cares? Don't pre-optimize code without some reason to do so. The code you have written is already reasonably efficient.
Now, COULD I have written it more elegantly, perhaps using a tool like histcounts to bin the grades? The virtue of histcounts is it will work for a vector of student grades. So, yes, I could have done so. For a "noob" the result might not have made a lot of sense, using what appears to be a histogram tool. Remember that code that does something in a way that you can't read to debug later is a bad idea. So until you get to the point where that sort of approach looks easy to you, avoid it.
Finally, COULD I have written your code in a way that is somewhat simpler? Well, yes. Swap the way you are doing things.
if num_grade >= 90
elseif num_grade >= 80
elseif num_grade >= 70
elseif num_grade >= 60
disp('The sky is falling!!! (said Chicken Little)');
The point is, you don't need to test if numgrade is less than 90 to test for a B, since you have already excluded the case where it is greater than 90 in the first branch of the if. So the set of tests that I wrote are simpler and more efficient, since they use only 1 test at each step.
One last point. You should learn about the difference between the & and && operators.
In an if statement where you have two tests A and B,
what is the difference? The && operator is a short-circuited test. Suppose that A is false? Can false & anything EVER result in true? Look at your truth tables for and.
So if A is false, the if statement never needs to evaluate the second test when using &&. The secondary test if only checked when A is true, thus when it is possible that a true result could happen. That saves some CPU cycles. But in the code as I wrote it, you only ever needed ONE test at a time anyway.
Similarly, || is a short-circuited version of the | operator.