Jump to content

Got a programming (C#) exam - help an idiot

Trixanity

Greetings interwebs.

 

I have a problem. I got a technological exam coming up in four days. Technological being programming and networking. It's a re-examination (was sick during the original exam 6 months ago) and just a few days ago I received the exam questions from the responsible teacher. I haven't touched programming in a while and I just realized how lost I am. The teacher is willing to help me, but it's kind of embarrassing the amount of help I need in order to pass. Granted, since it's a mixed exam and I expect to pretty much ace the other half, I do expect to pass regardless of how miserable my programming skills and knowledge are.

 

So I turn to you guys. I hope you can help me understand algorithms and programming logic (I hope the terminology covers it). That's my main issue. I'm pretty familiar with the syntax etc but obviously the hard part is how to write and understand proper code - which I've always sucked at, so it would be much appreciated if someone can explain it to me like I'm an idiot/five years old.

 

As mentioned, I've received a bunch of exam questions and the basic formula is "explain this method" and then some lines of code aka a method.

 

I'm not necessarily looking for a detailed answer that I'll merely commit to memory and recite at the exam. I am interested in learning and understanding what's going on.

 

I'll give an example from the exam questions. I won't just paste all my exam questions as I hope to learn something and not just rely on memory since I'll probably receive questions during the exam that I won't be able to answer if I don't understand how things work.

 

One of the methods I need to explain is the following:

        private string hex2dec(string instr)        {            string result ="";            Int32 decint=0;            Int32 i,x=1;            instr = instr.ToUpper();            for (i = instr.Length; i > 0;i--)            {                if(Convert.ToInt32(instr[i-1])<10)                    decint += Convert.ToInt32( instr[i - 1]);                if (instr[i - 1] == 'A') decint += 10*x;                if (instr[i - 1] == 'B') decint += 11 * x;                if (instr[i - 1] == 'C') decint += 12 * x;                if (instr[i - 1] == 'D') decint += 13 * x;                if (instr[i - 1] == 'E') decint += 14 * x;                if (instr[i - 1] == 'F') decint += 15 * x;                x = x * 16;            }            result = decint.ToString();            return result;        }

 

I understand the syntax and structure mostly. And I also know what the code does (the name of the private string kinda gives it away) but I expect that I need to explain in detail what each line does in order to convert a hexadecimal to decimal and why it's written in the way it's written.

 

So please explain to this idiot how things work. When I look at it, I see math and I also suck at math. Maybe I'm looking at it wrong but that's why I'm asking.

 

Feel free to request more info. I don't know what else to say presently.

Link to comment
Share on other sites

Link to post
Share on other sites

"but it's kind of embarrassing the amount of help I need in order to pass"

 

Why? whats so embarrassing about it??? we all need help from time to time. i dont think its embarrassing to say hey i dont remember some of this and i need more help then most. looking back at classes in the past i wish i had the incite to swallow my pride and ask for help. no one will judge you.

Link to comment
Share on other sites

Link to post
Share on other sites

The first problem that you seem to have is ignorance. You missed or were too lazy to read the very obvious post located here:

 

PZ20Fqo.png

 

Until you fix your post you'll get no help form me nor a not insignificant number of others as well... Really there's far too many people who don't give a shit about formatting now...

The single biggest problem in communication is the illusion that it has taken place.

Link to comment
Share on other sites

Link to post
Share on other sites

That is my major for college. I start college on the 18th of August. I took some C# but I forgot lol. Maybe @LukaP can help you.

Love cats and Linus. Check out linuscattips-fan-club. http://pcpartpicker.com/p/Z9QDVn and Asus ROG Swift. I love anime as well. Check out Heaven Society heaven-society. My own personal giveaway thread http://linustechtips.com/main/topic/387856-evga-geforce-gtx-970-giveaway-presented-by-grimneo/.

Link to comment
Share on other sites

Link to post
Share on other sites

-snip-

Well a mod must of fixed but it is located in that part of the forum.

Love cats and Linus. Check out linuscattips-fan-club. http://pcpartpicker.com/p/Z9QDVn and Asus ROG Swift. I love anime as well. Check out Heaven Society heaven-society. My own personal giveaway thread http://linustechtips.com/main/topic/387856-evga-geforce-gtx-970-giveaway-presented-by-grimneo/.

Link to comment
Share on other sites

Link to post
Share on other sites

-snip-

 

 

 

My bad. Fixed now. I read the stickies. Not familiar with other forums that have topics _above_ the usual stickies. So yes, ignorance. Luckily it's easily corrected :) As you saw, I did attempt to enclose the code without knowledge of the tags - however futile it was.

Link to comment
Share on other sites

Link to post
Share on other sites

It's taking in a string in hexadecimal format. That's a number format similar to decimal (0-9) which rolls over every 16 instead, so you have the usual 0-9 then you get A-F before it rolls back. E.g. 11 in hexademical is 17 in decimal (16*1+1*1) and 1B is 27 (16*1+1*11).

 

The loop of the program has a sum (decint) of each column of the hex number given (remember how you do it in decimals with hundreds, tens and units?) and each iteration of the loop adds to that sum. There are lots of if statements to convert the different characters you can find in a hex string into their decimal equivalents. The first one looks at the digits given (0-9) and these can be directly converted. The second one looks at A and since A(hex)=10(dec) we add on 10, then B(hex)=11(dec) so we add on 11 etc.

 

Now look at the x, remember how you do it with columns?

 

In decimal

100 10 1 (each column is the previous * 10)

1      2   1

 

= 1*100+2*10+1*1 = 121

 

In Hexadecimal

256 16 1 (each column is the previous * 16)

1      A  F

 

=1*256+16*10+1*15 = 431

 

The loop starts at the end of the string and works its way forward (notice how the loop starts at .length and the iterator is i--?). So the first column is the units (hence why x is initialised to 1) and then at the end of each iteration we multiply x by 16 to get the multiplier for the next column.

 

I'm also pretty sure the code has a bug:

The standard case of converting a 0-9 hex digit to a 0-9 decimal digit doesn't do the multiplication by x:

Take 1B in hex which we know from before is 16*1+11*1 which is equal to 27.

This algorithm would convert the B to an 11 then convert the 1 to a 1 and add it on which would give us 12 which is WRONG.

 

The code itself isn't well written though (even if it isn't your code). Some improvements

  • Declaring all your variables at the start is a bad idea. Declaration should be as close to (ideally in the same line as) initialisation of your variables. This helps to reduce the risk of having variables uninitialised. Lets take a look at each one.
    • result: this variable doesn't even need to exist. It's initialised as the empty string and then assigned the final converted string then returned. You can do away with this entire thing and just return decint.ToString()
    • decint: this is the only justified declaration in this group of declarations. You need access to decint outside the loop so you can't declare it inside the loop so the only place it can go is here.
    • i: this is the loop counter variable. There are very few if not ZERO circumstances where the loop counter should be accessible outside the loop. It's not threadsafe, it's not good for the garbage collector, it confuses the loop declaration. NEVER DO THIS.
    • x: somewhat justifiable. You don't need x outside the loop but you can't declare it inside the loop since its value needs to be known across multiple iterations and a variable declared inside the loop only has that value for that iteration. However, you could initialise it each time since it's always going to be equal to instr.Length-i (work it out). However the repeated initialisation is a bit slow so that would justify putting x outside the loop.
  • The result variable isn't even needed, it creates extra complexity in the code for no benefit, just return decint.ToString()
  • Some of the spacing is a bit off, binary operators should always have a space between the operator and the operands. That's a stylistic choice that I prefer so you can ignore the space if you want but you should at least be consistent about it. The first if statement's spacing doesn't match the spacing in the rest of the method.
  • x = x * 16 can be written as x *= 16. Not sure why this wasn't done since they've already used decint += in places.
  • There's no validation on the input string (ignoring converting it to upper case). At minimum there should be a null check and a check that every character in the string is either a 0-9 digit or an A-F character.
  • hex2dec is a pretty bad name, HexadecimalToDecimal would be better. The length of a variable name is no longer a problem, more readable names are always better. Similarly, decint is a godawful name, should be something like decimal. x should be something like columnMultiplier and i should be columnNumber. instr should be hexString.
  • The switch statement would be better suited for this than lots of if statements, this is pretty much what it was made for.
  • Repeatedly trying to access the character using the array index rather than accessing the array once and storing it
  • The method would be easier to use if it was "fluent". This would mean having a signature like: private string ConvertToDecimal(this string hexString). This means you could call it on a string object like this: 
    string decimalString = "AF042BC".ConvertToDecimal();

 

