• We are delighted to introduce GiftBot 2.0, the next generation of our popular gifting feature. To celebrate, we'll be giving away some incredible prizes over the coming weeks in one big Giveaway Extravaganza!

Programming |OT| Functional, Imperative, OOP, Cargo-Cult,... all are welcome!

phisheep

Member
Oct 26, 2017
742
As a beginner and someone who is happy to learn at a fairly slow pace I'm not necessarily in a rush to do anything real serious, but how much grasp should I have on a language before I start bashing my head at making a thing?
It depends really on how you best learn things. But there's an awful lot about programming that you *only* learn from making your own things, and one of the key skills of programming is knowing how to look up stuff that you don't understand - which is something you have to do a whole lot of first time you make something!

It's as well, though, in order to avoid taking yourself down blind alleys, to have a reasonable grasp of what sort of thing the language can do, even if you don't understand the details.

There's no earthly point in delaying making something until you know everything about the language, because nobody ever does. Every language has quirks, opportunities, idioms and idiosyncrasies that don't make it into courses and books and have to learned on the job.

What I usually do is speed-read a textbook two or three times first. Not so I understand everything in it, but so that when I reach a sticking point I have some grasp of where I need to be looking for an answer. Then I dive into making something straight away, just because that's the way I learn best.

You might find you work differently. If you're happy working through whatever it is you are working through and it doesn't feel like a chore then that's fine. But the first time it starts to irk you and you want to get started on something, then go for it, because it is a hell of an incentive to learn more everytime you get stuck on something.
 

BreakyBoy

Member
Oct 27, 2017
163
As a beginner and someone who is happy to learn at a fairly slow pace I'm not necessarily in a rush to do anything real serious, but how much grasp should I have on a language before I start bashing my head at making a thing?
The sooner the better. You can usually accomplish quite a bit with introductory-level knowledge. If anything, the process of developing software will probably introduce you quickly to any gaps in your knowledge, and will give you a better impetus to figure it out, and actually learn how to resolve the problem.

There is a lot of important work done on the theoretical side of Computer Science, but at it's heart, CS/Programming is a practical discipline. You should be building things. The sooner you do that, the better.
 

Necromanti

Member
Oct 25, 2017
2,778
It depends really on how you best learn things. But there's an awful lot about programming that you *only* learn from making your own things, and one of the key skills of programming is knowing how to look up stuff that you don't understand - which is something you have to do a whole lot of first time you make something!
I think this is one area where I struggle in terms of doing it the "respectable" way. I've seen many people recommend that you should only read the documentation, and if you need to look up actual examples by other people, you're doing yourself a disservice or don't know what you're doing. But a lot of documentation seems dense, obscure, or incomplete for a general use case, and only makes sense once you actually understand what it's doing. I'll keep engaging in the use of shameful shortcuts when necessary, though.

Rant over.
 

Huw_Dawson

Member
Oct 25, 2017
1,315
London, United Kingdom
As a hobby I am porting RPG Maker MV's game engine, which is a Node engine running 33,000 lines of ES5 Javascript implementing Pixi and nw.js, to Typescript, just because I am kinda bored of not having decent intellisense when working on my game projects.

It is very boring.
 

phisheep

Member
Oct 26, 2017
742
I think this is one area where I struggle in terms of doing it the "respectable" way. I've seen many people recommend that you should only read the documentation, and if you need to look up actual examples by other people, you're doing yourself a disservice or don't know what you're doing. But a lot of documentation seems dense, obscure, or incomplete for a general use case, and only makes sense once you actually understand what it's doing. I'll keep engaging in the use of shameful shortcuts when necessary, though.

Rant over.
I'm with you all the way. All too often the "respectable way" is the wrong way, as in too slow, too uncertain and not in the least demystifying. The official documentation for C++ and Forth is impenetrable, but then it is mostly written for compiler-writers not for jobbing programmers. The Python Language Reference is the same (though the Library Reference is much better) and the Python Tutorial is pretty well marvellous except that it fails dismally when talking about classes because it assumes you've come across them in C++ or Smalltalk and doesn't actually explain what one is!

I tend to read a lot and then discard most of it once I've found a favourite, and rely mostly on K&R 2 for C, the Programmers' Guide for Forth, and python-course.eu for Python; plus Stackoverflow, which is super once you've learned how to phrase things you are searching for. The official stuff is for backup only.
 

