• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

0xCA2

Member
Went to a career fair yesterday. Felt like a total dork with nothing to offer. I asked someone in this thread what type of stuff would get me an internship: they told me I should work on more complex things. As a result, I did these. The visual novel game library* is unfinished but I'm itching to just move on to something else, like learning C++ and doing it in plain opengl or taking the code in there and applying it to more complex games (because I feel that'd impress employers), or learning C, or something.

Tl; Dr: Here is my portfolio. What can I learn from here to be more employabl? Note: I'm looking for internships.

*I created this library over the summer to try to better understand game logic systems, something I also got advice about in this thread.
 
What can I learn from here to be more employabl? Note: I'm looking for internships.

Just took a quick look over your github. One thing you should consider doing is go back to your notepad clone project, and give it a final polish. Write docs, add a proper build system with instructions, either script based or maven/gradle whatever. I see you're using gradle for CYOA-toolkit so you should be able to add it to the other one. If a potential employer goes on there and sees well written docs (nothing too massive, just enough info to use) and they get a clear set of steps on replicating your build that will count for big points. I know that I am 100 times more likely to use a library/check something out if I can just clone, build, done. Consider using github releases to upload your jar rather than including in the source. Otherwise it's a good starting point, just keep adding new projects and try to keep the docs/build management up to date. Those are actually the least work out of anything else for a project but they make it look much more professional than just a bunch of code uploaded.
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
It turns out Popovers have been overhauled for IOS8. Why that means they need to break the ones already working, I don't know....

Mmmmm...popovers.

popovers-3.jpg
 

Volcynika

Member
I feel so dumb that I can't figure this out, but this SVG syntax is stumping me. I know it's something small, but I can't get working the way I want. (Javascript)

Code:
 var x = 350; var y = 0; scale = 0.57

this.button = this.paper.path('M' + x + ',' + y + 
		              'H' + (x + (185 * this.scale)) + 
			      'V' + (y + (42 * this.scale)) + 
			      'L' + (x + (165 * this.scale)) + ',' + (y + (42 * this.scale)) + 
			      'L' + (x + (165 * this.scale)) + ',' + (y + (62 * this.scale)) + 
			      'M' + (x + (165 * this.scale)) + ',' + (y + (42 * this.scale)) + 
			      'v' + (this.scale * 20) + 
			      'a' + this.scale * 20 + ',' + this.scale * 20 + ' 0 0,0 ' + 20 * this.scale + ',' + (this.scale * -20) + 
			     'M' + (x + (165 * this.scale)) + ',' + (y + (62 * this.scale)) + 
			     'H' + (x + (20 * this.scale)) + 
			     'a' + this.scale * 20 + ',' + this.scale * 20 + ' 0 0,0 ' + 20 * this.scale + ',' + (this.scale * -20) + 
			     'V' + (y + (-42 * this.scale)) + 
			     'Z');

I'm using Raphael.js and I know this is the elliptical arc format: A - elliptical arc - (rx ry x-axis-rotation large-arc-flag sweep-flag x y)+

It makes the image appear like this
SdOdhYM.png


What I want though is basically a rectangle with two rounded edges on the bottom. I'm trying to figure out how to mirror the elliptical arc on the bottom. Any ideas? Only started messing with SVG today.
 
So Rust looks pretty cool, I've heard talk that it's meant to replace C/C++ in the long run. 15-20 years out. It sounds really cool, still seems a bit underbaked.

Thoughts on it?

It's pretty fantastic. I've been using it for small hobby projects and I really like it. It's much less verbose and much more secure than C. I haven't had a single segmentation fault in Rust (outside of unsafe blocks) and code is generally a lot shorter than it is in C. It also allows you to do functional programming, it has pattern matching, lambdas, a really nice iterator API (map, filter, reduce and so on), type classes (called "traits" in Rust) and type inference. It's also generally really fast. (close/equal to C/C++) Gotta say that the traits system is probably one of my favorite things about Rust. It allows you to write very generic code very easily. It also avoids the trap C# and Java have fallen into (every class inherits from Object, which has .equals(), .toString() and so on). In Rust, you can only do an equality test on things that have the same type and that both implement PartialEq or Eq.

Something that can be pretty annoying is that the borrow checker (and the type checker as well) is sometimes a little overbearing, forcing you to introduce an extra local variable for no good reason and so on. Some of that might be bugs as well.
 
