As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/
Options

Giant Programming Clusterfuck++

NightslyrNightslyr Registered User regular
Shamelessly stolen from Janin's awesome OPs (all examples below written in Python):

Turning progamers into programmers hell yeah

I wrote up this wall of text while playing EVE. I hope that this thread will become a place where people new to programming can learn what languages are available, how to operate basic parts of programming, get help deciphering inscrutable homework assignments, etc. It might also serve as a useful repository for commonly-asked questions like "what is a pointer", "how do I write a function", etc.

Basic overview

In the code samples here, lines starting with the "#" character are comments. This means that they are not part of the program itself, but are instructions or notes to the reader.

Stuff that doesn't go anywhere specific

Always turn on compiler or interpreter warnings, and set them to maximum. If possible, make them errors rather than warnings. Compiler writers are very smart, and probably know more than you do. Read the documentation to your compiler or interpreter to determine how to set warning and error levels.

Variables

Variables are a way to "label" a certain value. They can be used to reduce code duplication. If you wanted to change the base value in the old code, you would have to update it in three places. In the new code, it only has to be updated in one.
# Old code
value1 = (5 * 10) + 5
value2 = (5 * 10) + 6
value3 = (5 * 10) + 7

# New code
base = 5 * 10
value1 = base + 5
value1 = base + 6
value1 = base + 7

To document code behavior. In the old code, the numbers "5", "10", and "100" are "magic numbers". Their purpose is unknown - may be it's how many cars have been sold, how many employees took the day off sick, or how many dollars were spent on candy bars. May be there's a comment hidden somewhere about its purpose, or may be not. In the new code, their purposes are inherently documented everywhere the variables are used.
# Old code
var = 100
income_today = var * 10 * 0.3

# New code
cent_multiplier = 100
net_dollar_income = 10
tax_rate = 0.3
income_today = net_dollar_income * cent_multiplier * tax_rate

In most modern languages, variables have "types". A type determines what values a variable can hold and what operations you can perform on it. For example, you can add two numbers, but cannot add a number and a string.

Common types of variables:
Boolean - May be either True or False, nothing else. In some primitive languages, such as C, the integers 0 and 1 are used instead of true and false.
Integer - A number with no fractional part.
Floating Point - A number that may contain fractional parts. Because computers only operate on Base 2 numbers, floating point math in most languages can give very "weird" values. For an example, enter "javascript:alert (0.1 + 0.2)" into your browser's URL bar.
String - An ordered list of characters. These might be letters like A, digits like 2, punctuation like !, or "unprintable" control characters such as a "new line" marker.
List - An ordered list of variables. These are usually accessed by a "0-based" index. For example, position 0 of the list (5 10 15 20) is 5, and position 3 is 20.

Conditionals

Conditionals are what separate a programming language from a mere list of equations. A conditional always has an if-block, and sometimes an else-block. In some languages, the two can be combined to save space. One thing to note here is the use of "==" to check for equality. Because "=" is used to assign to a variable, "==" checks if two values are equal.

An example of an if statement:
name = "Alice"
if name == "Alice":
        print "Hello Alice!"
else:
        if name == "Bob":
                print "Guten Tag Bob!"
        else:
                print "I don't know who you are."

# The same as above, with a combined 'elif' statement
name = "Alice"
if name == "Alice":
        print "Hello Alice!"
elif name == "Bob":
        print "Guten Tag Bob!"
else:
        print "I don't know who you are."

Loops

Loops are used to help reduce code duplication. If you have to do something many times, it's easier to put into a loop than try to write out every step. And if you want to change how many times something happens, it'll have to be in a loop.

The most basic form of the loop is the while loop. This loop will simply run over and over until some condition is met. If you make a mistake in the body, the loop might run forever and freeze your program.
x = 10
while x < 500:
        x = x * 10
print x

The other popular form of the loop is the for loop. A for loop is used for doing something once for every item in a group.
numbers = [5, 10, 15, 20, 25, 30]
# The number is: 5
# The number is: 10
# etc
for number in numbers:
        print "The number is: ", number


# The name is: Alice
# The name is: Bob
# etc
for name in ["Alice", "Bob", "Charlie", "David", "Eve"]:
        print "The name is: ", name

Nightslyr on
«13456763