MotiD

Member
Oct 26, 2017
785
I'm trying to write this method (Java) for an exercise and I gotta ask this since it seems impossible, but it's more likely I just can't figure out the solution yet

Let's say I have a 2d array, and I have to go over the array and figure out who the 'neighbors' of each index are (it could be 8, 5 or 3 other numbers depending on the given index) so I could calculate the average of the neighbors + index and place the average inside the index

Do you think it's possible to do that with a nested for loop and no if conditions? As far as arrays go, I can only use .length for help
 

phisheep

Member
Oct 26, 2017
742
I'm trying to write this method (Java) for an exercise and I gotta ask this since it seems impossible, but it's more likely I just can't figure out the solution yet

Let's say I have a 2d array, and I have to go over the array and figure out who the 'neighbors' of each index are (it could be 8, 5 or 3 other numbers depending on the given index) so I could calculate the average of the neighbors + index and place the average inside the index

Do you think it's possible to do that with a nested for loop and no if conditions? As far as arrays go, I can only use .length for help
Think yourself back to February when you were doing that knight's move problem on a chessboard. It's the same sort of problem and it has the same sort of solutions.

Specifically, if you surround the 2d array with zeros at top, bottom, left, right your cell will always have 8 neighbours - at row +|- 1 and column +|- 1. that makes the summing up easy. Averaging is a bit more tricky, as it depends whether there can be real zeros in the array - but I'm sure you will come up with something!
 

MotiD

Member
Oct 26, 2017
785
Think yourself back to February when you were doing that knight's move problem on a chessboard. It's the same sort of problem and it has the same sort of solutions.

Specifically, if you surround the 2d array with zeros at top, bottom, left, right your cell will always have 8 neighbours - at row +|- 1 and column +|- 1. that makes the summing up easy. Averaging is a bit more tricky, as it depends whether there can be real zeros in the array - but I'm sure you will come up with something!
Huh, it's funny that you were able to remember the Knight move problem and I wasn't ;p

I have some time before I need to finish this exercise so I've been thinking this through slowly and I figured that -

1. Indexes at the corner of the matrix will always have 3 neighbors
2. Every index between 2 corner indexes will always have 5 neighbors
3. Every other index in the 'inner shell' will always have 8 neighbors

Now, I've only come up with this seeing 2 sizes of matrices and it might be totally wrong, but this is what I've got!
Sadly, this didn't really help me come up with a solution lol

The array can contain zero, but also only positive numbers, so I could come up with a theoretical solution using that.
I have an idea that I was going to use which relies on 2 index positioned diagonally to a given index - let's say I have a matrix of 4x4 and I want to look woh the neighbors of the index (2,2) are

I would look at the index (1,1) and go right and down, and look at the index (3,3) and go up and left to to all 8 possible indexes
This becomes trickier when it involves one of the indexes on the 'outer shell' but every index will always have at least one other index positioned diagonally so it can be solved.

Thing is with this solution I'm looking at a fair number of if statements, which is what I was looking to avoid. Someone at my class mentioned he managed to write the logic for this method with a nested for loop and using the conditional statements in the loop with no additional if statements.
I don't know whether to believe him or not.
 

Theonik

Member
Oct 25, 2017
833
You can simply check x + 1, x - 1, y + 1, and y - 1 to get all the neighbours. In edges and corners you will get exceptions but you can wrap the check in a try catch block to handle that.
 

Megasoum

Member
Oct 25, 2017
12,803
Hey guys quick question... Not necessarily exactly programming specific but anyway.

You guys have any good suggestions for video series on YouTube for UE4 or Unity tutorials?

I'm already experienced in C# and have a, very rusted, base in C++.

I know both companies have tutorials on their site but I'm looking for community made playlists.
 

metaprogram

Member
Oct 28, 2017
965
Started learning Lua for a new job I'm starting in 2 weeks. Man, who makes programming languages with 1-based indices in this day and age? Ugh.

And the lack of a good IDE / debugger is super lame. I'm using ZeroBrane Studio but maybe I'm just spoiled by using Visual Studio with C++ and Python for so long. I don't know how anyone functions without good tools.