Maybe I didn't read the OP right. If I didn't then my bad feeling like crap right now. Anyway this might be a REALLY stupid question. if I want to enter the field of programming what do I need to study in college? Of course I'll look through the resources in the OP later. Just so I can have a little understanding this programming stuff.
 

Haly

One day I realized that sadness is just another word for not enough coffee.
Well, you'll probably want to look into your college-of-choice's Computer Science degree. The kind of classes you'll take in a BSc Computer Science curriculum include:

Computer Science: Basic programming knowledge using one of the "starter" languages, these days it's typically Java, Python or C++/C#
Discrete Math: A special branch of mathematics dealing in logic, structures and sets
Statistics: Another important branch of math for programming
Linear Algebra: Vector spaces and transformations, most commonly used in graphics programming
Algorithms: Analyzing the runtime of algorithms and techniques on their creation
Programming Languages: A sort of crash course on multiple languages at once
Software Architecture: How to design and structure large scale programs
 
Thanks a lot man! I'll definitely be looking at computer science. Math is intimidating since I've never been good at it but it's college, I was planning on studying a lot anyway.
 

Sharp

Member
Something that can be pretty annoying is that the borrow checker (and the type checker as well) is sometimes a little overbearing, forcing you to introduce an extra local variable for no good reason and so on. Some of that might be bugs as well.
It's a bug, and it was annoying enough that it got prioritized and is in the process of being fixed. It will definitely be working by 1.0.
 

0xCA2

Member
Just took a quick look over your github. One thing you should consider doing is go back to your notepad clone project, and give it a final polish. Write docs, add a proper build system with instructions, either script based or maven/gradle whatever. I see you're using gradle for CYOA-toolkit so you should be able to add it to the other one. If a potential employer goes on there and sees well written docs (nothing too massive, just enough info to use) and they get a clear set of steps on replicating your build that will count for big points. I know that I am 100 times more likely to use a library/check something out if I can just clone, build, done. Consider using github releases to upload your jar rather than including in the source. Otherwise it's a good starting point, just keep adding new projects and try to keep the docs/build management up to date. Those are actually the least work out of anything else for a project but they make it look much more professional than just a bunch of code uploaded.

By docs do you mean a Wiki on Github or something like a Javadoc?
 
By docs do you mean a Wiki on Github or something like a Javadoc?

Even just a more elaborate README would be fine. Compile from source instructions, installation instructions, usage instructions. Javadoc is only really needed if you're putting out a library. Here's the README to one of my projects and it just contains enough information to help people get up and running if they want to clone it etc. as well as basic usage for the api. Not saying what I've got up there is a perfect model for emulation but just to show the level of detail I'm talking about :).
 
It's a bug, and it was annoying enough that it got prioritized and is in the process of being fixed. It will definitely be working by 1.0.

That's great to hear. It can sometimes be frustrating to try to satisfy the Rust compiler. Something that comes to mind, for example when doing a map operation on a list, like this:
Code:
let xs = vec![12i, 14, 15, 17, 12, 12];
let ys = xs.iter().map(|i| i % 2i).collect();
The compiler will complain. (error: cannot determine a type for this bounded type parameter: unconstrained type) If you add a type annotation (Vec<int>) to ys, it works fine.

edit: I just asked about that in the Rust IRC channel and it was explained to me that you can actually collect values into all sorts of different collections, like you can collect the result of a transformation on a Vec or a slice into a HashMap or a HashSet, which I didn't know and sounds very useful.
 
Just bear in mind, c++ imposes no constraints on your coding style -- you can do what you want, how you want, to all positive and negative consequences. Java is not that way. Java imposes oop on you. Some stuff doesn't work well with oop. Tough luck, make it work as best you can, even if your code no longer makes as much logical sense as you'd like.

It makes the transition interesting in both directions. Java programmers now using c++: free men you are. What will you do with that freedom?

*cue brave heart theme*
 

RELAYER

Banned
Needing help with new mbed project.

There are several parts, but right now I am wanting to read the temperature using a LM35.

I can do this and I'm using Terra Term to see the values.
For this section I wrote something like this

Code:
Serial pc(USBTX; USBRX); //for communicating with terminal through usb

AnalogIn lm(p20); //the thermometer connected to pin 20

float x;