Posts

  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Functions

    Functions are another tool for reducing duplicated code (see the pattern yet?). Just like a function in mathematics, a programming function takes some variables as input and returns some as output. Unlike mathematical functions, programming functions can do other things as well, such as save files or send stuff to the user. A function will run until it reaches a "return" statement, at which point it will give control of the program back to the parent function.

    Basic functions


    I'll define a simple function here, so you can see how it's put together. As an example I will use the Fibonacci function, which is defined thus:
    470072226d1629b5b6b973f1881b2051.png
    def fib (n):
            if n == 0:
                    return 0
            if n == 1:
                    return 1
            return fib (n - 1) + fib (n - 2)
    

    Keyword parameters

    Some languages support a concept known as "keyword parameters", which makes it easier to remember what goes where if the function has many parameters. An example using the income_today example from earlier:
    def income_today (net_dollar_income, tax_rate):
            cent_multiplier = 100
            return net_dollar_income * cent_multiplier * tax_rate
    
    print income_today (net_dollar_income = 10, tax_rate = 0.3)
    

    Functions as parameters

    As one last functional feature, some languages support functions as parameters! These are fun. I'll use an example of searching a list for a value that matches the passed in function. This code sample will check if a list of names contains "Alice" or "Bob".
    def matcher (x):
            if (x == "Alice") or (x == "Bob"):
                    return True
            return False
           
    def exists_in (list, match_func):
            for item in list:
                    if match_func (item):
                            return True
            return False
           
    # Prints "True"
    print exists_in (["Alice", "Charlie", "David"], matcher)
    
    # Prints "False"
    print exists_in (["Charlie", "David", "Eve"], matcher)
    

    Nightslyr on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Types of languages

    Languages are broadly split into two categories, dynamic and static. A static language has types fixed when it's run. If a function in a static language expects to get an integer, you can't pass it a float instead. For this guide, I will be focusing on dynamic languages, because I find them easier to read, write, and maintain. Specifically, I will cover Python (my personal favorite), with a small detour into Javascript.

    Dynamic languages

    An incomplete list of popular dynamic languages:
    Python - Popular for everything from game scripting (Battlefield 2, Civilization 4) to web applications to physics simulations. My personal favorite.
    Ruby - A less well-known language than Python, Ruby has seen a resurgence with the advent of Rails, a popular web application development framework.
    Lisp - A somewhat popular language following the "functional" paradigm, the basis for programs such as GNU Emacs and...uh...
    Smalltalk - Still one of the best object-oriented languages around. Many of the ideas in Smalltalk were used in Objective C, which forms the basis for much of OS X.
    Perl - Very popular for UNIX scripting, but is infamous for being rather easy to make incomprehensible.
    ECMAScript/Javascript - The most popular and widely installed language on the planet. Has gained a reputation as a horribly awful language due to incompetant monkeys writing in it, but in reality it's only moderatly awful.

    Python
    One of the most popular dynamic languages, used for everything from large websites like Google to game scripting. All data is modeled as "dictionaries" -- otherwise known as "associative arrays" or "hash tables" in other languages. Objects, modules, and full libraries are simply dictionaries of attributes. Python is also a philosophy -- well-written code is said to be "Pythonic" if it obeys the Python philosophy, which emphasizes explicit behavior and "one obvious way to do it". Python is said to be "batteries included", and features a massive standard library.

    Ruby
    Borrows the good ideas from Perl, Smalltalk, and Lisp. All data is contained in objects, and all objects communicate by passing around "messages". Message passing is the distinguishing characteristic of Ruby and Smalltalk. It allows very flexible programming by making a class responsible for *all* of its behavior. Want to set the "bar" attribute of object "foo"? When you execute "foo.bar = 1", you're actually performing "foo.bar= (1)". No modifications to an objects state are permitted except through its messages.

    ECMAScript/Javascript

    Crazy shit, "some text" + 10 = "some text10" instead of an error. Use a library like jQuery or you will go mad.

    Static languages

    Rather than try to describe all the differences between dynamic and static languages all at once, here's an example of printing out names from earlier. Keep in mind that both versions are the full program (C++ example):
    #include <stdio.h>
    
    #define NAME_COUNT 5
    
    int main ()
    {
            char *names[NAME_COUNT] = {"Alice", "Bob", "Charlie", "David", "Eve"};
            for (int index = 0; index < NAME_COUNT; index = index + 1)
            {
                    char *name = names[index];
                    printf ("The name is: %s\n", name);
            }
           
            return 0;
    }
    

    There are several things to notice here:
    - The definition of the main() function. A static language such as C requires that all code be placed in functions. In practice you will rarely write code outside of a function in any language, but it can be helpful for learning how to program.
    - The code uses an array, rather than a list. The nuances of arrays are discussed in a following post.
    - The for loop is dramatically different. Rather than simply passing each value into the block, the user must manually construct, check, and update an index variable.
    - The print function requires that the user specify what is being printed (a string, "%s"). If you specify an incorrect type code, the program is likely to crash.

    For this reason, I do not advise new programmers to immediately jump into using languages such as C/C++/C#/Java. When you've learned how to walk, then you can learn how to walk in lead boots. I especially ask that you do not start with any dialect of Basic, because the available good example code is dwarfed by the amount of bug-riddled, insecure garbage.

    Nightslyr on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    This page is TODO because OOP is a big subject and I wanted to get the rest up first.

    EDIT: I've added some more to this, but I'm really lazy and OOP is a big subject.

    Object-oriented Programming

    The two core principles of object-oriented design are information hiding and behavior sharing. Rather than a mass of single-purpose functions, bundle them together to provide a clean interface for the rest of the code to access.

    Information hiding

    Just as a function protects other code from having to know what operations it goes through to arrive at a conclusion, OOP protects other code from knowing what function is being called and what data is being used. If you create an object with certain data and then pass it to a function, the function does not know and does not need to know what data the object was created with. The object can be treated as a magic black box that spits out answers. If you use a functional language like Haskell or Lisp, closures provide much the same function.

    It also allows for sane state management - rather than a giant grab-bag of global variables that might get modified who-knows-where, the object's variables are protected from unknown modifications. This can come in very handy during debugging, when you need to know when a data value is (for example) being set to something invalid. If it's a global, you would have to put print statements all over the place or trust in a debugger. If you use an object, you can put in many less statements (or breakpoints, whatever). Obviously, the closer access to an attribute is controlled within the object, the fewer "chokepoints" there will be for the data.

    Note that this does not mean that you should hide all attributes behind get_ functions. I see this annoying pattern a lot in Java programmers, because they've had OOP slammed down their throats in a language that doesn't support properties. If the purpose of your class is to simply contain a bunch of data with no behavior, just make all the attributes public. Please do not ever write classes that look like this (might not compile, been a while since I used Java, but you get the idea):
    /**** DO NOT DO THIS, DO NOT DO THIS, DO NOT DO THIS ****/
    class DataContainer {
            private final int a, b, c, d;
            public DataContainer (int _a, int _b, int _c, int _d)
            {
                    a = _a;
                    b = _b;
                    c = _c;
                    d = _d;
            }
           
            int get_a () { return a; }
            int get_b () { return b; }
            int get_c () { return c; }
            int get_d () { return d; }
    }
    /**** DO NOT DO THIS, DO NOT DO THIS, DO NOT DO THIS ****/
    

    Behavior Sharing

    Say you've got two classes for printing that share some of code, but have parts that are different:

    By moving the common code into a shared parent class, you can reduce code duplication. This is probably easiest to see with an example, so I'll use a hypothetical printing library. This library can handle both laser printers and ink printers:
    class LaserPrinter:
            method calculate_size ():
                    size = 10
                   
            method print ():
                    calculate_size ()
                    feed_paper ()
                    check_toner_level ()
                    warm_up_laser ()
                    fancy_laser_stuff ()
                    check_supplies ()
                    warn_on_low_supplies ()
                   
    class InkPrinter:
            method calculate_size ():
                    size = 10
                   
            method print ():
                    calculate_size ()
                    feed_paper ()
                    fancy_ink_stuff ()
                    clean_excess_ink ()
                    check_supplies ()
                    warn_on_low_supplies ()
    

    Note the duplicated code. This problem can be reduced if you move the common code into a parent class, and then inherit from it:
    class Printer:
            method calculate_size ():
                    size = 10
                   
            method print ():       
                    calculate_size ()
                    feed_paper ()
                    fancy_parts ()
                    check_supplies ()
                    warn_on_low_supplies ()
                   
    class LaserPrinter (Printer):
            method fancy_parts ():
                    check_toner_level ()
                    warm_up_laser ()
                    fancy_laser_stuff ()
                   
    
    class InkPrinter (Printer):
            method fancy_parts ():
                    fancy_ink_stuff ()
                    clean_excess_ink ()
    

    Nightslyr on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Pointers and Arrays

    The dynamic (and some static) languages above do a very nice job of hiding implementation details for variables. However, if you want to get anywhere with C or C++ you must learn how pointers and arrays operate. The two are one and the same, so I will cover both at once.

    First, some definitions. A pointer is a variable that points to another variable. An array is like a list, but has a size fixed when it is created. Within the computer, memory can be treated as a massive one-dimensional array. When you create a variable (say, an integer) the computer will calculate the amount of memory required, allocate it from the available memory, and give you a pointer to that memory size. Anything you want can be stored in there, not just what type you originally asked for, but don't get crazy or people will hate you and your code. While in dynamic languages variables are "labels", in a static language variables are "boxes".

    There is another important difference between an array and a list. An array can only hold one type of object (specifically, each cell in an array is of a fixed size equal to the size required for each instance of the array's contained type). For example, say you were to construct an array of 4 32-bit integers. Each cell of the array will be 32 bits long, for a total of 128 bits. You can construct a list such as [1, "Hello", ["lol", "wow"]], but an array can only hold whatever the array was created for.

    Here's an example of using pointers to manipulate integer variables in C:
    int a; /* a is an integer with no set value */
    int b = 5; /* b is a separate variable, set to 5 */
    int *c = &a; /* c is a pointer to a */
    int *d = &a; /* d is a pointer to a */
    
    /*
    At this point, our memory looks like this:
    a: undefined
    b: 5
    c: <address of a>
    d: <address of a>
    */
    
    /* A pointer can be re-assigned to point to a different slot in memory */
    d = &b; /* d is now a pointer to b */
    
    /* A pointer can be "de-referenced" to access the variable it is pointing to. %d is the code for a decimal integer. */
    printf ("b = %d, *d = %d\n", b, *d); /* Prints "b = 5, *d = 5" */
    
    /* If the de-referenced pointer is modified, the variable it points to is also modified. This is truly Spooky Action at a Distance */
    *d = 10;
    printf ("b = %d, *d = %d\n", b, *d); /* Prints "b = 10, *d = 10" */
    
    /* In this line, we set the value for the "a" variable without accessing it. It could be in an entirely separate part of the program */
    *c = 5;
    printf ("a = %d, *c = %d\n", c, *c); /* Prints "a = 5, *c = 5" */
    

    Now, to tie all this into arrays. An array is actually treated, internally, as a pointer. You can dereference it, modify it, whatever. What's more, you can treat normal pointers like arrays! An example:
    int array[3] = {7, 8, 9}; /* Array of 3 integers */
    int a = 5, b = 10;
    int *a_ptr = &a;
    
    /* Dereferencing an array returns the first value of that array */
    printf ("array[0] = %d, *array = %d\n", array[0], *array); /* Prints "array[0] = 7, *array = 7" */
    
    /* A pointer can be treated like an array */
    printf ("a_ptr[0] = %d\n", a_ptr[0]); /* Prints "a_ptr[0] = 5" */
    
    /* Because arrays are contiguous memory space, moving the pointer around will move around in the array */
    /* This is how the [] operator is implemented */
    printf ("array[1] = %d, *(array + 1) = %d\n", array[1], *(array + 1)); /* Prints "array[1] = 8, *(array + 1) = 8" */
    
    /* If your pointer is pointing to contiguous variables, you can do the same thing */
    printf ("b = %d, a_ptr[1] = %d, *(a_ptr + 1) = %d\n", b, a_ptr[1], *(a_ptr + 1)); /* Prints "b = 10, a_ptr[1] = 10, *(a_ptr + 1) = 10" */
    

    Nightslyr on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    This page reserved for any other intro info that other people want.

    Nightslyr on
  • Options
    ObsObs __BANNED USERS regular
    edited January 2009
    You should add threading.

    Obs on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Obs wrote: »
    You should add threading.

    Since I'm still more or less a beginner myself, I'll need someone to PM me some notes on that. Is threading even appropriate for a beginner programming thread, though?

    Nightslyr on
  • Options
    iTunesIsEviliTunesIsEvil Cornfield? Cornfield.Registered User regular
    edited January 2009
    Meh, we get more than beginner questions in the thread sometimes. I can write some C# threading stuff for you, but if you want a language outside of that you'd need to talk to someone else. :)

    iTunesIsEvil on
  • Options
    bowenbowen How you doin'? Registered User regular
    edited January 2009
    Threading becomes a nightmare outside of anything but .NET, or other CRE languages, in my experience. I hate doing it in C++.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    C# sounds like the best option, then. I remember trying to do/simulate threading in C about 8 years ago. I was thoroughly confused.

    Nightslyr on
  • Options
    BlueSquareBlueSquare Registered User regular
    edited January 2009
    bowen wrote: »
    Threading becomes a nightmare outside of anything but .NET, or other CRE languages, in my experience. I hate doing it in C++.

    What is a CRE language?

    BlueSquare on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    BlueSquare wrote: »
    bowen wrote: »
    Threading becomes a nightmare outside of anything but .NET, or other CRE languages, in my experience. I hate doing it in C++.

    What is a CRE language?

    Maybe they mean CLR?

    Nightslyr on
  • Options
    KrisKris Registered User regular
    edited January 2009
    I remember tackling threading in Java during one of my introductory computer science courses, while we were making this plane dogfighting game. It was horrible and couldn't get my threads running properly. A little write-up would be much appreciated, even if it is for C#. :D

    Kris on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Well, someone's going to have to PM me about threads, because like I said before, I know jack about them.

    Nightslyr on
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    bowen wrote: »
    Threading becomes a nightmare outside of anything but .NET, or other CRE languages, in my experience. I hate doing it in C++.

    Its implementation of threads is clearly more fundamental but its very doable on C or C++ if you're in the right C frame of thought. And 99.9% of the time a simple fork()s in C works just as well and will likely be faster since you don't have to go through the added overhead of the framework. C# is nice and all but it always feels really bulky whenever I use it and I can't really imagine using it for something so performance sensitive that threading must be used instead of simple forking.

    Of course, I get to use the FUBAR'd proprietary language developed in the 70s (or technically its 2nd generation descendant, the other half is its early 90s fourth generation descendant, also proprietary). Therefore I probably shouldn't criticizing perfectly reasonable languages like C#.
    Kris wrote: »
    I remember tackling threading in Java during one of my introductory computer science courses, while we were making this plane dogfighting game. It was horrible and couldn't get my threads running properly. A little write-up would be much appreciated, even if it is for C#. :D

    This is a problem with how we're teaching programming in the US. About the most complicated thing that should be done in an introductory course is Towers of Hanoi.

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    Nightslyr wrote: »
    Now, to tie all this into arrays. An array is actually treated, internally, as a pointer. You can dereference it, modify it, whatever. What's more, you can treat normal pointers like arrays! An example:
    int array[3] = {7, 8, 9}; /* Array of 3 integers */
    int a = 5, b = 10;
    int *a_ptr = &a;
    
    /* Dereferencing an array returns the first value of that array */
    printf ("array[0] = &#37;d, *array = %d\n", array[0], *array); /* Prints "array[0] = 7, *array = 7" */
    
    /* A pointer can be treated like an array */
    printf ("a_ptr[0] = %d\n", a_ptr[0]); /* Prints "a_ptr[0] = 5" */
    
    /* Because arrays are contiguous memory space, moving the pointer around will move around in the array */
    /* This is how the [] operator is implemented */
    printf ("array[1] = %d, *(array + 1) = %d\n", array[1], *(array + 1)); /* Prints "array[1] = 8, *(array + 1) = 8" */
    
    /* If your pointer is pointing to contiguous variables, you can do the same thing */
    printf ("b = %d, a_ptr[1] = %d, *(a_ptr + 1) = %d\n", b, a_ptr[1], *(a_ptr + 1)); /* Prints "b = 10, a_ptr[1] = 10, *(a_ptr + 1) = 10" */
    

    You should probably include something about allocation here. And multidimensional arrays. Oh and casting.
    Something like:
    int** stuffDoneHere(int x, int y)
    {
    int z=0;
    int ** multiArray=(int**)malloc(sizeof(int*)*x);
    for(z=0;z<y;z++)
    {
       multiArray[z]=(int*)malloc(sizeof(int)*y));
    }
    return multiArray;
    }
    
    But I allocate my memory idiosyncratically (I'd been using malloc for arrays for a year before someone pointed out I should be using calloc). And sorry if my rusty C code is f'ed up I'm not by a compiler to check.

    Oh and this would be a decent place to go into standard error output. And from there you get to files pretty easily.

    edit:

    Frustration rant - I miss C. That is a fucking elegant language. Its mysteries are deep and its truth powerful. This is the crap I get to code in
    DO{@Next(account) @pe.last.txn[20071130,account]^FIRST,@pe.last.txn[20071231,account]^LAST,
    "O"^txn.class,FIRST^txn.urn,
    DO{@Next(txn.urn),txn.urn'>LAST IF{@RA @GET.BATCH,1^?(B).BJAX,
    IF{'BAR.BCH.urn 1^?(B).BJAERR[account,txn.urn,"NO BATCH on BYR"];
    @BAR.BCH.status'="POSTED" 1^?(B).BJAERR[account,txn.urn,BAR.BCH.urn,"NOT POSTED"];
    @txn.amount+?(B).BJAAMT[@txn.type,@bar.status]^?(B).BJAAMT[@txn.type,@bar.status]}}}};

    RA
    IF{@txn.type="A";@txn.type="R"}

    GET.BATCH
    @BAR.BCH.number.x[@txn.bch.date,@txn.bch]^BAR.BCH.urn

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
  • Options
    Mr.FragBaitMr.FragBait Registered User regular
    edited January 2009
    Here is an example of threading in python, which might be easier to understand than c# for beginners.
    The lack of syntax coloring makes it hard to read though. And the php tags made it look atrocious.
    #simple multiple producer one consumer example in python
    from threading import Thread #import Thread class
    from Queue import Queue #implements all needed locking
    import time #needed to access sleep method
    
    def producer(given_queue, to_produce, num_times, wait):
        """this is a function that when run as a thread will
    put the given item into the queue a number of times, waiting
    the fractions of seconds in wait"""
        for num in range(num_times):
            given_queue.put(to_produce)
            time.sleep(wait)
    
    def consumer(given_queue):
        """this function will print the things in the queue, will
    stop when None is found"""
        while True:
            item = given_queue.get()
            if item is None:
                return
            print item
    
    if __name__ == '__main__':
        #queue that is shared between all threads
        queue = Queue()
        #make a thread that will add 'first' to queue ten times
        pro1 = Thread(target=producer, args=(queue, 'first', 10, .0001))
        #make a thread that will add 'second' to queue ten times
        pro2 = Thread(target=producer, args=(queue, 'second', 10, .0001))
        #change the thread waits to see how it changes the output, even though
        #both threads have similar timings they will not always go in the same
        #order, showing that the threads are asynchronous
    
        #make a thread that will consume whatever is in the queue
        cons = Thread(target=consumer, args=(queue,))
    
        #start threads, these will run independently of each other and this
        #main thread
        pro1.start()
        pro2.start()
        cons.start()
        
        def kill_consumer():
            #wait on the producers
            for producer in (pro1, pro2):
                producer.join()
    
            #now that all producers done, tell consumer everyone is finished
            queue.put(None)
    
        Thread(target=kill_consumer).start()
    

    Mr.FragBait on
  • Options
    AngelHedgieAngelHedgie Registered User regular
    edited January 2009
    Actually, Nightslyr, the three (yes, three) principles of OOP are encapsulation (what you called information hiding), inheritance (what you called behavior sharing), and most important, polymorphism.

    Polymorphism Made Simple

    So, what is polymorphism? Simply put, it's that objects remember what they are and behave accordingly, even when they're referenced through a parent class.

    For example, let's say we make a Mammal class, with a function Speak that doesn't return anything:
    public class Mammal
    {
       public Mammal()
       {
       }
    
       public string Speak()
       {
          return "";
       }
    }
    

    Now, let's make some child classes depicting other animals:
    public class Dog : Mammal
    {
       public Dog() : base()
       {
       }
    
       public override string Speak()
       {
          return "Woof\n";
       }
    }
    
    public class Cat : Mammal
    {
       public Cat() : base()
       {
       }
    
       public override string Speak()
       {
          return "Meow\n";
       }
    }
    
    public class Pig : Mammal
    {
       public Pig() : base()
       {
       }
    
       public override string Speak()
       {
          return "Oink\n";
       }
    }
    
    public class Human : Mammal
    {
    
       private string _name = "";
    
       public Human(string Name) : base()
       {
           _name = Name;
       }
    
       public override string Speak()
       {
          return "Hi, I'm " + _name + ".\n";
       }
    }
    

    Now, we'll create an ArrayList of Mammals, then ask them to speak.
    ArrayList<Mammal> MammalList = new ArrayList<Mammal>();
    MammalList.Add(new Dog());
    MammalList.Add(new Cat());
    MammalList.Add(new Pig());
    MammalList.Add(new Human("Bob"));
    
    string speech = "";
    
    foreach (Mammal m in MammalList)
    {
        speech += m.Speak();
    }
    
    label1.Text = speech
    

    The label will now say:
    Woof
    Meow
    Oink
    Hi, I'm Bob.

    As you're already pointing out, I called each of the elements in the example as Mammals, though, not as their specific child class. But because of polymorphism, eash of those Mammals remembered what they were, and called their specific version of the Speak function.

    AngelHedgie on
    XBL: Nox Aeternum / PSN: NoxAeternum / NN:NoxAeternum / Steam: noxaeternum
  • Options
    AngelHedgieAngelHedgie Registered User regular
    edited January 2009
    Loops Part Two: The Loopening

    There are two more types of loops used in modern programming languages that you'll see. The first is called a do-while loop, and is used when you want a while loop to execute at least once.
    int x = 1;
    int y = 1;
    
    do
    {
       x = x + 1
    }
    while (x <= 0)
    
    while (y <= 0)
    {
       y = y + 1;
    }
    

    In the above example, you will have x equal to 2, but y equal to 1. This is because the while statement is evaluated at the start of the while loop, but at the end of the do-while loop.

    The other form of loop is a relative newcomer, only seen in newer languages and addon libraries for older OO languages like C++. It's called a foreach loop, and is used to run a function across all elements of a collection (like an array).
    int[] intArray = [1, 2, 3, 4, 5];
    
    foreach (int i in intArray)
    {
       i = i + 3
    }
    

    This will add 3 to each element in the array, giving us [4, 5, 6, 7, 8].

    Doing this with a for loop is much more work:
    int[] intArray = [1, 2, 3, 4, 5];
    
    for (int i = 0, i < 4, i++)
    {
       intArray[i] = intArray[i] + 3;
    }
    

    Note that the syntax of the foreach loop is much simpler than that of the for loop.

    AngelHedgie on
    XBL: Nox Aeternum / PSN: NoxAeternum / NN:NoxAeternum / Steam: noxaeternum
  • Options
    EtheaEthea Registered User regular
    edited January 2009


    The other form of loop is a relative newcomer, only seen in newer languages and addon libraries for older OO languages like C++. It's called a foreach loop, and is used to run a function across all elements of a collection (like an array).

    Could also explain it uses an iterator, and what that is.

    Ethea on
  • Options
    AngelHedgieAngelHedgie Registered User regular
    edited January 2009
    Ethea wrote: »


    The other form of loop is a relative newcomer, only seen in newer languages and addon libraries for older OO languages like C++. It's called a foreach loop, and is used to run a function across all elements of a collection (like an array).

    Could also explain it uses an iterator, and what that is.

    Actually, foreach doesn't use an iterator.

    AngelHedgie on
    XBL: Nox Aeternum / PSN: NoxAeternum / NN:NoxAeternum / Steam: noxaeternum
  • Options
    BlueSquareBlueSquare Registered User regular
    edited January 2009
    Ethea wrote: »


    The other form of loop is a relative newcomer, only seen in newer languages and addon libraries for older OO languages like C++. It's called a foreach loop, and is used to run a function across all elements of a collection (like an array).

    Could also explain it uses an iterator, and what that is.

    Actually, foreach doesn't use an iterator.


    Actually, it does in the CLR languages (really enumerator here). It only unrolls to a 'for loop' on intrinsic types.

    BlueSquare on
  • Options
    NightslyrNightslyr Registered User regular
    edited January 2009
    Ack, so many replies/revisions! I'll get to work on all those tomorrow. Thanks for all of the input so far, everyone.

    Nightslyr on
  • Options
    AngelHedgieAngelHedgie Registered User regular
    edited January 2009
    Iteration Vs. Recursion

    There are actually two ways to repeat code - iteration, where we loop over and over through a piece of code; and recursion, where we call a function inside of itself. Let's take a look at Nightslyr's Fibonacci function:
    int fib(int n)
    {
       if (n == 0)
          return 0;
       if (n == 1)
          return 1;
       return fib (n - 1) + fib (n - 2);
    }
    

    This is an example of a recursive function. If you look at the bottom, you can see that to get any value past the first 2, we call the function inside of itself. That said, we could write the same function iteratively:
    int fib2(int n)
    {
       if (n == 0)
          return 0
       if (n == 1)
          return 1 
       else
       {
          int v1 = 1;
          int v2 = 1;
          int temp = 0;
          n = n-2
          for (int i = 0; i < n; i++)
          {
             temp = v1 + v2;
             v1 = v2;
             v2 = temp;
          }
          return v1 + v2;
       }
    }
    

    That will do the exact same thing as the recursive example. However, it is a bit more complicated.


    Now, here's the kicker - which one would you use to calculate, say...the 5th Fibonacci number? How about the 25th? I would use the recursive function to get the first, but the iterative one to get the 25th. The reason is simple - while the iterative function is more complex, it always remains at the same level of complexity. In comparison, watch what happens when we start looking at the mechanism of the recursive function:

    fib(2) = fib(1) + fib(0) = 1 + 1 = 2
    fib(3) = fib(2) + fib(1) = (fib(1) + fib(0)) + fib(0) = (1 + 1) + 1 = 3
    fib(4) = fib(3) + fib(2) = (fib(2) + fib(1)) + (fib(1) + fib(0)) = ((fib(1) + fib(0)) + fib(1)) + (fib(1) + fib(0)) = ((1 + 1) + 1) + (1 + 1) = 5

    And so on. As you can see, the recursive function increases in complexity in a geometric fashion, whereas the iterative version increases arithmetically.

    AngelHedgie on
    XBL: Nox Aeternum / PSN: NoxAeternum / NN:NoxAeternum / Steam: noxaeternum
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    (I'll essentially be using psuedo code below. I think AH is using C# and I'm trying to remain consistent but its been 2 years since I used it)

    Polymorphism is probably the central concept behind OOP, and one of the more difficult to fully grasp. Its also one of the few areas where different languages require fundamentally different designs depending on their implementation of inheritance.

    Abstract Classes
    Consider: What if you were using the above Mammal system. No animal is simply a "Mammal" and there is no "Mammal" noise to make when it speaks. The system should thus be prohibited from creating an instance of "Mammal" as this does not reflect reality.

    While this may appear harmless in other examples it could lead to instability and security holes.

    This is achievable through an "abstract class."
    abstract private class Mammal
    {
      public virtual string Speak();
    
    }
    
    Not there is no Constructor, nor is there any code behind Speak(). The lack of code behind Speak is optional, but by using the virtual keyword, any non-abstract subclass must implement Speak.

    Time is running short (I want to bang out a few more things before 530 when I'm out of here), so forgive the pseudo-code here on out.

    Multiple inheritance:
    In some languages (C++, LISP, Python), a class can inherit from more than one class. Other languages (Java, C#, PHP) you can inherit obligations through more than one class if you use a specific type of abstract class called an "interface." The former is increasingly deprecated because (in part) of the diamond problem.

    The above example could have "Mammal" as an interface if we removed the name attribute (or made it some combination of final, constant and/or static depending on the language).
    Interface Vendor
    {
    public bool takeMoney();
    protected bool evaluateChoice();
    public bool receiveChoice();
    protected bool dispenseToy(Object x);
    }
    

    Any vendor - a coke machine, a candy machine, a cigarette machine, or a robot bartender would have to implement those features.
    Class RobotBarKeep extends Robot implements Vendor
    {
    /*etc*/
    }
    


    There's more if anyone wants to tackle Final classes and probably more important the static concept, fire away.

    Oh and Linked Lists. That should probably be covered in combination with recursion, right before Tower of Hanoi

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
  • Options
    ObsObs __BANNED USERS regular
    edited January 2009
    Intro to Cocoa Programming (Mac OS X)


    What you will need: a Mac and Xcode Developer Tools. You can buy a Mac from your local Apple store and Xcode should be available online as well, some say it also comes on the installation DVD with most Macs.

    Prerequisites: You should be familiar with object oriented concepts and programming in general, as these are universal things that may not be specific to Cocoa. If you already know C and at least one object oriented language such as C++ or Java, you will do well and learn fast as fuck.

    I'll update this section here regularly with new stuff over time, so check back every once and a while because I can tell already I'm probably not going to write all this stuff in one sitting. If you have any questions PM me or ask in the thread (but I don't really keep up with every page of this thread).

    So let's begin.



    Part 1: Objective C 2.0

    This language is what you will use to do your Cocoa programming. If I had to describe Objective-C, I would basically tell you it's C with powerful object oriented shit added to it. C is a complete subset of Objective-C, which means any Objective-C compiler will also compile pure C code; you can freely mix C, C++ and Objective-C code together in the same application without problems. This gives you a powerful advantage, because you have the ease of high level coding like with Java and C#, but you are not restricted to it all the time (so you could do some custom optimization).

    Because of this, a good Objective-C programmer should also be a good C programmer.

    In Objective-C there exist things called objects. Objects are basically structures that carry two things, variables and methods. An object is defined by a class. The class describes the format of the object, meaning it tells you what variables the object has and their types, and what methods the objects run and what they return. In Objective-C, a class is also used to allocate an object.

    When you want an object to run a certain method, you send it a message. There is a certain format to sending a message to an object, it looks like this:
    [objectRecievingMessage messageBeingSent];
    


    Notice this is dramatically different from some languages where you may write something like:

    object.Function();


    Well, it gets wierder. If you are sending messages with parameters, they start to look like this
    [objectRecievingMessage messageBeingSentWithParameterOne: 55.0  ParameterTwo: 958.0 ParameterThree: 46.0];
    

    It looks bizarre at first, the function being peppered with parameters all up inside it like that, but the end result is some very readable code. The format for the messages is defined of course when you write the classes.

    In Objective-C there is also a variable of type id. An id variable stands for object identifier. You can think of an id as a pointer to any type of object. So if you see a method that returns a type "id", it means it returns a pointer to an object. Because an id can be any object type, you don't really know shit about it other than the fact that it IS an object.



    A class is defined by two files: a header file (.h) and an implementation file (.m). Xcode generally creates both these files when you go to define a new class.

    Here is an example of a class definition, in it's own file called noobert.h
    #import <Foundation/Foundation.h> [I] ////This line adds all the necessary header files for Cocoa.
    [/I]
    
    @interface noobert : NSObject {[I] ////This line means you are defining an interface for a class named noobert, which inherits the instance and method variables of the class [b]NSObject[/b].[/I]
         
         int one; [I]///standard int[/I]
         float two; [I] ///standard float[/I]
    }
    
    -(float)multiplyNumbers; [I] //this defines a method that returns a float[/I]
    -(void)printGarbage;      [I]//this defines a method that returns nothing[/I]
    -(void)newNumbersForFirst:(int)num1 Second:(float)num2;[I]              //And this method returns nothing and takes two parameters, num1 and num2, of type int and float respectively.[/I]
    
    @end    [I]//and here we know that the class definition has come to an end. [/I]
    
    #import <Foundation/Foundation.h> 
    
    @interface noobert : NSObject {
         
         int one; 
         float two; 
    }
    
    -(float)multiplyNumbers; 
    -(void)printGarbage;     
    -(void)newNumbersForFirst:(int)num1 Second:(float)num2;
    
    @end    
    

    And here is the implementation of that class, in a separate file called noobert.m
    #import <Foundation/Foundation.h>
    #import "noobert.h"     [I]////Notice we have to import the .h file for the class to this .m file so it can know what the hell is going on. We use quotes because it's a file we created here in the project.[/I]
    
    @implementation noobert     [I] ////Now this line lets us know we are implementing methods for the noobert class.[/I]
    
    
    -(float)multiplyNumbers {
    
         return (one * two); [I]//returns the result of multiplying these two numbers, which will be a float. [/I]
    }
    
    
    -(void)printGarbage {
    
          printf("\n get the fuck outta here"); [I]//prints a line to the console, wherever that is. [/I]
    }    
    
    -(void)newNumbersForFirst:(int)num1 Second:(float)num2 {
    
          one = num1;
          two = num2;
    } 
    
    @end         [I]// implementation is over at this point[/I]
    
    #import <Foundation/Foundation.h>
    #import "noobert.h"    
    @implementation noobert 
    
    
    -(float)multiplyNumbers {
    
         return (one * two);
    }
    
    
    -(void)printGarbage {
    
          printf("\n get the fuck outta here");
    }    
    
    -(void)newNumbersForFirst:(int)num1 Second:(float)num2 {
    
          one = num1;
          two = num2;
    } 
    
    @end        
    



    So now suppose we have this class called noobert, and we wish to create an object of type noobert.

    We will need to create a variable, allocate memory for the noobert object, and then initialize it. It works like this (assuming all this code is a part of something larger):
    noobert *variableName;      [I]//The * means this is a pointer to an object of type noobert. We do not create statically defined objects. If you try you will get an error. [/I]
    
    variableName = [[noobert alloc] init];   
    
    [I]///In the line above you are telling the class to allocate memory for a new object of it's type. The alloc function returns an object of type "noobert". Then, for that object, you call it's init function which prepares the new object instance for use. If you think it's weird that something abstract like a class could receive a message like that in Objective-C, don't worry about it. I think every class in Objective-C actually creates it's own instance at the start of a program that serves a single purpose of creating new objects of it's own type, but I could be horribly wrong. Either way, doesn't really matter. [/I]
    
    
    //and now the new object can be used for stuff. 
    
    int small;
    [variableName printGarbage];
    float value = [variableName multiplyNumbers];
    small = (value * 2);
    [variableName newNumbersForFirst:small Second:[variableName multiplyNumbers]];
    
    //etc...
    
    






    Ok well I've talked about Objective-C this whole time and I actually haven't said anything about Cocoa yet so I'll have to continue later because I'm going to sleep.

    I don't really know how much more I'll write about Objective-C, I mean I could basically go on forever, and I've only scratched the syntactic surface here. It's a simple language to learn though if you have the right background, so next update I'll show you how to start building applications right away, complete with full UI and stuff, no command line BS. Peace.




    Part 2: Building a Cocoa Application

    coming soon

    update: in case anyone cares, I'll get to this eventually, sorry I'm just pretty loaded with work right now

    Obs on
  • Options
    noobertnoobert Registered User regular
    edited January 2009
    Obs wrote: »
    Intro to Cocoa Programming (Mac OS X)


    Reserved.

    waitin' on 'dis.

    noobert on
  • Options
    BlueSquareBlueSquare Registered User regular
    edited January 2009
    As relating to .NET languages, (syntax is C#):

    An abstract class can not be marked private. That would defeat the purpose of being inherited. It can be marked public or internal.

    If a method must be implemented by sub classes (edit: i had weird wording here), it is marked abstract, such as your Speak() method. It is not a virtual method.

    Abstract classes can certainly have a constructor and any other implementation that is seen in non-abstract classes.

    An Interface is not an abstract class at all. It is a special type that defines a contract that the object that implements the interface is bound to uphold. There is not much else to it than that. Interfaces also can not define the accessor on it's members. IOW, you can not tell the implementer that they must set function Foo to private.

    One important concept I have not yet seen discussed is the concept of immutability.

    BlueSquare on
  • Options
    ASimPersonASimPerson Cold... and hard.Registered User regular
    edited January 2009
    As the user with the 11th-most posts in the old thread, let me state here:

    Ask some freakin' C questions :)

    ASimPerson on
  • Options
    ecco the dolphinecco the dolphin Registered User regular
    edited January 2009
    ASimPerson wrote: »
    As the user with the 11th-most posts in the old thread, let me state here:

    Ask some freakin' C questions :)

    I second this sentiment.

    Although I get the feeling we're getting a bit long in the tooth, old friend. Back in my days, I remember having to write assembly bitblt instructions by hand to work with SVGA graphics (640 x 480 x 16-bit colour!? WOW!!! I think my S3 video card had enough video memory to do 800 x 600 x 16-bit colour as well!). See, it was real mode on the x86 back then - I hadn't quite mastered protected mode, so I could only access 64k of video RAM at any time. Ahh, bank switching.

    Remember EMS and XMS? You wanted more than 640k but didn't want to go into protected mode? EMS and XMS were the only real ways (well, there was that fake real mode with 32-bit flat memory addresses that you could get into, but that required you to remove memory managers like himem.sys and emm386, so it didn't feel that good).

    Learning how to use DMA to pipe sound out to sound-blaster compatible cards.

    Man, those were the days.

    Now, you get callbacks and HALs and whatever else to do everything for you.

    Times have changed, I say. Perhaps for the better, but I still remember the shock I had when I finally played a wav file through my speakers (okay, I had calculated the sample rate wrong, so it played about 4 times as fast or something - but still!).

    ecco the dolphin on
    Penny Arcade Developers at PADev.net.
  • Options
    ASimPersonASimPerson Cold... and hard.Registered User regular
    edited January 2009
    ASimPerson wrote: »
    As the user with the 11th-most posts in the old thread, let me state here:

    Ask some freakin' C questions :)

    I second this sentiment.

    Although I get the feeling we're getting a bit long in the tooth, old friend. Back in my days, I remember having to write assembly bitblt instructions by hand to work with SVGA graphics (640 x 480 x 16-bit colour!? WOW!!! I think my S3 video card had enough video memory to do 800 x 600 x 16-bit colour as well!). See, it was real mode on the x86 back then - I hadn't quite mastered protected mode, so I could only access 64k of video RAM at any time. Ahh, bank switching.

    Remember EMS and XMS? You wanted more than 640k but didn't want to go into protected mode? EMS and XMS were the only real ways (well, there was that fake real mode with 32-bit flat memory addresses that you could get into, but that required you to remove memory managers like himem.sys and emm386, so it didn't feel that good).

    Learning how to use DMA to pipe sound out to sound-blaster compatible cards.

    Man, those were the days.

    Now, you get callbacks and HALs and whatever else to do everything for you.

    Times have changed, I say. Perhaps for the better, but I still remember the shock I had when I finally played a wav file through my speakers (okay, I had calculated the sample rate wrong, so it played about 4 times as fast or something - but still!).

    Um, I kind of hate to say this, but while I do know everything you're talking about, I never had to deal with it.
    I've been out of college for 2 years now.
    That said, I do program C every day and it's just my preferred language. While I'm sure OS and other system level code can be written in other languages, it's still mostly good ole C.

    ASimPerson on
  • Options
    Smug DucklingSmug Duckling Registered User regular
    edited January 2009

    ...

    And so on. As you can see, the recursive function increases in complexity in a geometric fashion, whereas the iterative version increases arithmetically.

    It doesn't have to. Recursion can do Fibonacci just fine. Just have to go about it slightly differently:
    int fib(int n) {
      return fib_helper(0, 1, n);
    }
    
    int fib_helper(int prev, int cur, int rem) {
      if(rem == 0) {
        return prev;
      } else {
        return fib_helper(cur, prev + cur, rem - 1);
      }
    }
    

    Runs in nice linear time. :)

    As an interesting exercise for anyone who's curious, try executing both my method and the previous recursive method of finding Fibonacci numbers. You will quickly see the difference in speed as you increase n.

    Smug Duckling on
    smugduckling,pc,days.png
  • Options
    Smug DucklingSmug Duckling Registered User regular
    edited January 2009
    Another, iterative, way to do it is called Dynamic Programming, which sounds more complex than it really is. At its core, it is about filling in a table of already calculated results so that you never need to calculate the same thing twice. A neat side-effect is that by the end of the calculation, you can have a table of results so that in the future you can recalculate the same problem by simply looking at the table.

    In the Fibonacci example, you might do it like this:
    int fib(int n) {
      int[] fibs = new int[n+1];
      fibs[0] = 0;
      fibs[1] = 1;
      for(int i = 2; i <= n; i++) {
        fibs[i] = fibs[i-1] + fibs[i-2];
      }
      return fibs[n];
      // If you wish you could return the whole array here for easy use later.
    }
    

    The iterative solution that was proposed earlier is kind of an optimization of this, designed to save memory. Since only the last two entries of the array of used, only those are kept in variables.

    Smug Duckling on
    smugduckling,pc,days.png
  • Options
    AiranAiran Registered User regular
    edited January 2009
    java.lang.NoClassDefFoundError

    I'm working in Eclipse. I've transferred my project files from my Vista laptop to my XP desktop. I fixed the reference file locations, etc etc.
    When I try to start main(), My laptop runs the program fine, my desktop does not. Does anyone have any ideas because this is seriously pissing me off. Google hasn't been much help, apart from telling me that main.class is missing, and to set the classpath to fix it. I'm not sure if I'm setting it correctly (Configure Build Path > Classpath tab > Advanced > Enter Classpath Variable > Configure > New).

    Seriously guys this is doing my head in :x

    [edit]NEVER MIND, I don't know what the hell happened, but the error fixed itself and after correcting a typo it found the prerequisite DLLs and shit, now it's working all fine and dandy, yay.

    Airan on
    paDudSig.jpg
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    BlueSquare wrote: »
    As relating to .NET languages, (syntax is C#):

    An abstract class can not be marked private. That would defeat the purpose of being inherited. It can be marked public or internal.

    If a method must be implemented by sub classes (edit: i had weird wording here), it is marked abstract, such as your Speak() method. It is not a virtual method.

    Abstract classes can certainly have a constructor and any other implementation that is seen in non-abstract classes.

    An Interface is not an abstract class at all. It is a special type that defines a contract that the object that implements the interface is bound to uphold. There is not much else to it than that. Interfaces also can not define the accessor on it's members. IOW, you can not tell the implementer that they must set function Foo to private.

    One important concept I have not yet seen discussed is the concept of immutability.
    I was trying to be more general conceptually then speaking directly to C# but a few points:

    1 - An abstract class can be private, both conceptually and in C#. I didn't intend to leave a private keyword on Mammal but that was incorrect for reasons other than inheritance.
    2 - Just screwed up on virtual keyword, rusty as a I said.
    3 - Abstract classes can have constructors, you're correct. Those constructors should not be directly accessible, however.
    4 - Interfaces are absolutely abstract classes. Abstract classes are by definition those classes that can not be directly created, only classes that inherit from them. Interfaces are a subset of abstract classes conceptually and only really exist to deal with multiple inheritance.

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    Airan wrote: »
    java.lang.NoClassDefFoundError

    I'm working in Eclipse. I've transferred my project files from my Vista laptop to my XP desktop. I fixed the reference file locations, etc etc.
    When I try to start main(), My laptop runs the program fine, my desktop does not. Does anyone have any ideas because this is seriously pissing me off. Google hasn't been much help, apart from telling me that main.class is missing, and to set the classpath to fix it. I'm not sure if I'm setting it correctly (Configure Build Path > Classpath tab > Advanced > Enter Classpath Variable > Configure > New).

    Seriously guys this is doing my head in :x

    Java classpath isn't set correctly. Always took me 20 minutes to figure out whenever I went back to Java at the start of a new semester

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
  • Options
    BlueSquareBlueSquare Registered User regular
    edited January 2009
    PantsB wrote: »
    BlueSquare wrote: »
    As relating to .NET languages, (syntax is C#):

    An abstract class can not be marked private. That would defeat the purpose of being inherited. It can be marked public or internal.

    If a method must be implemented by sub classes (edit: i had weird wording here), it is marked abstract, such as your Speak() method. It is not a virtual method.

    Abstract classes can certainly have a constructor and any other implementation that is seen in non-abstract classes.

    An Interface is not an abstract class at all. It is a special type that defines a contract that the object that implements the interface is bound to uphold. There is not much else to it than that. Interfaces also can not define the accessor on it's members. IOW, you can not tell the implementer that they must set function Foo to private.

    One important concept I have not yet seen discussed is the concept of immutability.
    I was trying to be more general conceptually then speaking directly to C# but a few points:

    1 - An abstract class can be private, both conceptually and in C#. I didn't intend to leave a private keyword on Mammal but that was incorrect for reasons other than inheritance.
    2 - Just screwed up on virtual keyword, rusty as a I said.
    3 - Abstract classes can have constructors, you're correct. Those constructors should not be directly accessible, however.
    4 - Interfaces are absolutely abstract classes. Abstract classes are by definition those classes that can not be directly created, only classes that inherit from them. Interfaces are a subset of abstract classes conceptually and only really exist to deal with multiple inheritance.

    1. It can be, only internal to another class. True. We should probably find a better example than the link you provided, which is almost a proof of concept (bad design) example of it. I can only think of a single design reason for using an abstract class in this manner.
    Either way, it *is* incorrect for inheritance because no types would have scope to it in that context. My point, although being wrong, was for you to correct your mistake so that others didn't repeat it.

    3. It needs to be decided if we're going to discuss what *can* be done and what *should* be done. Public constructors are fine on abstract classes. They aren't the best as far as design goes, but they are correct. It wouldn't make much sense for a language to support abstract classes yet allow them to be instantiated just because you made the constructor accessible.

    4. I completely disagree. Saying they are the same and then saying one is a subset of the other makes no sense to me. They function differently and provide different, yet closely related, purposes. Thinking they are the same is exactly why most people fail interview questions about the two.

    BlueSquare on
  • Options
    AiranAiran Registered User regular
    edited January 2009
    PantsB wrote: »
    Airan wrote: »
    java.lang.NoClassDefFoundError

    I'm working in Eclipse. I've transferred my project files from my Vista laptop to my XP desktop. I fixed the reference file locations, etc etc.
    When I try to start main(), My laptop runs the program fine, my desktop does not. Does anyone have any ideas because this is seriously pissing me off. Google hasn't been much help, apart from telling me that main.class is missing, and to set the classpath to fix it. I'm not sure if I'm setting it correctly (Configure Build Path > Classpath tab > Advanced > Enter Classpath Variable > Configure > New).

    Seriously guys this is doing my head in :x

    Java classpath isn't set correctly. Always took me 20 minutes to figure out whenever I went back to Java at the start of a new semester

    Yeah see, I tried entering the 'jdk folder/lib' location into the Windows env variable section, I don't think Eclipse cares though. Spent an hour looking through Eclipse settings and saw nothing obvious. Somehow a reboot fixed the problem. It was a goddamn headache anyway.

    Airan on
    paDudSig.jpg
  • Options
    KrisKris Registered User regular
    edited January 2009
    BlueSquare wrote: »
    PantsB wrote: »
    BlueSquare wrote: »
    As relating to .NET languages, (syntax is C#):

    An abstract class can not be marked private. That would defeat the purpose of being inherited. It can be marked public or internal.

    If a method must be implemented by sub classes (edit: i had weird wording here), it is marked abstract, such as your Speak() method. It is not a virtual method.

    Abstract classes can certainly have a constructor and any other implementation that is seen in non-abstract classes.

    An Interface is not an abstract class at all. It is a special type that defines a contract that the object that implements the interface is bound to uphold. There is not much else to it than that. Interfaces also can not define the accessor on it's members. IOW, you can not tell the implementer that they must set function Foo to private.

    One important concept I have not yet seen discussed is the concept of immutability.
    I was trying to be more general conceptually then speaking directly to C# but a few points:

    1 - An abstract class can be private, both conceptually and in C#. I didn't intend to leave a private keyword on Mammal but that was incorrect for reasons other than inheritance.
    2 - Just screwed up on virtual keyword, rusty as a I said.
    3 - Abstract classes can have constructors, you're correct. Those constructors should not be directly accessible, however.
    4 - Interfaces are absolutely abstract classes. Abstract classes are by definition those classes that can not be directly created, only classes that inherit from them. Interfaces are a subset of abstract classes conceptually and only really exist to deal with multiple inheritance.

    1. It can be, only internal to another class. True. We should probably find a better example than the link you provided, which is almost a proof of concept (bad design) example of it. I can only think of a single design reason for using an abstract class in this manner.
    Either way, it *is* incorrect for inheritance because no types would have scope to it in that context. My point, although being wrong, was for you to correct your mistake so that others didn't repeat it.

    3. It needs to be decided if we're going to discuss what *can* be done and what *should* be done. Public constructors are fine on abstract classes. They aren't the best as far as design goes, but they are correct. It wouldn't make much sense for a language to support abstract classes yet allow them to be instantiated just because you made the constructor accessible.

    4. I completely disagree. Saying they are the same and then saying one is a subset of the other makes no sense to me. They function differently and provide different, yet closely related, purposes. Thinking they are the same is exactly why most people fail interview questions about the two.

    Can someone give a clear explanation of the difference between abstract classes and interfaces, and perhaps an example of when you would want to use one and not the other? I'm still shaky on this topic, even after my C# course last semester.

    Kris on
  • Options
    PantsBPantsB Fake Thomas Jefferson Registered User regular
    edited January 2009
    BlueSquare wrote: »
    4. I completely disagree. Saying they are the same and then saying one is a subset of the other makes no sense to me. They function differently and provide different, yet closely related, purposes. Thinking they are the same is exactly why most people fail interview questions about the two.

    The definition of an abstract class is one that can not be instantiated.

    "Interfaces" only exist in languages that prohibit multiple inheritance. They exist explicitly because of the diamond problem. Intro courses don't teach it in these terms usually but the only reason they exist is to get some of the benefits of multiple inheritance while limiting the problems inherent by gimping some of the flexibility in the class (usually all virtual methods & only immutable/static attributes).

    If you can come up with an interface example that could not be conceptually replaced by an abstract class in a system with multiple inheritance fire away. In the same way that an abstract class is a subset with restrictions of classes in general, interfaces are a subset of abstract classes.

    PantsB on
    11793-1.png
    day9gosu.png
    QEDMF xbl: PantsB G+
This discussion has been closed.