I'm tempted to write a full Lua integration for VS just because this pisses me off so much.

That said, the book I'm using to learn Lua is really great. I really did not expect a book about a scripting language such as Lua to assume a strong working background in both interpreted and compiled languages, plus a solid foundation of computer science. All books these days try to start from the assumption you don't already know how to program, which makes them extremely boring and painful to read.

The very first exercise in the entire book is "Modify the factorial example in the Introduction to not fail if if you enter a negative number." But the whole point of the example was just to illustrate what Lua looks like, and at this point exactly 0 programming constructs for the language have been introduced. Fucking love it, just gets down to business.

In the second chapter, before even talking about a single control flow mechanism or basically anything at all for that matter, they show off an 8-queens puzzle implementation and ask you to modify it to do various things. I wish all language books were like this.
 
Last edited:

MotiD

Member
Oct 26, 2017
785
Last edited:

Zevenberge

Member
Oct 27, 2017
351
That said, the book I'm using to learn Lua is really great. I really did not expect a book about a scripting language such as Lua to assume a strong working background in both interpreted and compiled languages, plus a solid foundation of computer science. All books these days try to start from the assumption you don't already know how to program, which makes them extremely boring and painful to read.

The very first exercise in the entire book is "Modify the factorial example in the Introduction to not fail if if you enter a negative number." But the whole point of the example was just to illustrate what Lua looks like, and at this point exactly 0 programming constructs for the language have been introduced. Fucking love it, just gets down to business.

In the second chapter, before even talking about a single control flow mechanism or basically anything at all for that matter, they show off an 8-queens puzzle implementation and ask you to modify it to do various things. I wish all language books were like this.
Interesting. I never actually use books to learn a new language, for the same reason you stated. I just download the compiler and/or runtime and hack until I built a small application. The downside of this is, as Walter Bright (compiler guru and creator of D) said
Walter Bright said:
I first learned programming in BASIC. Outgrew it, and switched to Fortran. Amusingly, my early Fortran code looked just like BASIC. My early C code looked like Fortran. My early C++ code looked like C.
Basically I always start molding my ideas into the language rather than letting the best practices of the language shape my ideas. (Fun fact, I feel that I learned more about functional programming by reading a paper on lambda calculus and type theory than trying to implement various problems in OCaml.)
 

Zelenogorsk

Member
Mar 1, 2018
1,009
About to finish my second semester as a CS student! I’m taking two programming classes (Algorithms & Data Structures and Assembly) next semester but i won’t be taking any summer classes and I’m looking for books or websites to help me stay sharp over the next 4 months. Maybe a book of challenge problems or something like that?

While still a beginner at this point im familiar with if/else, for/while loops, arrays, functions, pointers, recursion, OOP, and operator overloading. The only language i know right now is C++.
 

Lidl

Member
Dec 12, 2017
1,097
About to finish my second semester as a CS student! I’m taking two programming classes (Algorithms & Data Structures and Assembly) next semester but i won’t be taking any summer classes and I’m looking for books or websites to help me stay sharp over the next 4 months. Maybe a book of challenge problems or something like that?

While still a beginner at this point im familiar with if/else, for/while loops, arrays, functions, pointers, recursion, OOP, and operator overloading. The only language i know right now is C++.
To become a more competent developer learn about debugging, advanced IDE functions or advanced text editors and version control.

If you are interested in embedded or OS development maybe learn about Linux (Linux From Scratch), C (The C Programming Language) or get into RPI, Arduino and FreeRTOSs.

If you want something else, check out functional programming, relational databases, ML or web stuff.

You might also want to prepare for theoretical CS and math courses which can be hard for some CS students.

For challenges I've done: Project Euler, Codewars, Leetcode, Hackerrank. The problem with most challenge websites is they put you in a controlled environment. You don't write your own tests, benchmarks or have to tinker with IDEs or compilers. Own projects are probably the best way to learn.

Oh and capture the flag (hacking) challenges are a thing as well.
 

Sesuadra

Member
Oct 26, 2017
1,534
God I've not been in here in a long time. Work took over and I've my final exam in the first week of may.

Questio to the github experts in here...two teams at work merged and now we got two github repositories..is there an easy way to merge them? I google'd but was left with more question marks over my head.