int main() {
   pc.baud(9600) //controls speed of information
      while (1) {
         x = lm.read(); //reading in the data from thermometer
         pc.printf("%f \n \r", x); //printing data along with carriage return to terminal screen
      }
}

Works.

But now I must use compute an average so that the displayed temperature does not fluctuate so much.

I remember using arrays to compute averages way back in Intro to Programming, but it is not working here. My sum just grows ever larger. These are the changes I wrote for displaying a computed average instead of just the direct information.

Code:
Serial pc(USBTX; USBRX); //for communicating with terminal through usb

AnalogIn lm(p20); //the thermometer connected to pin 20

float x;
float array[1000];
float sum = 0.0;
float average = 0.0

int main() {
   pc.baud(9600) //controls speed of information
      while (1) {
         for(int i=0; i<1000;i++) {
            array[i] = lm.read(); //reading in the data from thermometer into array
         }
         for(int i=0; i<1000;i++) {
            sum = sum + array[i];
            average = sum/1000;
         }
         pc.printf("%f \n \r", average); //printing data along with carriage return to terminal
      }
}

Doesn't work.
The sum just grows forever.
What mistake am I making?
 

Sharp

Member
shoot-yourself-foot-internet-marketing-sabotage-online-marketing-success-training.jpg


I've been using Go for my latest project. I used to be a C++ dev, and compared to that, it's such a pleasure!
I think Go gets a lot right. It's one of only a very few select modern languages that puts compile speed first and foremost in the spotlight, and there's been a lot of work done to make sure the language is easy to read for both machines and humans. The technical talent involved with the language is immense, and it shows. Green threads have their issues, but Go does them about as well as you can in an imperative language. The tooling around it is amazing--every language should have something like gofmt.

That said, I have major issues with Go that haven't been alleviated even by talking to the implementors. I think they learned entirely the wrong lessons from C++'s problems, and are disingenuous about some of their solutions. Yes, C++ is way too complex. Everyone knows it, even (especially) Stroustrup. But Go's response is to ignore the last forty years of programming language theory. I have heard people cite this as a strength. It isn't. Some really useful things happened in the last forty years...

Like fast compile-time type inference. Go has sort-of type inference, but it's more like C++ auto--it's the sort of thing you add onto an old language as a hack, and I don't really understand why a new statically typed language wouldn't have better inference.

Like efficient generics. I have talked to a lot of Go fans about this one. The general attitude seems to be that generics outside of array and map aren't useful that often. In application code, that's true, but it isn't true in libraries. It causes issues with dynamic linking, but Go uses static linking anyway! If Go were more honest about its problem domain, it could use C#'s solution (boxing except for primitives) and everyone would be happy. Instead, it lingers on the question of stack vs. heap vs. compilation time vs. binary size, when the reality is that people who want generics either (1) use a more inefficient algorithm to take advantage of Go's existing types, (2) use interface, and suffer from lack of type safety, runtime checking, and vtable indirection, or (3) monomorphize them with an external program. Literally, the template implementation from the CFront days.

Like incredibly good optimizing compilers. That fast compile time you get out of Go? Well, I've had lots of people tell me (in very condescending tones) that it's because Rob Pike and Russ Cox care about compilation speed. And yes, that's definitely part of it. And yes, C++ is particularly bad. But a huge part of modern compilation times is spent in optimization passes. Huge. Go's solution is to do the bare minimum optimization, and get to machine code as fast as possible. It leads to slower programs, often significantly slower, and requires the programmer to worry a lot about runtime performance. Again, this wouldn't be so bad if Go was honest about what it's good for (the same target space as dynamic languages with specialization in web servers) but it makes it totally inappropriate as a C++ replacement.

Like huge swathes of type theory that can solve problems from error handling to concurrent access by eliminating entire classes of problems in your programs. I get it--every feature in C++ was added for a reason and it's easier not to screw up if you refuse to add anything. But we've been down this road before with Java, and all it served to do was make the eventual implementations of those things suck. Copy-pasted code sucks, would you rather have Java generics or C# generics? Null pointers are bad, would you rather use a Swift Option or the Java Optional? Exceptions suck, would you rather use Go's tedious, impossible-to-abstract, monotonous error-checking (that can still be ignored and doesn't actually provide safety) or have Haskell's monadic do notation? Data races blow, would you rather have to constantly remember to add volatile (or synchronized) to every variable that could be involved in a data race, or would you rather have Rust or Mezzo's ownership system that makes it *impossible* to screw up? I'm been bitten by all of these things *routinely.* Enough so that it's painful to me to write anything large or critical in Ruby (a language I know really well) because it's so easy to mess these things up. And large and critical is basically C++'s wheelhouse. Again, it's an area where Go just needs to be honest about who it's targeting.

