Saad Malik's Opus
Fall 2012
Data Structures
Discrete Structures
Computer Organization (Ind. Study)
Data Communication
My name is Saad! I'm going to finish my computer science degree from CCC this year and transfer to maybe SUNY Binghamton/Stonybrook, or RIT, or whatever. Not too sure yet.
Today for Data Comm we managed to get asterisk up and running properly. We connected a softphone on my laptop to a softphone running on Andrews laptop, all through asterisk's service. We edited files that we weren't supposed to, since we couldn't find the options in the gui web interface.
I'm hoping that for Thursday we can get asterisk to connect to the cisco phone, and maybe get to work on integrating it with google voice. Maybe if we get really lucky we can even start figuring out how to text non local numbers using the google voice service.
At first I had a lot of trouble understanding asterisk, but now I think I am getting the feel for it. I think it will be less confusing as progression is made.
Yesterday in Data Structures we got into the 'real' data structures part. We started learning about linked lists, and got as far as insertion and must now code a deletion.
I thought the way the a link list works is very cool. It can basically dynamically allocate, and uses struct pointers, and uses the struct to create more instances of the struct (as many as the program wants). We're basically teaching the program how to give itself more memory within certain constraints. If you screw up and are not careful about these constraints, you can lose track of where the nodes are located - so while the program is running, it is taking up memory that it can't even get back to: a memory leak.
The whole deal with this was very intuitive and I appreciated how it worked. I probably could not reproduce it on the spot perfectly, but looking at the example from class I can understand how it is doing what it is doing.
I will probably create the deletion part of it in a couple days, I don't anticipate it being too difficult.
Yesterday I coded the increment function. I even made it work with bignum, and work for any given base (upto base 16). At first I did some weird thing where I incremented every value in the number, not sure why I did that. Once I got rid of that, the solution became much much easier to implement.
To test this, I would copy my code into my bignum location (where it belonged, in this case I believe it was in ops). I would then make a backup of the .o file that was already there. Then, I would run make from the bignum directory, and then cd to testing, do a make clean and then do a make. Then I can run the respective test program. It is very neat. I may write a decrement function later today or tomorrow.
While working on asterisk last week we started running into a lot of dead ends. However, now that we know a lot about how it works, I believe the best course of action will now be to start fresh and keep very careful track of everything and undo unnecessary changes instead if letting them pile up. I really think we could get it up and running with Google voice in a day with a fresh start.
We know how to add custom ringtones, know how to create extensions and how to compile from source and how the .conf files work (some of them). All we need to do is get a clean Linux district on the machine and follow a guide that actually specifies the asterisk version to be used. It should work out pleasantly that way.
CPU Registers
A CPU register is effectively how the CPU manipulates given data.
The CPU can use load commands to bring data from memory, into a register. The register is the fastest part of a computer - it's where the CPU can do work with the greatest speed. Once some data is loaded into a register, the CPU can then manipulate that data. Add, subtract, all of these things happen in the register. Once the instruction is done, another command can be used to push that data back into memory and then the register is available for use once again.
For the z80 CPU simulator, the registers will be represented by text files. A combination of scripts and C programs will be used to load data from a memory file into a register, then perform the desired operation, and then move the result in whatever way was intended. It will end up being a ton of different scripts and programs, because there are many different combinations - as there are multiple registers, and we need a way to move values between registers, move values from registers to memory, from memory to registers, etc.
CPU Registers
A CPU register is effectively how the CPU manipulates given data.
The CPU can use load commands to bring data from memory, into a register. The register is the fastest part of a computer - it's where the CPU can do work with the greatest speed. Once some data is loaded into a register, the CPU can then manipulate that data. Add, subtract, all of these things happen in the register. Once the instruction is done, another command can be used to push that data back into memory and then the register is available for use once again.
For the z80 CPU simulator, the registers will be represented by text files. A combination of scripts and C programs will be used to load data from a memory file into a register, then perform the desired operation, and then move the result in whatever way was intended. It will end up being a ton of different scripts and programs, because there are many different combinations - as there are multiple registers, and we need a way to move values between registers, move values from registers to memory, from memory to registers, etc.
pointer arithmetic (esp. in relation to arrays)
Pointer arithmetic is basically when you use math on pointers to accomplish a task. Generally this task is looped, where the math is incrementing or decrementing… and generally this is used for 'pointer arrays' (as opposed to 'bracket arrays').
When you want to make an array, and fill it with 20 zero's. You will create a pointer. You will then create a loop that will fill in a zero to the array, where the pointer is having a counter of some form (usually) being added to it. That part where the pointer is having stuff added to it, that's pointer arithmetic.
Pointer arithmetic is arguably faster, but it really does depend on surrounding code and the CPU and the compiler etc.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
A collection of data that is organized so it can easily be modified, updated, or deleted.
A cool website to test sql: http://www.w3schools.com/sql/sql_tryit.asp
This website has it's own sql database up and lets you run commands on it to see what different commands will do.
SELECT CompanyName, ContactName FROM customers
This sql command would display all data values that are under the 'CompanyName' and the ones from 'ContactName' from the customers list.
So all the people that are identified as customers in the database - they have different forms of data for each customer. Such as CompanyName, and ContactName. There are others as well. This command would pull just the two that I listed. It seems a lot like a real life implementation of linked lists..
SIP - Session Initiation Protocol
SIP is a signalling protocol. I would guess that that means it is a certain method of having machines communicate. It is typically used for voice and video communication. SIP can be used for two-party (unicast) and multiparty (multicast).
You can modify IPs and ports, invite more people, and add/delete media streams.
SIP can take care of 5 things:
At first I had no idea what SIP was all about and had difficulty understanding it. Now I have a pretty good understanding, I think. I'll probably ask about it next class to make sure I am right, but I feel like SIP is basically just a 'code' of how machines communicate. Just like how humans use English, or Spanish, or Arabic. Computers can use SIP.
On further research, the analogy is fairly sound, but needs a little bit more to it. SIP is basically a specific format that machines can use to communicate. It's a set of certain things that need to be done while communicating. It's not like a language…. it's more like the RULES behind a language.
asterisk
A programming language to communicate and execute the basic functions of telephony services.
Example of a configuration file written using asterisks language. Given an example, it is pretty easy to figure out what certain things mean. The 600 numbers are the numbers to call, and then it will Dial and use the given protocol to try to connect to the defined name. The 20 is how long it will ring for.
exten => s,1,Answer() exten => s,n,Wait(2) exten => s,n,SendDTMF(1) exten => s,n,Dial(SIP/Saad&SIP/Andrew&SIP/LairPhone&SIP/Dataking&SIP/sipura&SIP/PA168,20) exten => s,n,VoiceMail(601@vm,u) exten => 601,1,Dial(SIP/Saad,20) exten => 601,n,VoiceMail(601@vm,u) exten => 602,1,Dial(SIP/Andrew,20) exten => 602,n,VoiceMail(602@vm,u) exten => 603,1,Dial(SIP/LairPhone,20) exten => 603,n,VoiceMail(603@vm,u) exten => 604,1,Dial(SIP/PA168,20) exten => 604,n,VoiceMail(604@vm,u) exten => 605,1,Dial(SIP/Dataking,20) exten => 605,n,VoiceMail(605@vm,u) exten => 606,1,Dial(SIP/sipura,20) exten => 606,n,VoiceMail(606@vm,u)
exclusive disjunction/nonequivalence
Exclusive disjunction means that only one can be true, but not both. It's basically an XOR.
Affirmation/Validity/Tautology
Everything is always evaluated as true
P | Q | X ---------------- 0 | 0 | 1 0 | 1 | 1 1 | 0 | 1 1 | 1 | 1 ----------------
Can I send a linked list to a void function, have the function perform something to change the list, and then have the changes reflect in the main program without actually having to return a pointer and setting the list equal to the function call?
To test this I am going to use knowledge gained through the data structures class. And a little discrete.
Based on what you've read with respect to your original posed question, what do you think will be the result of your experiment (ie an educated guess based on the facts known). This is done before actually performing the experiment.
State your rationale.
Since linked lists use a pointer to work… I am going to have to use double pointers to make this while thing work out okay. I also tried this using just the single pointers and the values would not stay globally throughout the program. Double pointers will have to be used, and I will probably get a headache. I am thinking I will have to define the start of the linked list as a double pointer. While I am filing it and stuff, I will have it dereferenced down only one level. When I pass it to a function to sort, I will pass the double pointer. So I will technically be passing by address. Within the function, I dereference it down one level and make the changes. These changes should carry through globally because it was passed by address.
/home/smalik2/repo/experiments
I believe my hypothesis was correct. Although I technically passed a single pointer by reference - its effectively the same thing.
I had a huge problem that was resolved when I figured out there was a malloc on a temp variable - and not on the start pointer. So the list would get lost and become a memory leak.
I'm much more comfortable with pointers now. On top of that, I'm gaining familiarity with double pointers which will let me make more concise code.
Today in Data structures we learned about binary trees. I didn't really see the point of it, until Matt showed how we can use it for sorting. It seems pretty awesome.
The difficult part will be working out the algorithms - but when it comes time to creating a program for binary trees, I will probably choose the recursive method since that is what I'm least familiar with.
For Discrete we've been working on a set program part 2. Basically we have to be able to build 2 sets, display 3 sets (third one is a 'result' set), union the 2 sets, intersect the 2 sets, and take a difference between sets A and B and between B and A. Also clear the sets.
I used iterative algorithms for this program and it was quite a pain after awhile - the algorithms are getting increasingly complex and long. I'm betting a recursive method would have worked much better - if we have another set program I would probably try that instead.
For comp. org. I set up a directory and have an increment and decrement up and running. I set up a bncreate, and a setnum function as well. The next stage is where it gets a little repetitive (ad where Andrew may or may not come into play) and that is writing the C code that would complement the LD functions. For LD functions I am thinking that since there are only a certain of possibilities it may just be better to 'hardcode' them into if statements and taking command line arguments.
Eventually, and I would probably need Matts help with this, there will be scripts that will actually be responsible for calling the LD functions and responsible for sending the command line argument to them.
The asterisk project has pretty much winded down. We've been unable to get the new machine working properly - it connects but no sound gets transmitted. We did connect it to a coffee maker and a lightbulb though so that was cool.
Now we are going to use a program called minimodem which takes a file input and then outputs it as sound (like the dialup sound). This sound will be transmitted through two cans and a string, and then received into a machine running the program in receiving mode. So we could hopefully transmit a photo using two cans and a string.
The LD instruction
The LD function is how data gets moved within this Z80 processor. That's pretty important.
LD C,2 is a simple LD function that will take the value of 2 and put that value into register C.
LD B,C is a LD function that will take the value in C (the 2) and put that value into register B.
LD E,0AAH is a LD function that will put the HEX value (hence the H) into register F.
LD H,11111111B will put that binary value into register H.
You can also do all of these using double registers, to denote 2 byte entities (like memory locations in RAM!)
These instructions all do the same thing (shamelessly taken from the z80 instructions manual):
LD B,073H
LD B,01110011B
LD B,65
LD B,“s”
We use LD functions to move from RAM.
LD A,0FFH - register A now contains the value of 255.
LD BC, 5364 - puts the value of 5364 into the double register BC.
LD (BC),A - puts the 255 from register A into memory location 5364 (BC).
LD E, (BC) - pulls the 255 from memory location 5364 (BC) into register E.
LD (BC), 200 - puts the contents of C into memory 200, and B into memory 201. (Take note that it is backwards.)
The LD instruction
The LD function is how data gets moved within this Z80 processor. That's pretty important.
LD C,2 is a simple LD function that will take the value of 2 and put that value into register C.
LD B,C is a LD function that will take the value in C (the 2) and put that value into register B.
LD E,0AAH is a LD function that will put the HEX value (hence the H) into register F.
LD H,11111111B will put that binary value into register H.
You can also do all of these using double registers, to denote 2 byte entities (like memory locations in RAM!)
These instructions all do the same thing (shamelessly taken from the z80 instructions manual):
LD B,073H
LD B,01110011B
LD B,65
LD B,“s”
We use LD functions to move from RAM.
LD A,0FFH - register A now contains the value of 255.
LD BC, 5364 - puts the value of 5364 into the double register BC.
LD (BC),A - puts the 255 from register A into memory location 5364 (BC).
LD E, (BC) - pulls the 255 from memory location 5364 (BC) into register E.
LD (BC), 200 - puts the contents of C into memory 200, and B into memory 201. (Take note that it is backwards.)
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
doubly linked list
A doubly linked list a a method of storing data.
The manner in which the data is stored is by a series of structs. There will be a variable that will always point to the first struct, and if you want there can be one to always point to the last struct.
Every struct has a minimum of three variables contained within - the data value, a pointer to the struct after it, and a pointer to the struct before it. These pointers is how one will navigate these structs, it is how they are linked together.
No references for this keyword.
linked list
A linked list is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a link to the next node in the sequence; more complex variants add additional links. This structure allows for efficient insertion or removal of elements from any position in the sequence.
Demonstration of the indicated keyword.
Plenty of linked list demos in my repo.
5 void FillList(Node **start) 6 { 7 char input; 8 Node *tmp; 9 tmp=(*start); 10 tmp == NULL; 11 printf("Enter a value (-1 to end): "); 12 scanf("%hhd", &input); 13 14 while(input != -1) 15 { 16 if (tmp == NULL) 17 { 18 tmp=(Node*)malloc(sizeof(Node)); 19 tmp->value=input; 20 tmp->next=NULL; 21 tmp->prev=NULL; 22 *start=tmp; 23 } 24 else 25 { 26 tmp->next=(Node*)malloc(sizeof(Node)); 27 tmp->next->value=input; 28 tmp->next->next=NULL; 29 tmp->next->prev=tmp; 30 tmp=tmp->next; 31 } 32 printf("Enter a value (-1 to end): "); 33 scanf("%hhd", &input); 34 } 35 }
This is a function that creates a linked list.
Freeswitch
Freeswitch is an open source communications piece of software that can be used for the creation of voice/messaging tools. It can be used as a standalone application, or embedded and ran with other programs.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
mutual exclusion
Mutual Exclusion is the method by which one can ensure that a region of memory cannot be accessed by two processes at the same time.
In logic terms, it can described as possibilities where you cannot have more than one be true at a time.
subset
A subset is a set which every element in the set is contained in a larger or equal size set. In other words a set with in a set.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
The set of {2,4,6} would be a subset of the set {0,2,4,6,8}.
For passing linked lists to functions and keeping track of the changes made without using a return, I had to use double pointers. What I would do is send the single Node pointer to the function by address - and define it as a double pointer in the function while dereferencing it once whenever it was used within the function.
What I was curious was would it be the same thing if I defined a double Node pointer in the main function, and just sent that without any dereferencing to the functions? It should be the same thing — it's still a double pointer after all.
This is basically more pointer playfulness. So all of the knowledge was gained last year from C/C++ Programming and from Matt.
I figured that it would work the same - since I am effectively doing the same thing, just shifting the notation by a little bit.
I tried to use this slightly different method in my stack program.
When I tried this - I kept running into seg faults.
When I talked about this with Matt, he figured it would be a malloc issue. Using the debugger, I figured out that even the pointers WEREN'T BEING GIVEN AN ADDRESS. So the pointer, was completely null. It didn't point to something. The pointer itself was null. Therefore, I couldn't pass it. My workaround was to create some variables and set their addresses equal to the pointers. I also had to implement two layers of mallocing. It was a gigantic pain, and the end result was that it sort of worked.
In the end, I resorted to passing single pointers by address :).
My hypothesis was half true.
It is applicable.
There is more going on than I thought - there were malloc issues that had to kind of manually be resolved, and it was a gigantic pain figuring it all out.
There were no shortcomings - I was able to test my hypothesis nicely.
The data is pretty nice about indicating that one would not want to accomplish this task this way.
Pass the single pointer by address.
I am getting started on the Binary Tree project. I looked into function pointers and got that all figured out. Now I just need to figure out the algorithm for inputting the queued values into the binary tree in a way that the traversal will actually print from least to greatest and so on. Also printing it in a 'tree' format will be tricky. I think once I figure it out iteratively then recursively and stack based should be easier.
For DataComm we setup strings and cans and managed to get a few bytes of data across them! Despite the fact that only about 1% of the data could make it through, it was still pretty cool. I would like to try to setup like a cardboard tube system and see if that transmits the sound cleanly enough for it to have a better transfer success rate. We also think that the sound may be becoming morphed, making it impossible for the receiving computer to pick it up. It was still pretty cool.
For Comp. Org. I got my increment working! Now that I have fully working code, I can work on the scripts that will make increment work for every possibility (every register, basically). Then I can modify increment to make a decrement. Then I can use increment and decrement for the addition and subtraction. I just wonder if it would be possible since they take command line arguments — I am planning on asking Matt. If so - then it is all go-ahead with the simulator!
This is a sample format for a dated entry. Please substitute the actual date for “Month Day, Year”, and duplicate the level 4 heading to make additional entries.
As an aid, feel free to use the following questions to help you generate content for your entries:
Remember that 4 is just the minimum number of entries. Feel free to have more.
Addition
Addition may not seem significant - but it's a huge part of the simulator. Understanding how it would be implemented will help greatly. If increment and decrement can be called (they need command line arguments though, so not sure how that would work) then it would be a matter of incrementing the first register whilst decrementing the other one to zero. If that is not possible, however, then it will be a case of manually adding the bits together (using a loop) with an if counter for the carry. It will be very similar to the increment logic. There is also the possibility of using XOR logic to add - but there will have to be an if to take care of the carrying over.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Tree Transversal
Tree traversal is the way that one can move around a binary tree. The method in which you move around and use the data can change what you are doing (sorting, printing from least to greatest, etc.). Because of the way that the tree works, one can do it iteratively, recursively, or stack based. The values have to be manipulated / stored outside of the tree as you traverse it, using a queue or a stack etc.
Recursion
Recursion is one technique for representing data that's size is not always known by the programmer. The implementation of recursion would be a function calling it's self in the function, there fore creating an infinite number of computations.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Identification of chosen keyword.
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Karnaugh Mapping
Karnaugh Mapping is a method by which one can take a truth table, or an expression, and simplify it. The working example on wikipedia is VERY useful in understanding this - I would recommend drawing it all out on a whiteboard and going by step-by-step. That is how I was able to grasp an understanding of it. I'll attach a photo as well showing how I worked through the example.
kleene star
Definition (in your own words) of the chosen keyword.
List any sites, books, or sources utilized when researching information on this topic. (Remove any filler text).
Karnaugh Mapping
Karnaugh Mapping is a method by which one can take a truth table, or an expression, and simplify it. The working example on wikipedia is VERY useful in understanding this - I would recommend drawing it all out on a whiteboard and going by step-by-step. That is how I was able to grasp an understanding of it. I'll attach a photo as well showing how I worked through the example.
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
Demonstration of the indicated keyword.
If you wish to aid your definition with a code sample, you can do so by using a wiki code block, an example follows:
/* * Sample code block */ #include <stdio.h> int main() { return(0); }
Alternatively (or additionally), if you want to demonstrate something on the command-line, you can do so as follows:
lab46:~$ cd src lab46:~/src$ gcc -o hello hello.c lab46:~/src$ ./hello Hello, World! lab46:~/src$
What is wrong with this hard drive?
Didn't collect info - just kind of winged it.
According to my friend, the hard drive is dead. He says he can't install an OS onto it, but he says it can store files just fine. I find this rather weird. He said I could keep it, so I want to get it working.
I'm going to see what's on the hard drive right now, delete everything on it, and try to install an OS onto it.
I checked the hard drive - it was completely un-formatted. I installed ubuntu onto it - it checked out okay.. but when I try to boot into it, it says that there is an error reading device. Something about a name mismatch or something. Weird. Wiped ubuntu off of it… installed debian. This time I noticed it actually installed grub - maybe that's what was wrong? No way to boot it? Yes! That was it! The hard drive is bootable now. Went ahead and put Windows 7 on it for gaming (since its a faster HD). I use the slower one for work, this new one for play. Fun.
from what I can tell, I think my friend had an issue getting the hard drive to boot because he wasn't giving it a boot partition which I think a hard drive needs. Installing grub fixed that, and then installing windows 7 installed the windows boot partition deal as well, so now the hard drive is happy. I have yet to run into the file lost horror stories he's told me about.
I'm happy I got a nice hard drive for free and got it to work.