any help would be appreciated :D
 

Zevenberge

Member
Oct 27, 2017
351
Why would you want to merge them? I assume each repository contained one application each. Unless you also plan to also merge those applications, I'd hesitate from merging the repos. My GF actually had to merge two very related applications at her job, so she merged two repos. At my own job, I actually split a large repo into two, as it contained two separate applications. It simplified the build and reduced inter-application dependencies.

If you still want to merge, I'd recommend merging locally, then (force-)pushing to a new remote repository and archive the old ones.
 

metaprogram

Member
Oct 28, 2017
965
Interesting. I never actually use books to learn a new language, for the same reason you stated. I just download the compiler and/or runtime and hack until I built a small application. The downside of this is, as Walter Bright (compiler guru and creator of D) said

Basically I always start molding my ideas into the language rather than letting the best practices of the language shape my ideas. (Fun fact, I feel that I learned more about functional programming by reading a paper on lambda calculus and type theory than trying to implement various problems in OCaml.)
I'm the opposite. My approach to learning these things has always been to read as many books as possible, do every single exercise in every book, and then try to write a real program.

It can get pretty boring at times, but I think in a lot of ways I'm a purist and if I just start randomly hacking away I always feel like I will end up doing something really stupid that could have been done really elegantly if I had just known what I was doing.
 

phisheep

Member
Oct 26, 2017
742
Programming has a way of biting you in the bum, hubris and nemesis and all that. Happened to me recently after I'd got all excited a few weeks ago about getting my Forth inner interpreter working. Turns out it wasn't working as well as I'd thought!

I had used this code as my benchmark - it's the example that crops in in all the books, and is used extensively in Jonesforth. Just defining two simple words:

Code:
: DOUBLE DUP + ;
: QUAD DOUBLE DOUBLE ;
What this does is define a word 'DOUBLE' that doubles a number on the stack by duplicating it and adding the two together, and a word "QUAD" that quadruples a number on the stack by doubling it twice. And yay! it worked! It was quadrupling numbers like anything! At which point I posted in joy here and started coding up a load more stuff ...

What I hadn't realised was that my implementation was executing the first DOUBLE twice and the second one not at all. All to do with me not updating the instruction pointer properly. So while it behaved itself for words built only from C primitives (and apparently for Forth words but only when they were the last thing in the definition and were there twice and were the last things in the definition), I ended up with some excruciatingly bizarre bugs as soon as things got any more complicated than that.

Serves me right I guess. Took me another week to rework the whole thing.

Still, I've now got about 80% of the core words of ANS Forth coded up, and it's looking good. Well, gooder than it was!
 

MotiD

Member
Oct 26, 2017
785
Is there any reason not to use the ternary operator for the initialization or conditioning part of a for loop? I couldn't find a lot of discussion about this topic, but what I did find made it seem like it's not the best idea (Java)
 

Somnid

Member
Oct 25, 2017
2,425
Is there any reason not to use the ternary operator for the initialization or conditioning part of a for loop? I couldn't find a lot of discussion about this topic, but what I did find made it seem like it's not the best idea (Java)
I'd have to see an example but you probably don't want to be using expressions for loop conditions because it's really annoying to figure out what you are trying to do. Count up, count down, take fixed sized steps but anything more than that my gut reaction would be don't.
 

Sesuadra

Member
Oct 26, 2017
1,534
Why would you want to merge them? I assume each repository contained one application each. Unless you also plan to also merge those applications, I'd hesitate from merging the repos. My GF actually had to merge two very related applications at her job, so she merged two repos. At my own job, I actually split a large repo into two, as it contained two separate applications. It simplified the build and reduced inter-application dependencies.

If you still want to merge, I'd recommend merging locally, then (force-)pushing to a new remote repository and archive the old ones.
oh sorry, I forgot to add, we use github not for code documentation...we use it only to track issues/ideas.
 

Zevenberge

Member
Oct 27, 2017
351
oh sorry, I forgot to add, we use github not for code documentation...we use it only to track issues/ideas.
Ah, then it's a whole different story. I have no idea how to merge the metadata of repositories. Maybe you can use the GitHub API to automatically pull all the issues from one repository and push it to another?
 

MotiD