I also hate the way Go sneaks in features that add deceptive complexity to the language...

Think generics are bad? Well, Go has generics--but only for blessed compiler types like arrays, maps, and channels, as well as some select functions.

Think exceptions are bad? It has exceptions, you use them with defer / panic / recover.

Think OOP is bad? It has a top type, and downcasts from interface have all the same issues they do in any other language.

Think undefined behavior is bad? Well, Go isn't memory safe--data races on maps or interfaces can lead to segfaults when accessing data across channels when GOMAXPROCS > 1 (and no, its race detector, while cool, doesn't always catch them). This is the best-kept secret of Go.

Dislike the overhead of automatic heap allocations? Surprise! The moment you take a reference, a heap allocation was introduced, and its global garbage collector started to track it (the escape analysis here is very minimal, because of compile time constraints).

Dislike the slowness of Java's bytecode? Well, Go starts up faster, but once it starts running it has the exact same problems (that's why it compiles so fast--it does very little optimization!)

There are other specific issues (how slow its C FFI is, [very] suboptimal garbage collection, a lack of RAII, heavy reliance on the runtime) that make it inadequate as a C++ replacement in most cases, but are acceptable compromises for its targeted domain--web servers. And I want to be clear--despite all my complaints, I think Go is really, really close to being a good language (generics would do it for me), which is part of what makes this so frustrating. I just wish Go was more honest about what it is. It's not a C++ replacement for most of the applications where C++ should be used.
 
shoot-yourself-foot-internet-marketing-sabotage-online-marketing-success-training.jpg


I've been using Go for my latest project. I used to be a C++ dev, and compared to that, it's such a pleasure!
Most likely blow something up unintentionally.
Perhaps. It's not for everyone. Though where impressions of the language are concerned, "C++" is ambiguous... C++11 is a huge improvement in usability from C++03, and 03 is a momentous improvement from the original spec.

But really, most software projects don't need a lot of freedom. If you're building a web site backend, for example, the tools that python/django or ruby/rails give you are, realistically, good enough for anything you'll do. String manipulation? Perl. etc.

That's actually my biggest issue with Java at this point -- I'm not sure what it's good for anymore. It's been flanked on both sides in utility, both as a general purpose language and one of specific functionality.
 
That's actually my biggest issue with Java at this point -- I'm not sure what it's good for anymore. It's been flanked on both sides in utility, both as a general purpose language and one of specific functionality.

Lucene, POI, Spring Boot + Spring Security + Spring REST, JPA, iText, and a host of other libraries make it still the best language for enterprise web development. It's also still the fastest language when it comes to throughput for a web application.
 

injurai

Banned
I think Go gets a lot right. It's one of only a very few select modern languages that puts compile speed first and foremost in the spotlight, and there's been a lot of work done to make sure the language is easy to read for both machines and humans. The technical talent involved with the language is immense, and it shows. Green threads have their issues, but Go does them about as well as you can in an imperative language. The tooling around it is amazing--every language should have something like gofmt.
.
.
.
<snip>

Go is something I've been really wanting to look into. It sounds it's not fulfilling what it sought out to do? Or is it just too early to be stable and well defined language?
 

RELAYER

Banned
I need some more advice please.

In addition to displaying the temperature, I have two buttons, one for Fahrenheit and one for Celsius, so I can switch modes.

I need the program to check if a button has been pressed, but I also need it to repeatedly display the temperature in the last selected mode if no button has been pressed.

So basically I need an infinite while loop that the program can also get out of at any moment.

How can I do something like that?

I thought about doing something like .....

Code:
if (fahrenheitbutton == 1) {
//call fahrenheit function
}
else if (celsiusbutton == 1) {
//call celsius function
}
else {
// call fahrenheit mode function
}

But I think if I do this it won't work because if the user chooses Celsius, they'll only get it once. But if I put a while(1) in the celsius function they can never go back to Fahrenheit.

Any ideas?
 

Granadier

