How to write code with less Ifs?

...

Other urls found in this thread:

youtube.com/watch?v=MNYuaEluUgQ
paltman.com/try-except-performance-in-python-a-simple-test/
docs.python.org/3/library/stdtypes.html#typesmapping
en.wikipedia.org/wiki/Hash_table
docs.python.org/3/reference/expressions.html#in
github.com/python/cpython/blob/master/Objects/dictobject.c#L650
wiki.python.org/moin/TimeComplexity
twitter.com/NSFWRedditImage

with switches

>using JavaScript
Ask the pajeets if you don't mind

>when you discover Python has no switch or case statement.

Fuuuuuuuuuuuuuu

object orientation

it was literally made for exactly $this

Polymorphism

Fuck switches ... I mean, using more functions, objects or I don't know. I want to know how to create code more readable or wit hbetter structure.

Could you show me an example? Code with statements vs polymorphism

that's like asking how to talk in first person without using first person pronouns.

Only way is if the IF is part of the query

mfw when ma OO and ma Polymorphism.

Here is your answer.
1. Compose functions which follow SRP.
2. Use ternaries.
3. Ban yourself from using if/else.

Sorted.

Use perl short circuit operators.

>SRP
Have you got any tutorials or interesting articles about SRP?

Using try catch and making the true condition generate an exception.

>OP image
if not ... end
if ... end else ... end

No need to nest them.

{
item: function,
item2: function,
...
}[thing to do with appropriate transformations](arguments)

youtube.com/watch?v=MNYuaEluUgQ

{ case1: function1, case2: function2, case3: function3}[ case ]();

create functions that sanitize the code checked instead of putting if statements and don't nest ifs conditions if its not requiered

Switches can let you do that. A switch with each case calling a separate function is well structured and readable.

use goto

Maybe better data structures, maybe better stream processing, maybe better encapsulation.

Give an example of some code with too many ifs and let's see if we can improve it.

Try it out. Like, actually try replacing some ifs with gotos in a program and make sure it runs. Don't just be like "lol I don't have to try it because I know it'll be shit", just do it.

if (bad thing) {
// throw error
// return
}

// more code

if (another bad thing) {
// throw error
// return
}

// even more code

// return some final value

gcc

Removing if/else statements from your code doesn't really remove them, it just hides them behind abstractions. Just use them if that's what you find easiest.

I don't have it already. But my friend has. It was one object with a lot of methods and if statements. He like this code and I don't know understand why.

do something like:
while () {

break;
}

try/catch

try:
something.could(error)
catch:
do something if error

It can be faster too. not applicable to all scenarios, will reduce the number of if statements in code if used correctly tho

def switchMeBaby(case):
"""
This structure is the pythonic equivalent
of a switch case structure.
"""
return {
1: print("1"),
2: print("2"),
3: print("idk tbqh")
}.get(case, 3) # 3 is default if case not found

That sounds good but I don't know how to use it for sure in real life could you give me real example?

shoving loops in as much shit as possible helps at times. Also abstracting everything into numbers allows you to make stuff into simple equations, cutting down on code length

>It was one object with a lot of methods and if statements. He like this code and I don't know understand why.

He's a brainlet user. Don't hang around brainlets.

d i c t i o n a r i e s

How would you write this differently in js ?

error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
alert(msg);
}

Switch so that the uppermost if case is evaluated first makes it nice and neat

polymorphism would be doing something like passing in function pointers for comparison in a sorting function instead of writing 18 different sorting functions for different data types or writing a ton of if statements to handle all the types.

Using fetch.

Here is a simple example in python:

# Try/Catch:
dictionary = {'a':1, 'b':2}
try:
c = dictionary['c'] # attempt to get item at 'c'
except KeyError:
dictionary['c'] = 3 # Set 'c'

# If/else:
dictionary = {'a':1, 'b':2}
if 'c' in dictionary: # check if key 'c' is in dictionary
c = dictionary['c']
else:
dictionary['c'] = 3 # set 'c' if 'c' not in dictionary

In this example, the if/else looks nicer but is much slower. For the if/else segment, the interpreter will search for the key 'c' in dictionary iteratively and return True if found, while the try/catch will just attempt to access the key 'c', and if there is an error while executing that statement, it is handled below, no searching required.