Member
Oct 26, 2017
785
I'd have to see an example but you probably don't want to be using expressions for loop conditions because it's really annoying to figure out what you are trying to do. Count up, count down, take fixed sized steps but anything more than that my gut reaction would be don't.
I managed to avoid this, but the idea was that I'd use it with the initialization of the variable, so far example for(int i = (a > b); ...; ...;) or maybe even the condition

I thought I needed it for a method I mentioned earlier that needs to determine how many neighbors every index in a matrix has and replace the number in the index with the average sum of its neighbors.
I ended up sending the array to a private method that uses 5 int variables, 3 ternary operators and a nested for loop and is 15 lines of code. Takes care of edge cases as well, for example if the matrix only has one row.

Not the most efficient because I call the method for every index in the matrix and return an int, but I don't really know anything about efficiency yet so that doesn't really matter at this stage ;p
 
Oct 28, 2017
8
I was wondering if anybody could point me in the right direction of implementing a B-Tree for a project I have. The B-Tree gets populated with 500 random unique integers. I can’t wrap my mind around how to start it. Any tips?
 

sleepnaught

Member
Oct 26, 2017
3,111
In python how can I take something like:

Python:
for num in range(1900, 2020):
    print(f'<option>{num}</option>')
but format the result in such a way it reads 5 items per line?
 

phisheep

Member
Oct 26, 2017
742
In python how can I take something like:

Python:
for num in range(1900, 2020):
    print(f'<option>{num}</option>')
but format the result in such a way it reads 5 items per line?
(I assume you mean to *write* rather than read 5 items a line.)

There are zillions of ways of doing it, but probably the neatest is the "grouper" recipe in the itertools module. You'll end up with something like this:

Python:
for five_things in grouper(range(1900,2020), 5, fillvalue=''):
    # now five_things is a list of five consecutive elements of the range,
    # padded out with fillvalue, and you just need some code to print it out.
    # Something like this maybe?
    print(*['<option>'+str(thing)+'</option>' for thing in five_things])
(Going by memory here, so all the details might not be right, but this is the way to go.)

Edit: Just got round to trying it - seems to work fine, just might need a bit of tweaking depending what you want to do if it's not an exact multiple of 5.
 
Last edited:

Lidl

Member
Dec 12, 2017
1,097
Thanks for the reply. Tbh I don't really use much open source software but I'm sure I'll find something. Is there really much I can contribute without knowing the codebase?
Well it depends on the issue you're trying to fix or on the feature you're trying to implement, but for the most part you would need to familiarize yourself with the codebase. For large projects you would also need to abide by their contributing guidelines.
Sometimes there's money involved: https://www.bountysource.com/ (although I must add that I've no experience with that site)
There's also bounties for ethical hacking: https://www.hackerone.com/
 

vypek

Member
Oct 25, 2017
4,501
So I've had python 2.7 on my PC for a while but not in any path variable. I've also just been keeping my scripts in one folder which is in the path so I can call them from any folder.

I'm attempting to install python 3.7 and running into issues. Even after I put 4 python folders (total between 2.7 and 3.7) I can't get things to run properly. When I call my old scripts, I get errors because the syntax is not compatible with 3.7. But I also can't seem to distinctly ask python 2 to run those scripts. Tried to change the python 2.7 exe to a new name and then try "python2 myScript.py" and had no luck. Anyone have any idea of how I can get things going so I can set python 3.7 as the new default but also managing to call on python 2.7 for old scripts in a folder defined in my path environment variable?
 

Sirpopopop

_ _ _ w _ _ _
Member
Oct 23, 2017
402
So I've had python 2.7 on my PC for a while but not in any path variable. I've also just been keeping my scripts in one folder which is in the path so I can call them from any folder.

I'm attempting to install python 3.7 and running into issues. Even after I put 4 python folders (total between 2.7 and 3.7) I can't get things to run properly. When I call my old scripts, I get errors because the syntax is not compatible with 3.7. But I also can't seem to distinctly ask python 2 to run those scripts. Tried to change the python 2.7 exe to a new name and then try "python2 myScript.py" and had no luck. Anyone have any id
ea of how I can get things going so I can set python 3.7 as the new default but also managing to call on python 2.7 for old scripts in a folder defined in my path environment variable?
Virtual Environments?
 