Is currently on Stage 1: Denial regarding the service game future
I need some more advice please.

In addition to displaying the temperature, I have two buttons, one for Fahrenheit and one for Celsius, so I can switch modes.

I need the program to check if a button has been pressed, but I also need it to repeatedly display the temperature in the last selected mode if no button has been pressed.

So basically I need an infinite while loop that the program can also get out of at any moment.

How can I do something like that?

I thought about doing something like .....

But I think if I do this it won't work because if the user chooses Celsius, they'll only get it once. But if I put a while(1) in the celsius function they can never go back to Fahrenheit.

Any ideas?

Variables to store the user's choice, C or F.
While loop with nested if/else statement.
Utilize system time so you can control how often the updates happen.

Those are some ideas I can think of off the top of my head. Go from there.
 

injurai

Banned
I need some more advice please.

In addition to displaying the temperature, I have two buttons, one for Fahrenheit and one for Celsius, so I can switch modes.

I need the program to check if a button has been pressed, but I also need it to repeatedly display the temperature in the last selected mode if no button has been pressed.

So basically I need an infinite while loop that the program can also get out of at any moment.

How can I do something like that?

I thought about doing something like .....

Code:
if (fahrenheitbutton == 1) {
//call fahrenheit function
}
else if (celsiusbutton == 1) {
//call celsius function
}
else {
// call fahrenheit mode function
}

But I think if I do this it won't work because if the user chooses Celsius, they'll only get it once. But if I put a while(1) in the celsius function they can never go back to Fahrenheit.

Any ideas?

May I ask what this is for? In general you don't want to use a loop to wait for input when the state of your system is unchanging. You would rather use signals. Though that might be beyond what you are doing. But if it's a program meant to live beyond an assignment or other hobby stuff then it's the way to go.
 

Sharp

Member
Go is something I've been really wanting to look into. It sounds it's not fulfilling what it sought out to do? Or is it just too early to be stable and well defined language?
No, it's pretty stable now (and pretty well-defined, too).

I think the best usecase for Go is essentially what I'd use Python for--relatively small projects or prototypes, solo or with maybe a few people working on it, where you just want to get something done quickly and don't want to have to worry too much about maintenance, code reuse, or performance. While it produces native code, compilation is usually so quick that there's not much practical difference from using a dynamic language--you can set it to compile every time you save. Because it compiles to native code (and is legitimately pretty good cross-platform), it has really quick startup times that make it useful for CLIs and super easy to deploy.