Like I said before, this isn't applicable to all control flow cases, but it can be more expressive and much faster than if/else in many cases

This is a good place to start. Less of
if (goodCondition) {
if (otherGoodCondition) {
// Long code goes here
} else {
fail2();
} else {
fail1();
}

... this, and more of
if (badThing) {
fail1();
}
if (otherBadThing) {
fail2();
}
// Function proceeds, knowing all is well

This is called happy path, or return early. Avoids writing the actual function already 2 or 3 ifs deep, and each failure condition is clearly tied to a failure result.

His code was like this

Why ?

Could just use a map which have predefined values and do msg = msgResponse(status)

Checking if a key is in a dict is approximately constant time. The exception is probably slower by just a little but I'm curious so I'm going to test.

Nice, thanks

because it's better

true, accessing keys in a dictionary is constant time, that is what makes the try/catch faster.

In my example, the if statement searches the dictionary's list of keys, which is in linear time, not constant time.

The try/catch only attempts to access the key, no iterative searching required, which is constant time, making it faster.

no prob

That's incorrect. Checking if a key is in the dictionary is what that if statement does and it does it in nearly constant time. Instead of finding it in the docs, I tested with a small list:

def trycatch():
dictionary = {'a':1, 'b':2}
try:
c = dictionary['c'] # attempt to get item at 'c'
except KeyError:
dictionary['c'] = 3 # Set 'c'
return dictionary

def ifelse():
dictionary = {'a':1, 'b':2}
if 'c' in dictionary: # check if key 'c' is in dictionary
c = dictionary['c']
else:
dictionary['c'] = 3 # set 'c' if 'c' not in dictionary
return dictionary

def dictget():
dictionary = {'a':1, 'b':2}
c = dictionary.get('c')
if not c:
dictionary['c'] = 3
return dictionary

from timeit import timeit

print(f"try/catch: {timeit('trycatch()', number = 1000000, globals=globals())}")
print(f" ifelse: {timeit('ifelse()', number = 1000000, globals=globals())}")
print(f" get: {timeit('dictget()', number = 1000000, globals=globals())}")

try/catch: 0.580322099965997
ifelse: 0.24982563697267324
get: 0.3444434580160305

I'll test on a larger list in a sec

>return after throw
Is b8

>exception is a string
B8

look, this isn't a cut and dry one is always faster than the other situation, this example was intended to be a simple introduction to try/catch for OP.

Sometimes the try/catch is faster than if/else. Generally as the a dictionary's size increases, try/catch becomes faster.

link: paltman.com/try-except-performance-in-python-a-simple-test/

pattern matching and guards

Also, with a try/catch, if the key already exists in the dictionary, you dont even have to search first. So when you generally expect the key to exist, try/catch is the more suitable option.

from random import randint
def r():
return randint(0, 1000000)

with open('/usr/share/dict/words') as file:
words = {line: r() for line in file}

def trycatch():
key = 'notindict'
try:
c = words[key] # attempt to get item at 'notindict'
except KeyError:
c = 3
return c

def ifelse():
key = 'notindict'
if 'notindict' in words: # check if key 'notindict' is in dictionary
c = words[key]
else:
c = 3
return c

def dictget():
key = 'notindict'
c = words.get(key)
if not c:
c = 3
return c

from timeit import timeit

print(f"try/catch: {timeit('trycatch()', number = 1000000, globals=globals())}")
print(f" ifelse: {timeit('ifelse()', number = 1000000, globals=globals())}")
print(f" get: {timeit('dictget()', number = 1000000, globals=globals())}")
slightly modified to avoid having to make millions of ~100000 sized dicts.

try/catch: 0.49404488992877305
ifelse: 0.1678085969761014
get: 0.2568349519278854

Boolean minimization

since you linked something about python2, I tried it in python 2:

try/catch: 1.26080799103
ifelse: 0.146075963974
get: 0.240267038345

again, this is only for the case when the key isn't expected to exist. If the key exists, try/catch is going to be faster because it doesn't need to check anything, it just executes.

However, I appreciate your contribution, you have showed me that the 'if item in dict' is generally faster than try/catch if the item doesn't exist.

This makes me wonder what the underlying mechanism of the 'if item in' is. Does it search the keys? Does it attempt to access the item and bypasses the exception handling system?

I can't seem to find anything other than stack overflow threads about it.

I guess this is the problem with python.. You don't really know whats happening underneath, you are just suppose to know the best way of doing things

Use pattern matching.

The point I want to make is that exceptions are not flow control. If I could bold that I would because it's important.

here it is when the key is in the dict (I used the key 'exception')
$ python2 testit
try/catch: 1.23828005791
ifelse: 0.13214802742
get: 0.238837003708
$ python3 testit
try/catch: 0.46092819003388286
ifelse: 0.15093874605372548
get: 0.24834226095117629

Do you know about hashsets and hashmaps? Hashmaps are a datastructure with O(1) asymptotic run time for checking if a key is present, getting a value associated with a given key, and insertion. In the very worse case these operations are O(n) (this is when hashes collide)
Dictionaries in python are hashmaps.
See docs.python.org/3/library/stdtypes.html#typesmapping and en.wikipedia.org/wiki/Hash_table for more information.

It bears repeating: excpetions are not flow control.

(also I know I'm showing some example with python2 but please please please don't write in python2 unless you absolutely must, there are so many reasons to move to python3)

I am well aware of what hashmaps and hashsets are. My question was regarding what the 'if item in dict' statement actually does underneath.

Also, python dictionaries are an abstraction on top of a hash table. They are objects with other data structures and methods that contain data like the unhashed keys. This is why I am curious as to how this works and there is no clear resources that explain it

also these tests disagree with your results: paltman.com/try-except-performance-in-python-a-simple-test/

Karnaugh Maps

where is the fallthru without code duplication?

docs.python.org/3/reference/expressions.html#in
Their use of 'equivalent' is confusing. But it seems to be up to the implementation how to implement it.

Here's cpython's hash lookup that gets called when checking membership: github.com/python/cpython/blob/master/Objects/dictobject.c#L650


Here's my program edited to run in both python 2 and 3. Feel free to try for yourself. I've played around with the order it runs the tests in to make sure that caching isn't doing anything and all that.
from random import randint
def r():
return randint(0, 1000000)

with open('/usr/share/dict/words') as file:
words = {line: r() for line in file}

def trycatch():
key = 'exception'
try:
c = words[key]
except KeyError:
c = 3
return c

def ifelse():
key = 'exception'
if 'exception' in words:
c = words[key]
else:
c = 3
return c

def dictget():
key = 'exception'
c = words.get(key)
if not c:
c = 3
return c

from timeit import timeit

print("try/catch: {}".format(timeit(trycatch, number = 1000000)))
print(" ifelse: {}".format(timeit(ifelse, number = 1000000)))
print(" get: {}".format(timeit(dictget, number = 1000000)))

ah! found it wiki.python.org/moin/TimeComplexity

Firstly, exceptions are designed to handler errors, not to run performance-critical code. There is not reason for developers to optimize throwing an exception, so don't rely on them for performance.

Secondly, when an exception is thrown the program has to:
- propagate the exception up to the first try block which can handle it
- clean up the scope that every try block has created along the way
- up the correct exception handler based on the type of the exception
For some languages clean up means stack unwinding (very expensive), calling deconstructors, releasing references, and so on. It depends on the language. Either way, the whole process of catching an exception is much more than a single if/else.

Thirdly, there is no magic sauce behind using a try/catch instead of an if/else or the get() method. They both use the same internal algorithm to get the value based on the key. An interesting thing is that python seems to cache the value when using the `in` keyword because checking if a key is inside a dictionary and then actually accessing it is a very common pattern. The third method should, at the first glance, be as fast as the second, but it's not because python has a pretty big overhead for calling python methods. It could've also be written as c = words.get(key, 3) which is the recommended way since in your code the key may exist in the dictionary with the value 0 associated, failing the test `if not c` and replacing it with 3.

I've found that I can do a lot to escape if's and for's by using chains of maps, filters, and reduces

>in your code the key may exist in the dictionary with the value 0 associated, failing the test `if not c` and replacing it with 3.
ah crap, I always forget that 0 is truthy.

>>Python has no switch or case statement.
Well, it looks like I have no reason to learn Python anytime soon

Write small functions with the if at the end. IF *condition* return. Then your else is the fallback.

its better to use function pointers and an enums

if ($first != 0) {
return "error 500";
} else if ($second == $third) {
$first = $second + 2;
return $first;
} else {
return "error 501";
}

Quick someone post the Yandere Simulator source code

usually nested ifs can be simplified. do a logical disjunction of all conditions and try to simplify it

>elifs literally the same as switch case
>"ayyy lmao, python is cucked. Looks like I'll stick with Java (the only language I know)"
Why are there only retards on Sup Forums

write a finite state machine generator

The ifs will be done one way or another in the code. Maybe you will code it, or the guy who coded the framework you are working with did it.
What you can do, is to abstract each part of the statement to give clarity on what it does, so when reading it again you have an idea of what your program is doing.
Also, if you are in objects, you might be able to solve it through new objects or methods, or you might even find a design pattern that fits your solution.

Ternary operators.

>Java (the only language I know)
Well, that is certainly not true.

>python
>good in any way shape or form
Why do these retards infest Sup Forums as well

Code that doesn't branch is worthless.

youre saying arithmetic instructions are worthless? (add, sub, xor, and, etc)

Functional programming to reduce flow control in general, strong functional decomposition, ternaries, which are a poor man's pattern matching.

JS is actually pretty good at functional programming now, complex destructuring and restructuring of both arrays and objects in expressions and arguments, arrow functions, object rest and spread, even do expressions are a stage-1 proposal, and currying has a decent proposal as well, but I think it's still stage-0.

Even in ES5 you could do the old

{
case1: fun1,
case2: fun2,
case3: fun3,
}[value]();

Oh, and I forgot to mention declarative style.

because it's the most sane scripting language and also capable of oop.

nobody wants to write complicated things in perl, because you wouldn't be able to understand any of it by the time you are done
nobody wants to write complex things in ruby, because half the gems are broken or deprecated, the documentation is incomplete unless you are able to decrypt moonspeak.
nobody wants to write complex things in bash or shell because both are nothing more but essentially wrappers with scripting functionality with a terrible syntax
nobody wants to write complex things in js, because its design is bad and running this type of shit outside of a browser is like running VB on a terminal server
nobody wants to write complex things in php, because it's not only terribly designed by a coding-analphabet who was to lazy to learn something that did things sufficient

it's also insecure because the coding-analphabets who jumped the php-hype train have no idea how to design a language

Try using more math and indexing. Compute everything then select the correct answer.

What if your program runs on weak cpu and it can't throw exception hard enough to exit the function?

I always assumed this is a way to go, but I see a lot of examples of crazy nesting in some big projects.
Also I recall some old fart was against multiple exits because it makes it "unclear" and "hard to predict".

For loops are incredible alternatives.

while/breaks are one of the ugliest constructs in programming, even worse than loop-and-a-halfs

because anyone worth a shit leaves
only the retards stay because they continue to get (You)s meanwhile on other sites they just get blocked/muted/filtered

>loop-and-a-halfs
whats this?

think about something where the exit status of the while loop depends on operations done within the loop; the first time you run the loop it will throw an error because the operation hasn't happened yet. you have to copy some of the contents out of the loop into the code before the loop starts so that there's something for the first pass of the loop to check.

a do/while loop would solve the problem but some languages don't have that.

oh yeah ive needed that before, thankfully C does have do while.
is
>loop-and-a-half
the "official" name? had never heard it before

Have they drunk enough functional kool aid to have pattern matching yet?

A switch statement is one such example.
But really what I think you're actually looking for is the deeper understanding of the problem that lets you make a less discrete solution and a more analog one.

Depends on the problem obviously.
Some languages are great at giving you pretty options for dealing with redundant typing of conditionals. One of the heavy handed methods is using inheritance driven polymorphism in object oriented programming (imo it doesn't usually lead to nicer code unless you're in a deep deep hole). Another less heavy handed is pattern matching in many functional languages.

It'd be better if you have an example.

Came here to say this. Ternary operators are life. I want to have children with the ternary operator. We will raise kids that only make the most terse and efficient decisions.

that's a funky way to do things, but i guess python is funky. an entire function just to do a switch statement.

still think an array of function pointers (essentially a hash table) is better than a switch (dont think you can do that in python either though)