metaprogram

Member
Oct 28, 2017
965
So I've had python 2.7 on my PC for a while but not in any path variable. I've also just been keeping my scripts in one folder which is in the path so I can call them from any folder.

I'm attempting to install python 3.7 and running into issues. Even after I put 4 python folders (total between 2.7 and 3.7) I can't get things to run properly. When I call my old scripts, I get errors because the syntax is not compatible with 3.7. But I also can't seem to distinctly ask python 2 to run those scripts. Tried to change the python 2.7 exe to a new name and then try "python2 myScript.py" and had no luck. Anyone have any idea of how I can get things going so I can set python 3.7 as the new default but also managing to call on python 2.7 for old scripts in a folder defined in my path environment variable?
Just take Python out of your path. instead of writing "python myscript.py" write "C:\python27\python.exe myscript.py", problem should be solved
 

vypek

Member
Oct 25, 2017
4,501
Just take Python out of your path. instead of writing "python myscript.py" write "C:\python27\python.exe myscript.py", problem should be solved
Oh, good point! I hadn't tried doing that before and was just trying to call the scripts the same way I did before when I had a single python version. Would have been nice if I had a way to just figure it out with a python exe name change but calling the path for the install seems like it should be relatively easy too! Thanks. This is the first thing that I'll try when I'm back at my home PC
 

Klappdrachen

Member
Oct 26, 2017
829
I was trying to compile a C file in the Terminal on my Mac, but I always got this error:
Code:
MBP:Documents user$ make ./untitled\ text\ 4
make: ./untitled text 4: No such file or directory
make: *** No rule to make target `./untitled text 4'.  Stop.
After I renamed the file to "untitled", it compiled without issues. So I'm wondering if the spaces were the issue. Is "\ " not the correct way to describe spaces in filenames? I got "./untitled\ text\ 4" using the autocomplete by pressing tab, so it should be correct, shouldn't it?
 
Last edited:

metaprogram

Member
Oct 28, 2017
965
Oh, good point! I hadn't tried doing that before and was just trying to call the scripts the same way I did before when I had a single python version. Would have been nice if I had a way to just figure it out with a python exe name change but calling the path for the install seems like it should be relatively easy too! Thanks. This is the first thing that I'll try when I'm back at my home PC
Yea I use side-by-side install of python all the time, and you basically just have to decide which one you want to be in your path, and then all others, use absolute path to python interpreter.

Make sure that in your scripts if you ever need to invoke python to run another script from within one of your scripts, you use `sys.executable` in the Popen() constructor to make sure your environment stays hermetic.
 

metaprogram

Member
Oct 28, 2017
965
I was trying to compile a C file in the Terminal on my Mac, but I always got this error:
Code:
MBP:Documents user$ make ./untitled\ text\ 4
make: ./untitled text 4: No such file or directory
make: *** No rule to make target `./untitled text 4'.  Stop.
After I renamed to file to "untitled", it compiled without issues. So I'm wondering if the spaces were the issue. Is "\ " not the correct way to describe spaces in filenames? I got "./untitled\ text\ 4" using the autocomplete by pressing tab, so it should be correct, shouldn't it?
should be, but in general, better to use quotes. make './untitled text 4'
 

Ambitious

Member
Oct 26, 2017
319
At work, we have several services which act as kind of a gateway to the database services. Some of their methods do have actual business logic, but many of them basically look like this:

Java:
public MyFoo getFooByBar(String bar) {
    Foo foo = backendWebService.getFooByBar(bar);
    return fooConverter.convert(foo); // Converts the DTO from the backend to the DTO type of this service
}
Would you write a unit test for a method like this? Some coworkers insist on it, but I don't see the point. The tests they write are basically mirrors of the methods, just with mocks. That's how the tests usually look like:

Java:
@Test
public void getFooByBar(String bar) {
    Foo foo = new Foo();
    MyFoo myFoo = new MyFoo();
    
    expect(backendWebService.getFooByBar(bar)).andReturn(foo);
    expect(converter.convert(foo)).andReturn(myFoo);
    
    MyFoo result = myService.getFooByBar(bar);
    assertEquals(result, myFoo);
}
I just don't see the point. The method doesn't have any real behaviour. It's just glue code. All this test does is to make sure that the backend service is called with the bar String. The assertion after the call is useless, as well as the implicit assertion in the second expectation (convert foo).
Pretty much every code change to the method will make this test fail. It has no value. A coworker made the point that if, for instance, a developer replaces bar with null in the getFooByBar call, the test would point this out. Well, yeah - but 1) the IDE would highlight the unused parameter, 2) our SonarQube would even post a comment about the unused parameter in the merge request, 3) an integration test would point out the issue anyway, and 4) If you want, you can add an undetected error to pretty much any method, no matter how well tested.

So, yes, I already know how useless tests like this are. I just have trouble convincing some coworkers. They insist that every public methods needs to have at least one test..
 

Zevenberge

Member
Oct 27, 2017
351
It's fun to think about. You do want to have a test to be able to check whether all the code is glued together correctly (and don't rely on IDE or the coffee factor). Ultimately, you'd want to have the confidence to deploy any green build to production instantly. On the other hand, why would you write tests for simple glue code like that? Especially if you are using mocks - you are basically testing if you have written exactly the two lines that your tests expects and don't test whether your application behaves as expected.
You could write an integration or end-to-end test for this (such that it actually does test something). I'm usually lazy and don't write tests for this.

However, more interestingly: why are we writing code like this? Our job is to tell computers what to do so that we don't need to do it ourselves. Why are we sometimes degraded to expensive coffee drinking macro processors? In D, I'd write the following:

C++:
class FooController : Controller 
{
    this(DatabaseService backendWebService)
    {
        _backendWebService = backendWebService;
    }

    private DatabaseService _backendWebService;

    mixin GlueCodeForService!DatabaseService;
}

template mixin GlueCodeForService(T)
{
    static foreach(method; getMethodsForGlueCode!T)
    {
        mixin GlueCode!method;

        unittest
        {
            ...           
        }
    }
}

template getMethodsForGlueCode(T)
{
    enum getMethodsForGlueCode = ...;
}

template mixin GlueCode(alias method)
{
    ...
}
There's a lot of stuff that is probably unfamiliar. Firstly, we have mixin templates. They basically generate code and paste it on the spot where they are mixed in, based on a number of arguments, in this case type T of our service. We have a helper template that defines a constant enum value, consisting of all the methods in our service that need only glue code (example annotated with @GlueCode). For each method that we need to generate a glue method for, we generate an endpoint and a corresponding unit test to keep your colleagues happy. We can then mixin the code for every service that we need to generate.

I don't think this is useful in any way, but it is fun to think about how and why we do things.
 

Somnid

Member
Oct 25, 2017
2,425
At work, we have several services which act as kind of a gateway to the database services. Some of their methods do have actual business logic, but many of them basically look like this:

Would you write a unit test for a method like this? Some coworkers insist on it, but I don't see the point. The tests they write are basically mirrors of the methods, just with mocks. That's how the tests usually look like:

I just don't see the point. The method doesn't have any real behaviour. It's just glue code. All this test does is to make sure that the backend service is called with the bar String. The assertion after the call is useless, as well as the implicit assertion in the second expectation (convert foo).
Pretty much every code change to the method will make this test fail. It has no value. A coworker made the point that if, for instance, a developer replaces bar with null in the getFooByBar call, the test would point this out. Well, yeah - but 1) the IDE would highlight the unused parameter, 2) our SonarQube would even post a comment about the unused parameter in the merge request, 3) an integration test would point out the issue anyway, and 4) If you want, you can add an undetected error to pretty much any method, no matter how well tested.

So, yes, I already know how useless tests like this are. I just have trouble convincing some coworkers. They insist that every public methods needs to have at least one test..
What I usually tell people is to think about the value of the test. Code is liability, this includes test code, so if the test doesn't seem valuable, don't write it. It adds to build time and when making changes it can make your code unnecessarily brittle, nobody likes fixing 200 unit tests. So ask yourself "is this code a likely point of failure?" "how much confidence do I have it works correctly?" or "is easy to subtly mess up in the future?" if you feel good about those things then perhaps it's best to skip writing the test. But you do have to negotiate it with your team because a good rule is if someone asks for a test it's supposed to be a check that you didn't just get lazy.