At runtime, Go is significantly faster than Python--around Java speed (unoptimized Java--like Python, I wouldn't spend too much time worrying about optimizing it). It has real concurrency and pretty nice synchronization abstractions in channels. It also has really great static analysis tools already (especially for being so young), which are significantly superior to Python's. Go can also be really good for web servers, since its green threading model is optimal for that usecase (though it makes significant sacrifices elsewhere).

The main drawback to Go for this usecase right now is just lack of generics (particularly generic data structures, but typesafe generic functions are annoying to work with). It's not a big a deal in dynamic languages since there's no static typechecking, but in Go they're really awkward to use since you have to use runtime reflection (which is super slow, extremely verbose, and subverts the type system) or just rewrite a new version of the type each time you use it (which is a real thing people suggest!) It helps make this less of an issue by providing proper generics for a few commonly used types and functions, but when you miss them, you *really* miss them. Fixing this would make things much easier on library writers.

As far as it not fulfilling what it set out to do, I'd say that's pretty emphatically true, but I don't think it matters that much. "A statically compiled Python" covers a lot of useful territory. I'm just tired of people calling it a "systems language" :p
 

RELAYER

Banned
Variables to store the user's choice, C or F.
While loop with nested if/else statement.
Utilize system time so you can control how often the updates happen.

Those are some ideas I can think of off the top of my head. Go from there.

I don't understand how to do any of these.
The first one sounds like the easiest, but won't I just run into the same problem?

The user selects a mode, I put the choice into a variable.Now I have two buttons for selecting a mode, and a variable. The variable is only changed upon an if statement being entered upon a button being pressed. Once in the if-statement, how to change the variable afterwards? How does the variable prompt an exit from the if-statement?

I think an answer would be to add another if-statement inside the if-statement, the condition being if the opposite button is pressed.

Is there some way to explicitly tell the program to exit the function?

edit: Hey cool I think I just figured it out. Thanks for the mental prompt! This was the best thing I ever built.

May I ask what this is for? In general you don't want to use a loop to wait for input when the state of your system is unchanging. You would rather use signals. Though that might be beyond what you are doing. But if it's a program meant to live beyond an assignment or other hobby stuff then it's the way to go.

It's only for an assignment.
It's for a microcontroller class. As you an see, I don't have much experience with programming in general.
 

Giggzy

Member
How are math degrees looked upon in the programming community? I'm not too far from completeing my degree, but I recently found a love for learning how to program.

Will teaching myself how to program and having a math degree allow me to find a job? Or is a computer science degree practically required?
 

The Mule

Member
I haven't done any programming for a long time, so I decided to write a simple program for assigning "gift receivers" to "gift buyers" for people in my family for secret santa, as a warm up to get back into it.

The rules I specified are:
  • A person can't be assigned them self
  • Each person is assigned two people (effectively means each person gets two presents)
  • Assigned names for a "gift buyer" must be different
  • A person can't be assigned as a "gift receiver" more than twice

This is what I have so far, written in Python. It mostly works, but isn't particularly elegant (see questions below the code block).

Code:
import random

#list of names
names = ["Jane", "Alfred", "Mary", "Jen", "Bob", "Ruth", "Trey", "Doug", "Celine"]
nameCounter = {}

#fill the dictionary with each name as the key and a value of 2
#used to ensure each person is assigned exactly twice
for x in names:
    nameCounter[x] = 2

#empty list of assigned names
#this will be constructed as a list of lists
#where the first name in the sub-list is the gift buyer, and the following two names are gift receivers
allocated_names = []


#function for retrieving valid names
def get_valid_name(x):
    name = random.choice(nameCounter.keys())
    while name == x or name == None:
        name = random.choice(nameCounter.keys())
    return name


#main thread
if __name__ == '__main__':
    #go through all the names in the list
    #x is the current gift buyer
    for x in names:
        #retrive the first name of the gift receiver
        name1 = get_valid_name(x)
        
        #retrieve the second name of the gift receiver
        name2 = get_valid_name(x)
        #check that the names are not the same and retrieve a new one until they're different
        while name2 == name1:
            name2 = get_valid_name(x)

        #add the gift buyer and two gift receivers to the list
        allocated_names.append([x, name1, name2])

        #decrement the counter for each name once they have been assigned
        nameCounter[name1] -= 1
        #has the name being assigned twice?
        if nameCounter[name1] <= 0:
            # remove name from dictionary to help with efficiency using random.choice() in get_valid_name(x)
            del nameCounter[name1]

        nameCounter[name2] -= 1
        if nameCounter[name2] <= 0:
            del nameCounter[name2]
    print allocated_names

I have two questions. One is reasonably specific and the other is much more general.

1. There is a situation where an infinite loop can occur. This happens when the program gets to the last one or two people in the list and the pool of remaining "gift receivers" contains them self, without a sufficient number of different people to choose from instead. How can I get around this while still retaining the random assignment? Effectively I need a way to ensure that, when the program reaches the final "gift buyers", there is a guarantee that there will be enough different people that doesn't include them self.

2. I'm looking for general advice on how to structure code. What are some design patterns that I should consider to craft better code?
 

injurai

Banned
How are math degrees looked upon in the programming community? I'm not too far from completeing my degree, but I recently found a love for learning how to program.

Will teaching myself how to program and having a math degree allow me to find a job? Or is a computer science degree practically required?

I work with a fair amount of people that got their degrees in math, and ended up learning programming purely through their jobs.

Math is a huge part of computer science, especially developing new technology. In fact math being computation is perfect.

I went straight into cs with the preference for logic and design, and a lack of patience in learning math. I really love math, it's just hard work for me. And in some small way I wish I had more math under my belt for programming. It isn't however required to be a good programmer, it just really really really helps if you want to be a programmer of certain things. Having a good background in math will only make you more valuable, so if being a mathemation isn't a prospect of your liking, computer science will offer very practical applications for you talents.
 

leroidys

Member
I haven't done any programming for a long time, so I decided to write a simple program for assigning "gift receivers" to "gift buyers" for people in my family for secret santa, as a warm up to get back into it.

The rules I specified are:
  • A person can't be assigned them self
  • Each person is assigned two people (effectively means each person gets two presents)
  • Assigned names for a "gift buyer" must be different
  • A person can't be assigned as a "gift receiver" more than twice

This is what I have so far, written in Python. It mostly works, but isn't particularly elegant (see questions below the code block).

Code:
import random

#list of names
names = ["Jane", "Alfred", "Mary", "Jen", "Bob", "Ruth", "Trey", "Doug", "Celine"]
nameCounter = {}

#fill the dictionary with each name as the key and a value of 2
#used to ensure each person is assigned exactly twice
for x in names:
    nameCounter[x] = 2

#empty list of assigned names
#this will be constructed as a list of lists
#where the first name in the sub-list is the gift buyer, and the following two names are gift receivers
allocated_names = []


#function for retrieving valid names
def get_valid_name(x):
    name = random.choice(nameCounter.keys())
    while name == x or name == None:
        name = random.choice(nameCounter.keys())
    return name


#main thread
if __name__ == '__main__':
    #go through all the names in the list
    #x is the current gift buyer
    for x in names:
        #retrive the first name of the gift receiver
        name1 = get_valid_name(x)
        
        #retrieve the second name of the gift receiver
        name2 = get_valid_name(x)
        #check that the names are not the same and retrieve a new one until they're different
        while name2 == name1:
            name2 = get_valid_name(x)

        #add the gift buyer and two gift receivers to the list
        allocated_names.append([x, name1, name2])

        #decrement the counter for each name once they have been assigned
        nameCounter[name1] -= 1
        #has the name being assigned twice?
        if nameCounter[name1] <= 0:
            # remove name from dictionary to help with efficiency using random.choice() in get_valid_name(x)
            del nameCounter[name1]

        nameCounter[name2] -= 1
        if nameCounter[name2] <= 0:
            del nameCounter[name2]
    print allocated_names

I have two questions. One is reasonably specific and the other is much more general.

1. There is a situation where an infinite loop can occur. This happens when the program gets to the last one or two people in the list and the pool of remaining "gift receivers" contains them self, without a sufficient number of different people to choose from instead. How can I get around this while still retaining the random assignment? Effectively I need a way to ensure that, when the program reaches the final "gift buyers", there is a guarantee that there will be enough different people that doesn't include them self.

2. I'm looking for general advice on how to structure code. What are some design patterns that I should consider to craft better code?

I would just try to do something simple twice. e.g.
Code:
import random

names = ["Jane", "Alfred", "Mary", "Jen", "Bob", "Ruth", "Trey", "Doug", "Celine"]

def match_gifts(gs, rs):
    givers = list(gs)
    receivers = list(rs)
    pair = []

    for giver in givers:
        receiver = giver
        while receiver == giver:
            receiver = random.choice(receivers)
        receivers.remove(receiver)
        pair.append( receiver)

    return pair

if __name__ == '__main__':
    first_list = match_gifts(names, names)
    second_list = match_gifts(names, names)
 for i in range(len(names)):
        print "{0} needs to buy one gift for {1} and one gift for {2}.".format(names[i], first[i], second[i])

If you really care about people not being matched to the same person twice, I would just do a "phase 1" like the one above, and then a "phase 2" with a check on the list from phase 1.

EDIT:

Here's another choice for main that makes sure that they aren't matched with the same person twice, and that doesn't have to deal with corner-casing and checking ending up with only the giver and someone they've already given to at the end of the list, which would require you to start over anyway.

Code:
if __name__ == '__main__':
    done = False
    first = match_gifts(names, names)
    while not done:
        second = match_gifts(names, names)
        for i in range(len(first)):
            if first[i] == second[i]:
                done = False
                break
            else:
                done = True
            
    for i in range(len(names)):
        print "{0} needs to buy one gift for {1} and one gift for {2}.".format(names[i], first[i], second[i])

The first solution is still preferable of course if you don't care if someone gets assigned the same person twice, e.g. "Bob needs to buy two gifts for Trey.".
 

r1chard

Member
Code:
    for i in range(len(names)):
        print "{0} needs to buy one gift for {1} and one gift for {2}.".format(names[i], first[i], second[i]

It's a minor thing, but whenever you see "for i in range(len(names)):" in Python code, there's usually a nicer way of doing it, usually using zip (or enumerate, if you really need the index):

Code:
    for name, first, second in zip(names, fist_list, second_list):
        print "{} needs to buy one gift for {} and one gift for {}.".format(name, first, second)
 

leroidys

Member
It's a minor thing, but whenever you see "for i in range(len(names)):" in Python code, there's usually a nicer way of doing it, usually using zip (or enumerate, if you really need the index):

Code:
    for name, first, second in zip(names, fist_list, second_list):
        print "{} needs to buy one gift for {} and one gift for {}.".format(name, first, second)

Awesome, thanks for the tip!
 
Lucene, POI, Spring Boot + Spring Security + Spring REST, JPA, iText, and a host of other libraries make it still the best language for enterprise web development. It's also still the fastest language when it comes to throughput for a web application.
I take issue with the accusation of Java being the fastest anything.

But yes, there's a huge amount of enterprise stuff from dinosaur organizations unable or unwilling to switch to modern technology. That's why it's still in use.

I'm not sure there's a legitimate reason other than that. Inertia is a powerful drug.
 
I take issue with the accusation of Java being the fastest anything.

But yes, there's a huge amount of enterprise stuff from dinosaur organizations unable or unwilling to switch to modern technology. That's why it's still in use.

I'm not sure there's a legitimate reason other than that. Inertia is a powerful drug.

Java is probably the fastest language that relies on some sort of VM to execute in. C# is about the same speed or slower, Python and Ruby (or pretty much any other interpreted language) are slower too. C and C++ can be faster but you won't use them for web development.

You seem to imply that the only reason people still use Java is because there's a ton of legacy code written in it; I don't think that's true at all. Java 8 was a big step forward to make the language less verbose and more fun to use. There's a ton of libraries for all sorts of things in Java. You can switch to a more modern language like Clojure or Scala very easily, since both languages have great Java interop. The JVM is probably the fastest VM around, with a very good JIT compiler that will especially benefit long running processes.

Twitter switched from Ruby on Rails to Scala for example. (not fully, but the performance relevant parts are now in Scala)
 

MNC

Member
Hey GAF, concerning issue tracking:

Say I have an app and I don't want reviews/emails from customers going "hey can you add this feature" or "hey when is this going to get fixed". I'm thinking of keeping a github repository purely for tracking issues. Pros: keeping track and categorizing them. Cons: Might be a bit of a threshold for people to overcome to post on Github, and creating an account and such. Also, I'm not sure what kind of permissions I can give to people and if I retain admin rights over the issues.

I really like Github so I prefer testing this approach, but I'd love to hear other suggestions.
 

phoenixyz

Member
Say I have an app and I don't want reviews/emails from customers going "hey can you add this feature" or "hey when is this going to get fixed". I'm thinking of keeping a github repository purely for tracking issues. Pros: keeping track and categorizing them. Cons: Might be a bit of a threshold for people to overcome to post on Github, and creating an account and such. Also, I'm not sure what kind of permissions I can give to people and if I retain admin rights over the issues.

On Github the Issue Tracker is connected to the source repository. Do you want to open your code? If not you are probably looking more for a dedicated Issue/Change Request Tracker like Bugzilla.
 

MNC

Member
On Github the Issue Tracker is connected to the source repository. Do you want to open your code? If not you are probably looking more for a dedicated Issue/Change Request Tracker like Bugzilla.

I would be making a separate open repository purely for issues; I have a few private repo's with the code itself. That itself might even make the whole ordeal moot; since issues usually are most useful for open source projects...
 

mltplkxr

Member
I take issue with the accusation of Java being the fastest anything.

But yes, there's a huge amount of enterprise stuff from dinosaur organizations unable or unwilling to switch to modern technology. That's why it's still in use.

I'm not sure there's a legitimate reason other than that. Inertia is a powerful drug.

There are non-technical reasons why Java is still a good choice. It's a really mainstream language and it has been for a long time.

This means that if a dev gets sick, leaves, etc. , it's easier and will take less time to replace from the point of posting the job offer, to the moment the dev is comfortable with the code. It's a lot less time and money to find, train, etc.

There's also a big network of subcontractors and professionnal support available anywhere in the world.

There's also the fact that Java has payed support contracts from a big company like Oracle.

These are all things that matter to the business side of a company.

A more technical factor that's less direct than speed and language complexity is the huge number of monitoring and profiling applications avaiable, some even come with the dev kit.
 
Top Bottom