Taking these improvements into account:

        private string ConvertToDecimal(this string hexString)        {            Int32 decint=0;            Int32 columnMultiplier=1;            hexString = hexString.ToUpper();            for (Int32 columnNumber = instr.Length; columnNumber > 0; columnNumber--)            {                char currentDigit = hexString[columnNumber - 1];                switch(currentDigit)                {                    case 'A': decint += 10 * columnMultiplier; break;                    case 'B': decint += 11 * columnMultiplier; break;                    case 'C': decint += 12 * columnMultiplier; break;                    case 'D': decint += 13 * columnMultiplier; break;                    case 'E': decint += 14 * columnMultiplier; break;                    case 'F': decint += 15 * columnMultiplier; break;                    default: decint += Convert.ToInt32(currentDigit); break; // Pretty sure this is a bug, it should multiply by x here                }                columnMultiplier *= 16;            }            return decint.ToString();        }
Link to comment
Share on other sites

Link to post
Share on other sites

Thanks. Regarding the code: It was not written by me. It's written by a teacher. I always suspect that they don't necessarily write good code but that they write simple code and attempt to avoid confusion by using - I suppose - more advanced techniques. I don't know whether that's the right approach or not but I honestly don't think they expect us to work with programming when we graduate. There's not enough focus on it, it's an addition to the curriculum that'll look good on the resumé I guess. I've talked with other people who've graduated - top students in fact - and asked the group whether they could actually program and only one raised his hand and he had prior experience so he already could before joining the program. Our primary focus is networking and that's where my own talents lie but that doesn't mean I'll forfeit this exam :) 

 

I appreciate the code cleanup. Would be good to present the use of the switch at the exam - will definitely earn some points (at least if I can present it properly). It's an oral exam by the way, so I won't be writing any of my own code or probably at best, I'll be writing a line or two on a whiteboard.

 

I understand the function of 'x' now, but I still have a bit of trouble with 'i'. I'm used to using '++' to increment numbers, so I realize that '--' decrements. Why do we decrement in this case? You've probably explained it but I can't seem to wrap my head around it. Also, what's the function of the [i - 1] array? Why is it minus one? I assume it correlates with the decrement of the previous statement. I think if I understand that, I'll understand the entirety of this method.

Link to comment
Share on other sites

Link to post
Share on other sites

I understand the function of 'x' now, but I still have a bit of trouble with 'i'. I'm used to using '++' to increment numbers, so I realize that '--' decrements. Why do we decrement in this case? You've probably explained it but I can't seem to wrap my head around it. 

 

We decrement because we're actually starting at the other end of the string. Normally in a for loop you start from 0 and work up to some maximum, say the length of a string. In this case we want to start from the maximum (string.Length) and work our way down, hence decrementing. E.g. in the string 123456 you first look at 6 then 5 then 4 then 3 then 2 then 1. You could do it front to back rather than back to front, but that would make calculating x a lot harder since x would need to start at 16*string.Length and be divided by 16 each time rather than starting at 1 and being multiplied. It's also marginally faster to multiply than to divide at a hardware level so it's a bit more efficient too.

 

Also, what's the function of the [i - 1] array? Why is it minus one? I assume it correlates with the decrement of the previous statement. 

 

You'll see array access (remember strings are just arrays of characters) with -1 pretty frequently. The reason is that arrays are zero indexed but we often need to use their length. E.g. the array {1} has length 1 but the only element in the array is at index 0. If we wanted to access it using the length, we have to use length-1 = 1-1 = 0. Similarly, {1,2,3,4,5} has length 5 but 1 is at index 0, 2 at 1, 3 at 2, 4 at 3 and 5 at index 4. If we want to access index 5 we have to look at index 4, i.e. length-1. Since the variable i is in this case related to length (as we are calculating it by decrementing the length), we also have to take -1 from i too. Another way you'll see this written is in a more standard for loop where the loop starts at 0 and counts up to strictly less than the length, i.e. the loop will stop at length-1, so in that case you wouldn't need the -1 since we've already accounted for it: e.g.

int[] array = {1,2,3,4,5};for(int i = 0; i < array.Length; i++){     int currentNumber = array[i]}
Link to comment
Share on other sites

Link to post
Share on other sites

I know this is completely irrelevant, but don't use the ToUpper() function for this. It's a reasonably expensive call and not really necessary here. I see it used a lot and it can really bottleneck some code.
If you were using a switch statement, you could just use
case 'A':case 'a':     decint += 10 * multiplier;    break;
 
 

 

  • Declaring all your variables at the start is a bad idea. Declaration should be as close to (ideally in the same line as) initialisation of your variables. This helps to reduce the risk of having variables uninitialised. Lets take a look at each one.

I'm pretty sure C# won't let you compile if you try to use an uninitialized variable.

 

Thought I agree with this for auto variables, I'd disagree with this for anything that you have to explicitly deallocate, such as IDisposables in C#. Makes it easier to make a mistake if you have them all scattered (though C#'s using statements makes this a bit more convenient).

Link to comment
Share on other sites

Link to post
Share on other sites

I have questions about two pieces of code. I'll add comments to the code to specify my questions to the code since your explanations for the first piece of code has made be understand a good deal about some of the other exam questions. Here goes.

        static string dec2hex(Int32 decint)        {            string result = "", result2 = "";  // why do we use two strings to do this?            Int32 temp1, i, x = 1;            for (i = 15; (i < 65537); i = i * 16)  // since we're converting decimals to binary, I understand that we multiply by 16. Why is 'i < 65537'? I know that the number equals the maximum range of                                                                   // 16 bit. I also assume 'i' equals 15 because hexadecimals operate in the range of 1 to 15 (F) and we multiply by 16 for each number in the column            {                temp1 = decint & i; // why do we use the '&' operator in this case?                if (temp1 < 10 * x)                    result += (temp1 / x).ToString(); // why do we divide by 1 ?                if (temp1 == 10 * x)                    result += "A";                if (temp1 == 11 * x)                    result += "B";                if (temp1 == 12 * x)                    result += "C";                if (temp1 == 13 * x)                    result += "D";                if (temp1 == 14 * x)                    result += "E";                if (temp1 == 15 * x)                    result += "F";                x = x * 16;            }            for (i = result.Length; i > 0; i--)                result2 += result[i - 1];            return result2;        }

Edit: the second piece disappeared when I submitted, so I have to redo it below:

 

        static string dec2bin(Int32 decint)        {            string result = "";            Int32 i;            for (i = 65536; i > 0; i = i / 2) // again, why do we use this seemingly arbitrary number '65536' ? I assume we divide 'i' by 2 because each number in the column doubles in value, so we kinda have to work around that during the conversion. A more eloquent explanation would be nice.            {                if (decint >= i)                {                    result += "1"; // Why do we use these two variables this way?                    decint = decint - i; // couldn't this have been written as 'decint -= i' ? I mean the line above could have been written as 'result = result + "1"' as I                                                                    //understand it                }                else                    result += "0";            }            return result;        }
Link to comment
Share on other sites

Link to post
Share on other sites

How to learn C#??? Start modding for terraria and you are done

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×