A guide on how-to deal with programming challenges, keep your code clean and survive any programming course - by a guy who did it all wrong.
There are many ways of solving programming problems. Some of the most known are:
You rarely use them separately, usually you mix them up. Even though there are some significant differences between these methods. All of them share the same thing namely, they divide a BIG problem into smaller problems (small enough to be solved). Thus, in my opinion Divide and Conquer is the best technique for problem solving.
Lets say that you are a lumberjack. Valentine's day is coming and your spouse wishes for a rocking-chair. You have no experience with carpentering, and you don't want to disappoint your spouse. Ambitiously, you decide to make the best rocking-chair ever made. From IKEA you got blueprint (so you now know how-to assembly a chair), and you are ready to go.
You start doing what you do the best. Namely, you cut (get) the tree. Obviously, entire tree is to big, so you chop the tree into smaller pieces of a raw wood. After x strokes and 30 minutes later, you have 33 raw wood pieces. You take first piece of a wood, and you make from it a part of a chair (an arm), you take second piece of a wood, and you make from it (a leg) etc.. After, a few hours of sculpting and carving in the wood, a raw materials became valid pieces of a chair. Having all elements ready, you start assembly the chair -following blueprint instructions. Few steps, and several hours later you have the best rocking-chair ever made that your spouse will never sit on. I am joking here. Good job!. What previously was nothing more than a huge tree now became a rocking-chair.
Lets Divide & Conquer (D&C) lumberjack story into a rocking-chair algorithm. Along we will count number of steps that it takes to produce a rocking-chair.
My Rocking Algorithm (TODO list)
total_nr_of_steps = 1 + 33 + 33 + 33
Now we have to ask ourselves a question. Is there any way that we can make these steps understandable by a human, but expressed in a computer like a language? The answer is YES. We can use Pseudocode - a computer like language understandable by humans.
"""Program: Lumberjack rocking-chair makerDescription: Pseudocode for making rocking-chairsVersion: 1.0Author: J.LumberjackComments: Even though, language looks like a python it is not a python code."""Start# cut (get) the tree (1)tree =tree_cut = falseraw_wood_pieces_container =RAW_WOOD_PICES_NEEDED = 33# chop the tree into smaller pieces of a raw wood (33)while tree_cut is falseif <= RAW_WOOD_PICES_NEEDEDraw_piece =elsetree_cut = true# take a piece of wood and you make from it part of a chairgood_chair_pieces_container = Nonefor piece in raw_wood_pieces_containerchair_piece =# start assembly the chair piecesrocking_chair = Nonefor piece in good_chair_pieces_containerrocking_chair =# give the chair to your spousereturn rocking_chairStop
As we can see anyone can talk and write Pseudocode. What's left is to translate Pseudocode to any programming language of your choice (Python, JavaScript, Cobal or Asembler).
I am more than sure that many of programming challenges will be written more in to TODO list rather than lumberjack story so, It should be easier for you to come up with an algorithm.
Lets have a look at below problem.
You are given a deck of cards represented by their values (from 0 to 52). A card combines two values a suit ('Clubs', 'Spades', 'Diamonds', 'Hearts') and a rank ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace', 'Joker'). Yours task is to ask a user for a card number. The program will determine the card suit and rank base on provided number. Example card nr.24 is the Queen of Spades. Additionally, if a card is a Joker then you print "Why so serious?". As long as the user provides numbers, the program ask for another card number. To quit program write "exit".
Hints.
As we can see, the card challenge is similar to the lumberjack story - maybe it is not so pictorial but, at the bottom these stories are the same.
Since we are wiser about Divide & Conquer method, lets use it to our advantage. We start with defining TODO list that will become our algorithm.
Joker Program (TODO list) - algorithm
Simple algorithm isn't it ?
Lets proceed to the next step. We scrap the text of computing challenge to find useful information. By this I mean candidates for variables (nouns) and candidates for function (verbs). We search for all information that we know, and information that we can infer from the text and save it in KNOWLEDGE list.
Joker Program (KNOWLEDGE list)
Step 1
We create an empty file called joker.py. We rewrite TODO and KNOWLEDGE lists into comments small enough to be implemented (comments will become the skeleton for our algorithm). Moreover, we like to keep things net so we provide basic information about our program.
#!/usr/bin/python3"""Author: my@email.comVersion: 0.5Date: 12.02.2016License: MITComments: You will be given several cards represented by their values (from 0 to 52).You will need to print out their names."""## ask for a card number from 0 to 52.## As long as user provides numbers the program ask for a card number.## negative cards numbers and numbers greater than 52 are not allowed## To quit program write "exit". Otherwise, program determine the card.## To determine card's suit divide its value by size of ranks (14), rounding down## To determine card's rank, take the remainder of division by size of ranks (14)## if a card is Joker then you print "Why so serious?"
Step 2
We start implementing the comments.
## ask for a card number from 0 to 52.user_input =
Step 3
When we are convinced that or first comment is ready we proceed with testing and we run the script.
$: python3 joker.pyPlease enter a card number :
We see that program does what we intended, so we stay convinced that the program is working. We proceed to the next comment. As we are adding new features we continue testing. Code > Test > Code > Test > Code > Test > Code > Test > Code > Test > Code > Test. On the way we discover that we cannot implement code in the same order as we mentioned in the comments. That is fine with us, as long as the program does what it should do.
After 11 steps, and fixing some bugs on the way we have our first program version 0.5. Yeha!!!
Step 11
This is our program version 0.5. We proceed to Step 12
#!/usr/bin/python3"""Author: my@email.comVersion: 0.5Date: 12.02.2016License: MITComments:You are given a deck of cards represented by their values (from 0 to 52).A card combines two values a suit ('Clubs', 'Spades', 'Diamonds', 'Hearts')and a rank ('2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace', 'Joker').Yours task is to ask a user for a card (number from 0-52), and program determine the card.Example card nr.23 is the Queen of Spades.Additionally, if a card is Joker then you print "Why so serious?".As long as user provides numbers the program ask for a card number. To quit program write "exit".## ask for a card number from 0 to 52.## As long as user provides numbers the program ask for a card number.## negative cards numbers and numbers greater than 52 are not allowed## To quit program write "exit". Otherwise, program determine the card.## To determine card's suit **divide** its value by size of ranks (14), rounding down## To determine card's rank, take the **remainder of division** by size of ranks (14)## if a card is Joker then you print "Why so serious?""""# ask for a card number from 0 to 52.user_input =# As long as user provides numbers the program ask for a card number.while user_input != "exit":card_number =SUIT =RANK =LOWER_CARD_LIMIT = 0UPPER_CARD_LIMIT = 52# negative cards numbers and numbers greater than 52 are not allowedif not (card_number >= LOWER_CARD_LIMIT and card_number <= UPPER_CARD_LIMIT):print("Allowed cards range is from 0 to 52 !!!")else:# To determine card's rank, take the remainder of division by size of ranks (14)card_rank =card_rank_value =# if a card is Joker then you print "Why so serious?"if card_rank_value == "Joker":print("Why so serious?")else:# To determine card's suit divide its value by size of ranks (14), rounding downcard_suit =card_suit_value =print("The card is: ", card_rank_value, 'of', card_suit_value)user_input =print("It was pleaseure to have you. Bye bye !!!")
Step 12 Refactoring
We start refactoring - making better code. We are aiming to achieve following goals.
#!/usr/bin/python3"""Author: my@email.comVersion: 1.0Date: 12.02.2016License: MITLinks: http://www.codeabbey.com/index/task_view/card-namesComments: Given several cards represented by their values (from 0 to 52).You will need to print out their names."""user_input =while user_input != "exit":card_number =MIN_CARD_NR = 0MAX_CARD_NR = 52SUIT =RANK =RANK_SIZE =valid_card = (card_number >= MIN_CARD_NR and card_number <= MAX_CARD_NR)if not valid_card:print("Allowed cards range is from 0 to 52 !!!")if valid_card:# Card's rank = rounded down number of a Card number % size of rankscard_rank_index =card_rank =if card_rank == "Joker":print("Why so serious?")if card_rank != "Joker":# Card's suit = rounded down number of a Card number / size of rankscard_suit_index =card_suit =print("The card is: ", card_rank, 'of', card_suit)user_input =print("It was a pleaseure to have you. Bye bye !!!")
When we are done with refactoring, we test our program again and check if the changes that we made didn't break our program.
You can see that programing is not so difficult, as long as you know what to do. By looking at the examples above you will see a pattern that can be applied to any programming challenge.
The pattern:
Programming is neither so easy as the above examples. Often, you don't have all information related to a problem. E.g. What if I removed the hints from the card challenge, so you would not know how-to calculate the card's rank and card's suit. Hmm.. This is where the real programming starts. You have to come up with a solution base on limited knowladge and limited time, and you have to do it well !!!
Programming is a mixture of two feelings: frustration and satisfaction. A good programming problem will not let you sleep at night, and will keep you up. An insane programming problem will not let you sleep at night and will keep you down. Solving both gives you satisfaction. However, satisfaction in both cases has different taste.
Last but not least, programming is about improvement, and with improvement comes a new languages, concept, technologies and tools. Despite many stereotypes, programming is a highly social job. You constantly communicate and cope with other people (client, user, manager, fellow programmer, community etc..). Therefore, if you lack this skill then you better sharpen it by going for a drink in a weekend evening and enjoy time with your friends :)
A programmer is a n-dimensional being. He/She can be good in 1st dimension, suck in 2nd and be exceptional in 3rd. However, it's hard to kick asses in all dimensions.
Programming dimensions:
"Good programmers write code that humans can understand." - Martin Fowler
Being a good programmer doesn't necessary mean having a lot of experience. I met a college who claimed that he had 10 years of experience (at that time he was ~23), and didn't know how to check if an image uploaded to the server was captured in portrait or landscape mode (based on image dimension). Therefore, good programmer != experienced programmer != an old programmer.
My other colleague finished his education at gymnasium level. At the time I met him he had 5 years of experience. Always on top with the newest technologies, tools, programming concepts, but he had no idea what Pythagorean was. My other colleague similar to the previous one, had 3-4 years of experience and was the best at debugging and seeing connections within the code - it was like his brain was directly connected to a debugger. Our common colleague said he would not be able to write a factorial in a recursive way (I had a hard time believing it).
The last one, my dear friend, a university graduate, an 'A' student. He is very good at maths, computational concepts, excellent at teaching, a scientist and the best pal. He is responsible for his work and reputation. He eats mathematical/physical challenges and just by looking at code, knows which Big O it fits in. He uses tools well known to him (nothing fancy compare to others), is quite outdated with technologies, and don't care much about coding standards. The best developer that I have ever worked with.
All the colleagues mentioned above are exceptional programmers that I had the chance to work with. The common denominator for all of them is that they are passionate about what they do and, they don't stop learning. Most people would call them geeks or nerds.
"Any fool can write code that a computer can understand." - Martin Fowler
A bad programmer is a person who deviates from the above list. In short, a bad programmer does a job half done, avoids responsibility, doesn't strive for improvement and the worst of all, doesn't learn from mistakes.
Good programmers are not born. One become a good programmer by making mistakes, learning from them, working and striving for the best. Good programmer is as good as the problem. Some of the programmers whom I mentioned would not fit into mathematical problems, but they would fit into technical problems and vice versa. At the end being a good programmer is like having a driving license - it's hard to get and easy to loose.
Bonan matenon means good morning in Esperanto language. It might be the first time that you hear about this language, after all it's only 129 years old. This Indo-European language is spoken by 2 millions people (including 2000 native speakers) scattered all over the world. As any natural language, it has a grammar, tenses, and new vocabulary is created by prefixing or suffixing the root of a word. Esperanto was born in a city that intersected four different cultures. The author L. L. Zamenhof wanted to create an easy-to-learn, politically neutral language that would transcend nationality and foster peace and international understanding between people with different languages.
Every programming language has its' Coding convention/style. Python has PEP-8, PHP has PSR-2, and Java has something here. A coding convention and Esperanto language are similar. They both have a set of rules that governs the language, and aim in unification.
Unfortunately, there is a major difference between Esperanto and coding convention. The Esperanto language, has no country, unknown culture and poor identity, making it nothing more than a fancy language to know. Where is a coding convention used by every programmer in the world. It's impossible to create professional software without following a coding convention, and I'm certain that it's impossible to create clean code without a coding convention.
Good programmer sticks to a coding convention. Personally, I follow conventions to 98% of guidelines. Why is that ? Convention places handcuffs on programmers hands, and that sometimes makes it hard to write cleaner code.
"A Craftsman is only as good as his tools." - of course this is a cliche saying. However, in the programming world, good tools or tools that you are fluent with can make your life easier.
Lets talk for a moment about bad tools. E.g. If you using simplistic tools like notepad) (or any of that kind) to write your python scripts then, it's like you were eating soup with a fork. From the other hand, if you are using Visual Studio for writing a bash scripts then, it's like you were eating soup with a spoon that is the size of a table.
I worked with following tools: Eclipse, Visual Studio, Aptana, Android Studio, Sublime Text, Python IDLE and Atom. Some of them are very good to work with single language (Eclipse, Pytohn IDLE), other are good to work with many languages (Sublime Text, Atom). So far I like Atom the most, it was created by a community of programmers for programmers. What I like in Atom the most are awesome plug-ins that facilitates writing a code E.g Linter informs me about syntax errors related to a specific programming language and convention. Atom-Beautify auto format my code.
Go with the flow and pick the tools that are common or trending within the community or a language that you are working with. There must be a good reason that new tools are constantly invented.
One and only measure of clean code is the number of "What The Fuck" phrase counted during a code review. This section contains wisdom of people respected within the community of programmers. I highly recommend to read Clean Code book.
Clean code is like a good book - you read it with one breath, and you don't want to stop reading it. Clean code is neat and elegant, it's divided by logical sections. Clean code is self explanatory, by just looking at it you know what programmer is expressing or want to achieve. Clean code is not necessary a computational efficient code - but it's easier to make clean code efficient rather than efficient code clean. Clean code contains solution that strikes with simplicity. Usually, clean code expresses only one thought per line. Clean code is not overloaded with comments. Clean code is neither too cluttered or too loose. Clean code uses well known principles and paradigms. Clean code is maintainable. Writing clean code requires discipline.
When you see a bad code (code that smells) three words automatically pops out of your mouth "What The Fuck!" - I'm not joking here. A bad code is like Tiger shop, full of crap that nobody wants. Bad code is duplicated and over commented. Comments in bad code are poorly written, doesn't match the code therefore, have no value. Can you imagine a book without paragraphs? this is an example where the code is too cluttered, where there is no logical distinctions between block of codes. Now can you imagine a book that every sentence (or two) a new paragraph is placed? this is an example of too loose code. Bad code doesn't follow convention - one space here, two spaces there, no spaces there, it's just a mess. A bad code does too many things in one line. A bad code has magic numbers - values that only the author understand. Bad code is incomprehensible and nobody can maintain a bad code thus, the code has to be written from scratch. Bad code is written in rush by people with "don't care attitude". A bad code is both a mystery and misery. Bad code originates from the intention of code being read only by the author of the code.
Recognize code smells and don't write a bad code!
In this section I will talk about software principles (philosophies) that you need to know in order to keep your code clean.
I will show you differences between a bad code and a clean code. I will take an examples of a bad code and I will refactor (rewrite) it to the clean one.
If you would like to know more about making your code better I recommend Refactoring book.
Look at the below code and please tell me what this code does.
for i in data:if == "premium":dis = 20elif >= 3:dis = 15else:dis = 0
If above code makes sense to you then please explain to me what dis, i and 3 is?
Does dist stand for a distance, display or discount? Is i an index or an item ? Why number 3 is so important ?
Have a look at the below code and tell me what it does.
ITEMS_DISCOUNT_COUNT = 3for customer in customers:discount = 0.0if == "premium":discount = 0.20items_in_basket =if items_in_basket >= ITEMS_DISCOUNT_COUNT:discount = 0.15
Can you see the difference? Clean code is self explanatory, unambiguous and comprehensive.
From the other hand, code that smells is non-informative, being far from comprehensive and its understanding is based on assumptions.
Don't Repeat Yourself it says that duplicated code is not allowed. Do everything to avoid code repetition!
Write Everything Twice (more than twice).
It says that first time you write a code, you are writing it for the solution, second for comprehension, third for efficiency and last for your sake.
"First do it, then do it right, then do it better." - Addy Osmani
Keep It Small and Simple minimalism and simplicity is everything in programing. Simplicity over complicity, shorter over longer.
Avoid writing long methods (longer than 4 lines of code), and make solution as simple as possible. When you reach this, then you make it even shorter and simpler.
Develop habit of KISS-ing, and keeping your code DRY and WET.
Choose names, as you would choose a name for your children - Uncle Bob.
It's all about names. Names in the code are everywhere, from variable names through the function names and classes to the packages names etc... names, names and even more names.
Therfore, you have to pick names wisely. Names have to be short, informative, unambiguous and descriptive. Everything that deviates from this rule is just bad!
Bad variables names are non-informative, either too short or too long, don't follow conventions and have names that makes code hard to understand.
Below you will find examples that illustrate bad vs good cases.
Having no convention equals to being inconsistent.
Bad
thesum = 0reversecomplementstrand = "gravitational_force = 9.81
Above example is perfect case of a bad variables names.
Below example shows better and the best candidates for the same variable names.
Good
# better, the bestsummation = 0total_sum = 0# better, the bestrev_compl_strand = "reverse_complement_strand = "# better, the bestGRAVITATION = 9.81GRAVITATIONAL_FORCE = 9.81
Conclusions
Remember to keep your names descriptive and informative. Follow the convention and stick to it!
Lack of information is bad.
Bad
# elapsed time in daysd = 12delay = 10000name_string = "Jerry"
In the example above if we didn't have comment above variable d it wouldn't be possible to say what this variable is responsible for. Additionally, value 1000 of delay variable is specified in minutes, hours or light years ? Furthermore, programmer choose to suffix the variable name with data type string. What will happen if you use casting operation then, string will no longer become string.
Good
delay_ms = 10000elapsed_time_in_days = 12name = "Jerry"
Conclusions
Good variable name carries information about its usage purpose or origin.
Bad variable names are nothing more than a variables with a magic values. What is worse than bad variable names with magic values are magic values itself.
Bad
state = 0if state == 1:# do somethingstate = 0else:# do somethingstate = 1
In the example above you have no certainty that state is a flag or an actual state. Moreover, you have no idea if state changes value to 3,4 or n further in the code.
Good
state = Falseif state is True:# do somethingstate = Falseelse:# do somethingstate = True
Conclusions
Use booleans over integers - booleans increase readability and reduce uncertainty.
Context shapes variable name.
Bad
in_file =for line in in_file:if "$" in line:print("US & A")
In the example above you might think that in_file is a good name for a variable that stores content of a file.
Look what happens when the context changes. Usage of in_file in the for loop makes the entire 2nd line sounds like a broken English.
Good
data_file =for line in data_file:if "$" in line:print("US & A")
Conclusions
Think of context where the variable is used and based on it create/change variable name.
Good variable name is short and informative.
Bad
max = 32min = -10
In the example above there is no doubt that max and min are good name for a variable that store maximum and minimum values.
However, in python max and min are function names that by default comes with the language.
Therefore, creating min and max variables programmer overrides native functionality of the language.
Good
maximum = 32minimum = -10
Conclusions
Be aware of reserved words and functions that comes with a programming language.
Have a look at the example below and tell me what's wrong with it ?
Bad
for i in :print()
There is nothing wrong with the above example except that it's understandable only by people who know how the range function works.
However, for the people who know nothing about pytohn and range function it's difficult to figure out what 1st, 2nd and 3rd parameter is responsible for.
Good
start, stop, step = 0, , 2for index in :print()
Conclusions
Use names that have meaningful distinction, such as source, target, start, stop, step etc.
"Master programmers think of a system as stories to be told rather than programs to be written"* - Uncle Bob
If variables are containers for data then, functions are actions performed on data. Variables are nouns and functions as verbs.
Good function do one and one thing only - tells one story only. Below you will find perfect cases of bad function names().
Bad
# implementationprint(a, b, c)
The above example shows major flows related to function names.
Good
# previously do_stuff()# implementationprint(first_name, middle_name, surname)
Conclusions
Good function/method name express its' responsibility and functionality. Good function clearly indicates what it does or what it returns.
If you cannot express intention of a function in a one word then use more words - following verb first convention. e.g. set_name(), refresh_access_token().
Good function do one and one thing only and do it well. Never forget to KISS your function.
Bad code and comments goes together like peas and carrots. When one cannot express himself/herself in code then he/she uses comments.
Bad
# ex.1 mean functionmean = (num1 + num2) / 2# ex.2 print users addresses with the for loopfor user in users:print(user.address)# ex.3 check if user is club member and is eligible for senior discountif and >= 60:discount = 0.50# ex.4 TODO implement hello world function# ex.5 calculate abs difference between max and min# min_number = min(numbers)# max_number = max(numbers)# min_max_diff = abs(max_number - min_number)
If you cannot see anything wrong with "# ex.1 mean function" then I have to stop you here. The comment says function however, I cannot see function call or neither function definition.
This comment is an example where implementation != intention making the comment noting more than a lie. Thus, comments are dangerous and can mislead the reader.
"# ex.2 print users addresses with for loop" this text shows case of comments abusing. Comment has no meaningful value and it doesn't explain more than code itself.
Thus, in this case the comment is nothing more than a noise.
"# ex.3 check if user is club member and is eligible for senior discount" this comment provides enough information however, this information is not incorporated to the code.
"# ex.4 TODO implement hello world function" is another example of code noise.
It looks like the hello_world() function was implemented and programmer forgot to remove the comment, by that author is creating a noise.
"# ex.5 calculate abs difference between max and min" this comment has entire section where three lines of code are commented.
If they are commented then it's not compiled. If it's not compiled then nobody uses it, and if nobody uses it why it's still there ? it makes no sense to have a code that is commented. Remove it as soon as your program reach mature state.
In this case I will leave comments in good code as reference. However in reality I would remove them.
Good
# ex.1mean = (num1 + num2) / 2# ex.2for user in users:print(user.address)# ex.3if :discount = 0.50# ORuser_eligible_for_senior_member_discount = ( and >= 60)if user_eligible_for_senior_member_discount:discount = 0.50# ex.4
Conclusions
Bad programmer explains him/herself with comments, good programmer explains him/herself with code.
If you can replace comments with explanatory variable of a function then, do it!
Remember to remove commented code when is no longer used.
Did you know that nearly, all code read by a computer (interpreter or compiler) is read from left to right from top to bottom ?
I like to think about code as if it was written as a text in a book.
Every line of a code represent a single sentence (a thought, a clue or an expression) and a group of a lines creates a complete paragraph. Each paragraph is separated by a line break
Code formating is the way of distribution code within a file. We have two types of formating Vertical and Horizontal.
Can you imagine a book that is written without paragraphs. I'm sure that as a reader you'd have hard time distinguishing where one action starts and other stops.
In one word it would be nightmare to read it and reference to it.
In the example below you will see a code being TOO CLUTTERED which describes the notion of having no paragraphs in the code - thus, no distinction between thoughts.
Bad - Vertical
filename=columnsum = None #Initiate variable for sum of the columnsflag = 0with as fh:for line in fh:if flag == 0:if line:flag = 1columnsum = 0columnsum+=print("The sum of columns in", filename, "is", columnsum)
Above code is an example of a vertical code being too cluttered. It's difficult to say where the main thought is and what is the main thought of this code.
In one word code is repulsive. Compare it with refactored version below.
Good - Vertical
total_sum = 0filename =with as data_file:for number in data_file:total_sum +=print("The sum of numbers:", total_sum)
In the example above you can easily see where program has space for variables initialization, and for the program input.
The main thought (paragraph / code block) of the program just pops to your eyes.
If we come back to the analogy of code being a text within a book and count number of line breaks then, we would count 4 paragraphs within this code.
Below example shows a code being too cluttered in the horizontal way.
Bad - Horizontal
if <= 0:if condition_1 is True and condition_2 is True: # Check if conditions are true
The example above breaks "one thought per line" principle what, makes it difficult to read since one line contains two thoughts making it hard to distinguish where one thoughts starts and other ends.
Good - Horizontal
if <= 0:# Check if conditions are trueif condition_1 is True and condition_2 is True:# do something
Lets get back to the analogy of code being a text written within a book. Can you imagine a book that each new sentence starts with a paragraph and each paragraph is separated by a line break (or two). If yes then you can see that a book would count 4000 pages instead of 200. Once again it would be nightmare to read it.
Example below illustrates a code being TOO LOOSE, which describes the notion of having too many paragraphs in the code. Again code gives repulsive impression.
Bad
x =if x > 0:for i in :prod = prod * iprint ("The product of number", x, "is", prod)elif x == 0:print ("The product of 0 is 1")else:print ("Error")
Good
try:number =assert number >= 0prod = 1if number > 1:for i in :prod = prod * iprint('The product of ', number, 'is', prod)except ValueError:print('Invalid value provided')except AssertionError:print('Number cannot be negative')
Conclusions
Code formating has tremendous impact on the code readability. Bad formating impedes code comprehension, good formating facilitates reading the code. Keep the trade of don't be too loose or too tight be just right.
Anti-pattern is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive.
In this section I will show you anti-patterns. Contrary to previous examples this section only show the bad code and shortly tells why is wrong with it.
Additionally, I mention several anti-patterns that have no code representation but it would be harmful not to know them.
if condition:for i in :the_sum = i + the_sumprint ('The sum is', the_sum)else:for i in :the_sum = i + the_sumprint ('The sum is', the_sum)
Too Loose Code
if x > 0 :for i in :prod = prod * iprint ("The product of number", x, "is", prod)elif x == 0 :print ("The product of 0 is 1")elif x < 0 :print ("Error")
total = 1.08 * price
ROWCOUNT = 20for i in :
try:weather =except WheaterExceptionError:weather = 'undefined'
# link: https://www.python.org/dev/peps/pep-0008/reversecomplementstrandprint ('test')if condition:# do somethingelif condintion2# do something 2
Conclusions
Familiarize yourself with Anti-patterns and avoid them by all costs!