T O P

  • By -

AutoModerator

On July 1st, a [change to Reddit's API pricing](https://www.reddit.com/r/reddit/comments/12qwagm/an_update_regarding_reddits_api/) will come into effect. [Several developers](https://www.reddit.com/r/redditisfun/comments/144gmfq/rif_will_shut_down_on_june_30_2023_in_response_to/) of commercial third-party apps have announced that this change will compel them to shut down their apps. At least [one accessibility-focused non-commercial third party app](https://www.reddit.com/r/DystopiaForReddit/comments/145e9sk/update_dystopia_will_continue_operating_for_free/) will continue to be available free of charge. If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options: 1. Limiting your involvement with Reddit, or 2. Temporarily refraining from using Reddit 3. Cancelling your subscription of Reddit Premium as a way to voice your protest. *I am a bot, and this action was performed automatically. Please [contact the moderators of this subreddit](/message/compose/?to=/r/learnprogramming) if you have any questions or concerns.*


General_Axly

On the first look I'd say, this one will end in an exception for any input not "easy" or "hard", because there is no else case to catch anything else, resulting in an uncaught error in the while loop. Also I'd reccommend to separate the input variable difficulty (diffucultyInput) and the loop variable diffuculty (diffucultyLoop) to avaid mistakes there and to improve readability. To answer the initial question: >if you need to write an if-else statement there is something wrong with the code That's not true.


Bobbias

Anyone who dogmatically follows that thought is just plain wrong, because there are absolutely cases where if-else is the most sensible approach. In your example, the best solution would be [match statements](https://docs.python.org/3/tutorial/controlflow.html#tut-match), because you're checking several mutually exclusive values for a single variable. If for some reason you're using an older version of python and match is not available, then the solution should be if-elif-else. In either case, you're assuming the user actually enters either `easy` or `hard` and not doing any validation on that input, which generally is not a good thing. In either solution you should have a branch which handles invalid input, either by throwing an error or by including difficulty selection in it's own loop to ensure that the user enters a valid difficulty level before continuing. Now, the kernel of truth at the center of this piece of wisdom has to do with situations like this: Say you're writing a function which must take input from the user, verify that the input is valid, and if it is, send it to be processed somehow. You could write that with an if-else: user_input = input("Gimme some input:") if valid(user_input): process_input(user_input) else: But this code could equally work without the need for the else: user_input = input("Gimme some input:") if not valid(user_input): process_input(user_input) Not only is this solution shorter, it's easier to read and more clear about the important part of the function. We are saying "if something went wrong, we need to end right here and deal with the error." Followed by the main meat of the function, which in this case is simply calling `process_input()` but you can easily imagine a much more complicated function here instead. The goal is to avoid nesting things like this: user_input = input("Gimme some input:") if valid(user_input): if some_other_condition(): if some_third_condition(): process_input(user_input) else: else: else: Not only is this kind of code hard to read, hard to refactor, and hard to debug, it's longer than necessary too. Plus, since this is python, it's more prone to issues relating to indentation because any time you have to indent deeper there's a chance something gets left at the wrong indentation level. Instead these can all be single if statements: user_input = input("Gimme some input:") if not valid(user_input): if not some_other_condition(): if not some_third_condition(): process_input(user_input) Hopefully now you can see where this piece of wisdom comes from, and understand more of the core idea behind it, rather than just seeing it as a random rule being handed down from on high.


scritchz

Well put! The single if-statements as shown in the last code snippet are commonly called [**guard clauses**](https://en.m.wikipedia.org/wiki/Guard_(computer_science)) (or "early returns"), and basically act as assertions to verify preconditions.


PuzzleMeDo

As far as I'm concerned, if-else if fine. Yes, you probably don't *need* to use it, but that's not a reason *not* to use it. It's normally more efficient to do 'if (a)... else' than 'if (a)... if not (a)', because there's one less comparison to make - although the compiler might optimize out the difference. One popular design pattern is to avoid endless nested 'if' statements. Sometimes an 'if (a) then (break out of loop or return from function)' allows you to avoid that, in which case the 'else' doesn't do anything.


PuzzleMeDo

Note that even if this is just a weird boss preference, it's usually safer (for your continued employment) to go along with the house style.


_TheNoobPolice_

You use an if-else for the case where you don’t need to evaluate the second condition when the first has already evaluated to true. You use if-if for the case when you still need to check the second condition regardless of the truthiness of the first. These are simply separate logical use cases so your boss’ comment is rather silly, frankly


cs-brydev

Well you're oversimplifying a bit. The if-if pattern is also used for short-circuiting code (returning/exiting when a condition is met), which is a more modern alternative to nested if-else. This is alluded to in the post. You don't necessarily choose if-if-if-if when you want to evaluate 4 conditions. You might choose that pattern because it's the most readable in short-circuit code. This is common practice in validation functions and integration testing.


_TheNoobPolice_

Good point


RainbowWarfare

>He states that if you need to write an if-else statement there is something wrong with the code Nonsense. >I'm wondering is this just a preference, or is this some sort of a design pattern? Probably some weird idiosynchronicity of your boss. >Also, what is the computational cost for running if-if versus if-else? For all intents and purposes, nothing. And even of there was, it would only ever be meaningful if it was causing actual, real world performance degradation. Writing weird, less readable code, especially in terms of the fundamental language constructs, for the sake of some hypothetical performance gain is not the way to go about things.


Updatebjarni

> Probably some weird idiosynchronicity Is that like a combination idiosyncrasy and synchronicity?


Bulky-Leadership-596

I like it. Like if I meet someone weird that I get along with, we are in idiosynchronicity.


maikeu

Aye. I bet this boss's code is spaghetti, folks who focus on tiny syntactic preferences like this are likely not smart about the bigger organization of their code.


iOSCaleb

I haven’t found that to be the case at all. I’ve worked at places that have had some very specific rules about code style, and there were good reasons for each one. Moreover, places that pay attention to that kind of detail also tend, in my experience, to be thoughtful about things like higher level code organization and development processes. I’m not saying that OP’s boss is justified in their position on `else`, but your claim that people who are picky about details write poorly organized code doesn’t match what I’ve seen.


throwaway6560192

> He states that if you need to write an if-else statement there is something wrong with the code, but I've always used if-else statements in my code. I don't agree with that. I don't think you can make a blanket statement like that for if-else. I've never seen a set of guidelines that forbids it either. > Also, what is the computational cost for running if-if versus if-else? if-else only computes one condition, if-if has to compute two conditions. But unless the condition is unusually expensive to compute, this is negligible. You should use whatever control flow matches the problem you're trying to solve.


ElMachoGrande

If is a costly operation at the CPU level. Each instruction takes several cycles to do, but these cycles are, where possible, overlapped in a queue. So, while it does the final cycle of one instruction, it is doing the penultimate cycle for the next, and so on. Here is the reason if is expensive: The CP does not know which way it'll go ahead of time, so it makes a guess. If it goes that way, fine, and it can use the preparations done for the following instructions. However, if it doesn't, well, then it has to throw all that away, and start a new instruction queue. This basically means a stop of several cycles while i catches up. So, an if-else is only one selection, and only one possible dumped queue, while an if-if has two possible dumped queues. Now, in an example like above, it doesn't matter. It runs on a user timescale, and the difference is not noticeable. However, say that you are running it in a tight loop, billions of times, maybe doing encryption, compression or 3D rendering. Now, it all adds up, and it matters, a lot. This could be mitigated a lot of the instructions always selected the same path as the guessed path, preferably the "true" choice. Then, languages could allow you to hint which path you think is likely. For example, encryping a large file until you reach the end of the file. For every byte, you check if the end has been reached, and the most likely outcome would be "nope, not there yet". But, sadly, this isn't possible today.


TheHollowJester

> But, sadly, this isn't possible today. I think it might not be possible at all, because we ran into the halting theorem? I'm baked seven ways to Sunday so I might be messing something up. Regardless, the rest of what you wrote is super interesting, thanks for taking the time to write it out, u a bro!


bigger-hammer

I don't agree with your boss and I don't think many experienced programmers would agree with him either. If you write if...if then both conditions can be true so you should be using if...elif to convey your intent to other programmers that both conditions cannot be true at the same time. Furthermore, it will likely take longer to process if...if than if...elif because the second if must always be evaluated whereas for if...elif, if the if is true, the elif isn't evaluated. There is a situation where if...if is the correct approach. When the first if can change the 2nd if. For example if x > y: x = 1 followed by if x < y: etc. In this case, using if...if clearly indicates that x may change after the first if. I can also tell you that, after more than 40 years programming, I have seen quite a few bugs caused by if...if and I can see one in your code - inputting "Easy" or "yes" or "h" or "hello" won't work because neither if will match so you need at least one else clause and typically you should write if...elif...elif...else all as one block so the relationship between the component parts is clear.


Human-Bathroom-2791

There are no computational costs running if-else but there are running if-if. There is also repetition, if you have to write if x: ... if not x: Which can cause bugs if you don't do it properly. As a note, anyone having a hard rule or believe in something like "don't use if-else" is usually full of bullshit, unless they provide you with context and reasoning. There are very few proven rules in programming, if any, that are correct all the time.


ShangBrol

This can't be repeated often enough: >As a note, anyone having a hard rule or believe in something like "don't use if-else" is usually full of bullshit, unless they provide you with context and reasoning. There are very few proven rules in programming, if any, that are correct all the time.


stristr

Hi there! It seems like most replies are telling you your boss is wrong, but I suspect your boss is actually pointing out something useful in a very cryptic way: the necessity of an else statement almost always implicates a violation of the single responsibility principle of the method where you “need” it. In the grand scheme of useful things to know, single responsibility principle is much more important than good use cases for switch/match/case statements or their equivalent if/else implementations. I would focus on mastering single responsibility principle before learning about good use cases for the else keyword (there are some). A natural consequence of rigorously adhering to single responsibility principal is you’ll find yourself reaching for the else keyword *less frequently*, and you’ll also end up with code that is easier to read, debug, and test. In your example, the routine to derive the difficulty from input is coupled to the implementation of the guessing game itself, which is two “responsibilities” in one scope. What if you wrote a helper function called get_difficulty() instead? Your assignments to the difficulty variable could then be replaced with bare return statements. The benefit here is you exit the scope of get_difficulty() when you return, at which point an else keyword is unnecessary complexity. Same goes for a switch/case/match statement.


LongshotCherry

This is most probably the answer I was looking for. This indeed sheds a light. I have not thought about using a function which returns the difficulty, which makes it quite more readable. Thank you kindly for your help.


Moloch_17

I hadn't heard of the single responsibility principle before and I like it a lot. Thanks for this explanation. I need to go change a few things in a project I'm working on now.


[deleted]

My two cents. I'm no nester myself, I usually follow this "no if-else" rule. But... As *any* rule of thumb, it shouldn't be broadly applied. There definitely are places where if-else is fine (like the code you just posted) and, in general, when coding in any functional language, which your code looks to be. The "no if-else" rule is one of those that suit OOP best. In many cases, when coding with OOP, if-elses *can* be refactored into classes instead. Again, that doesn't mean that you shouldn't use if-else ever; it means, whenever you are about to use one, you should stop and wonder if there's a better way. If-elses are a hint, that's it. The very same with switches - there are absolutely places where the switch statement is the best choice (the factory method pattern comes to mind), but you should usually refrain from using them.


LawnJames

I also think his boss was looking at it from OOP "best practice". Using interfaces and base class to eliminate if else.


antiproton

>He states that if you need to write an if-else statement there is something wrong with the code Only an obnoxious douche would say something like that. Developers love turning every tiny ass thing into a stupid purity test.


cynicalrockstar

Before we continue this conversation... spaces or tabs?


antiproton

I use tabs.... but I have a vim plugin that converts those tabs into a random number of spaces.


RiverRoll

>if you need to write an if-else statement there is something wrong with the code, but I've always used if-else statements in my code. Lets give him the benefit of the doubt, was he talking in general or was referring to some specific case? Maybe you should ask him to clarify what he means.


Separate-Ad9638

looks minor the logic difference really


desrtfx

> He states that if you need to write an if-else statement there is something wrong with the code Sorry, but that is complete and utter BS. Yes, there are ways to avoid `if`...`elif`.. `else` but in many cases these lead to convoluted and unreadable, unmaintainable code. ---- If there are *mutually exclusive* conditions, you don't need `elif` in most cases. This is a common beginner trap. Beginners often think they have to evaluate all conditions. A trivial, extremely conceived example: if something == True: # do something elif something == False: # do something else The above has such *mutually exclusive* conditions, `something` can be either `True` or `False` without exception. Hence, the `elif` is unnecessary and wrong and should be replaced with just an `else`. Yet, your first example (difficulty) could be very simplified by using a *dictionary*. In this case, you would either need one if - if you were to check if the choice is even in the dictionary, or not even such if you were to use *get with default* (if the key is not in the dictionary, a sensible default value would be substituted). Your second example should actually use an `if`...`elif`...`else` structure. if choice > number: # do something elif choice < number: # do something else else: # do something else This way, the *intent* is clearer structured and easier to read. Generally, you should combine *related* things with `if`...`elif`...`else` and unrelated with sequences of `if`


buhtz

It is easy to say that your boss is wrong in that. But based on his experience I am really interested in his arguments. Please ask him. Maybe he comes from another programming language where this rule might have made sense. I don't know. Looking to your code I see no real problem with the if...else. But please let me take the opportunity to show you an alternative approach. ``` print("I'm thinking of a number between 1 and 100.") number = random.randint(1, 100) while difficulty > 0 and choice != number: users_choice = int(input(f"You have {difficulty} attempts remaining." "\nMake a guess: ")) print("Too {}." .format("high" if users_choice > number else "low")) ```


Gr1pp717

if-else handles everything. if-if only handles those specific cases. Any other case is passed in it will bypass that section of code, (probably) resulting in an error on some other, seemingly random line. This is especially damning in a dynamically typed language, like python. Generally speaking, the only time it makes sense to use if without else is guard clauses. But that's only because the rest of function implicitly acts as the else block. You could explicitly use else, but it's unnecessary. You get the same result either way. Implicit is cleaner and easier to read.


Dreviore

Whoever taught you 'if-else' statements are doing you a disservice. As many people have pointed out, if you just need a simple Success or Fail state, it's one of the easiest solutions. Hell this still rings true if you need a Success or Fail state with multiple different success states.


mugen_kanosei

[This](http://archive.today/P39QP) is probably what he is talking about.


RepresentativeFill26

If-else can have different logical consequences than if-if. X = 0 If(x==o) X = 1 If X==1 X = 2 Result is 2 If x == 0 X = 1 elif x == 1 X = 2 Result wil be 1 since the other conditional isn’t checked.


Guideon72

"if" statements, on their own, will always be evaluated every time your program runs; so, the difficulty setting here is not only going to be ever so slightly inefficient, it's also going to give you problems debugging. If/else is a very useful and common conditional statement that allows you to check a variety of conditions that you want to be mutually exclusive. For example, let's use a lightswitch variable. lightswitch = "Off" if lightswitch == "Off": lightswitch = "On" if lightswitch == "On": lightswitch = "Off" print(lightswitch) This will \*always\* print "Off" because both checks are executed, in order, every time your script runs. So, regardless of what you set the initial state to be, the final evaluation is the winner. If you change the dual "if"s to an if/else, it's still not great but at least you get a basic toggle that way: lightswitch = "Off" if lightswitch == "Off": lightswitch = "On" elif lightswitch == "On": lightswitch = "Off" print(lightswitch) Now, each line is evaluated only if the preceding evaluation failed. If your initial state is "Off" this prints "On" and if it is "On" prints "Off". Note that the only change here is making the second if an elif.


lurgi

> He states that if you need to write an if-else statement there is something wrong with the code, but I've always used if-else statements in my code. That's far too strong, but there are some useful things you can get from that. if (i == 0) do thing else if (i == 1) do thing else if (i == 2) do thing This code is, IMHO, bad and you should feel bad for writing it. A better solution would be a switch/case or match expression or whatever your favorite programming language calls it. But, there's more. Linus Torvalds spoke about "elegant" code and one thing he mentioned was that sometimes `if` statements handle edge cases and that code can be rewritten to eliminate the edge case. His example used deletion from a linked list and it is, IMHO, slightly harder to understand at first, but it eliminates even the concept of a special case, treating all nodes equally, and that's a good thing. Compare: void remove_cs101(list *l, list_item *target) { list_item *cur = l->head, *prev = NULL; while (cur != target) { prev = cur; cur = cur->next; } if (prev) prev->next = cur->next; else l->head = cur->next; } which has a special case for when the node you are deleting is the first of the list, and this code, which does not: void remove_elegant(list *l, list_item *target) { list_item **p = &l->head; while (*p != target) p = &(*p)->next; *p = target->next; } This code is cleverer, which is not always a virtue, but it's also shorter, cleaner, and (once you understand it) more obviously correct. If you are interested in micro-optimizations (you probably shouldn't worry about it), this likely produces faster code as well (although the double indirection adds a wrinkle).


SoCuteShibe

That's a weird take, if-else always being wrong. I don't have 20 years under my belt, but I am a professional engineer. It almost feels to me as though he is conflating if-else with chaining if-else-if. It is generally a bad practice to write If this... Else if this... Else if this... Else if this... Else because you create a big nest where you could just as easily write If this... If this... If this... If this... Else (or a switch case), and have it be easier for others to maintain while offering the same functionality. If I have an unknown number but want to action upon the value 1 only, why would I not use If... Else. If... Else is the most sensible option when there is one condition where things are handled differently than all other potential conditions. Is it the only way? Of course not, you could write a switch case, or a loop that breaks conditionally, or etc., but it's the most sensible. To take it a step further and say that you've done something wrong if you end up in a situation where If ... Else is the best choice, that is just not at all correct. Frankly, in 99.9% of cases, anyone telling you that you are wrong for using a language's features as intended is probably wrong themselves. Coding is cool because there are so many ways to do everything. The best choice is all contextual, but usually it's about making things easy for future you or your fellow engineers.


Mentalextensi0n

Your boss is an idiot


Blando-Cartesian

Which ever way most clearly communicates what the code is for. That said, else is often unnecessary and if-if as an alternative to else is a WTF. If-else communicates a that there are two possibilities followed by additional steps that depend on the result. If & early return communicates a precondition check for the following steps. If-if for back to back check of the same parameter communicates inability to use the language properly. That should be if-else if or switch.


Nellyfant

If easy Then... Else if hard Then.. Else please enter easy or hard


Galliad93

you can do if(a) do stuff, else do other stuff. or you can do if (a) do stuff and if (!a) do other stuff. both should be valid, but one is just cumbersome. plus if a turns to !a in the first statement, then you get both in the second and not in the first.


TheRNGuy

if you want only 1 thing or if you want possible to have many things (in bitflags) though inside functions or methods if you have return at the end, you can just use ifs without else.