30 Days Of Python 👨‍💻 - Day 6 - Loops II And Functions

The joy of coding Python should be in seeing short, concise, readable classes that express a lot of action in a small amount of clear code – not in reams of trivial code that bores the reader to death.
Guido van Rossum
Starting off from where I left, I continued exploring more loops while playing around with some code. Then I moved on to learning one of the most important things of programming, functions. I came across functions and methods in Python, docstrings, best practices along with scopes in detail. I will try my best to explain in lucid and simple terms.

Loops Continued

While Loops
While loops are another way to run a block of code several times based on a specific condition. We need to be a bit careful when dealing with while loops to accidentally not create an infinite loop that would keep executing till they crash our systems!
  1. hungry = True while(hungry): # This is always true so it keeps printing until system crashes! print('Give me something to eat!!')     
But while loops are cool. They are simple to write and easy to read. We just need to tell the interpreter when to stop the loop. It can be done either by using a break statement which stops the loop execution and breaks out of the loop or by making the condition false to stop the execution.
  1. hungry = True 
  2. while(hungry): 
  3.    print('Give me something to eat!!'
  4.    break # prints only once and stops the loop execution     
  7. hungry = True satisfaction = 0 
  8. while(satisfaction < 10):
  9.  satisfaction += 1
  10.  print('Give me something to eat!!'# prints 10 times    
Another feature of while loop is that it can be combined with an else block.
  1. hungry = True satisfaction = 0 while satisfaction < 10: satisfaction += 1 print('Give me something to eat!!'elseprint('I am super satisfied now'# gets printed once condition is falsy     
It needs to be noted that if the break statement is used in the while block, then the else block is not executed.
While vs For Loop
For loops are usually useful when knowing the range of the iterable that needs to be looped. Whereas while loops can come in handy when we want to perform some task multiple times not knowing the range beforehand.
  1. while True:
  2.  response_from_user = input('Enter some message. Enter bye to exit')
  3.  if(response_from_user == 'bye'):
  4.     break     
Apart from the break statement, there are two other statements, continue which instead of breaking out of the loop continues to continue the iteration. pass is not often used but it is sometimes used as a placeholder to continue executing the statements after the loop.
Quick Coding Exercise
Let’s find the duplicate emails in a list of emails and print them.
  1. email_list = ['roger@hey.com','michael@hey.com','roger@hey.com','prince@gmail.com'
  2. duplicate_emails = [] 
  3. for email in email_list: 
  4.    if email_list.count(email) > 1 and email not in duplicate_emails: 
  5.       duplicate_emails.append(email) 
  6. print(duplicate_emails)     
That was my approach to solve the problem. Let me know how you would have solved it in the comments. Alright! Time to switch to an interesting topic, function.


Functions are a very important concept and they are present in all programming languages. Functions allow us to define an action (block of code) and then execute the action any number of times without repeating ourselves following the principle of DRY. Up until now, I have been using some of the in-built functions provided by Python such as print, input, len etc. It’s time to create one.
  1. def blow_fire(): # This part is called function definition  
  2.   print('fire 🔥 🔥 🔥')  
  3. blow_fire() # This part is called function invocation blow_fire() # It can be called any number to times to perform some action      

Arguments and Parameters

The above function was kind of cool but it has some limitations as well. It can perform only the same action. Let’s make it more extensible and make it perform actions at will by passing some data to it
  1. def blower(name, emoji): # parameters   
  2.   print(f'{name} {emoji} {emoji} {emoji}'
  3. blower('fire''🔥'# arguments blower('water', '🌊')   
While defining a function, when we provide some data to it to perform some action based on the data, the provided data is called a parameter. A function can be provided with any number of parameters.
When the same function is called or invoked to perform the action, it accepts the data as arguments. It is just terminology but it often confusing and used interchangeably.
The above is also called positional parameters or positional arguments because of the order or position of the parameters or arguments matter.
  1. def blower(name = 'fire', emoji = '🔥'): # default parameters   
  2.   print(f'{name} {emoji} {emoji} {emoji}')   
  3. blower('fire''🔥'# arguments   
  4. blower('water''🌊') blower() # fire 🔥 # this works as the function has default parameters defined     


return is a keyword in Python that is used to return a value from a function. To makes functions more useful, it needs to return some value based on evaluating an expression. If no return statement is specified or the expression of the return statement does not evaluate to a data type, then the function returns None. In JavaScript world, this None can be linked to void.
The return statement terminates the function and exits out of it.
  1. def multiplier(num1, num2):   
  2.   return num1 * num2   
  3. result = multiplier(2,3)   
  4. print(result) # 6     
Time to do something cool using the return statement.
  1. def sum(num1):   
  2.     def child(num2):   
  3.         return num1 + num2   
  4.     return child   
  6. add_10 = sum(10)   
  8. print(add_10(20)) # 30 (Closure!!!)   
  9. print(add_10(50)) # 60   
  10. print(add_10(100)) # 110     
Yay! I just validated that there is the concept of closure in Python as well, just like in JavaScript. It is so effective in creating factory functions. In the above block of code, I was able to create a generic function add_10 and pass dynamic arguments to it to generate a different result. How cool is that!
Will explore more about this next week when learning about the functional programming concepts in Python.
Methods are simply functions that are defined inside an object or in other terms, they are ‘owned’ by the objects. They are called using the object name followed by the . operator to execute or invoke them.
When writing custom functions, it would be very helpful if the objective of the function is mentioned so that other co-workers or users of the code can easily understand what the function does while using them. The IDE would show the info of the function. Also, there are some helper functions and methods to view the information about a function if present.
“Code tells you how; Comments tell you why.”
— Jeff Atwood (aka Coding Horror)
  1. def test_function():   
  2. '''
  3. This function just prints test to the console. 
  4. '''  
  5. print('test') test_function()    
“Code is more often read than written.”
— Guido van Rossum
*args and **kwargs
*args is the short form of arguments and **kwargs stands for keyword arguments. These are used when a function needs to accepts any number of arguments or keyword arguments.
  1. def powerful_function(*args):     
  2. print(args)
  4. powerful_function(1,3,2)   
  5. # (1, 3, 2) --> Returns a tuple def   
  7. super_function(**kwargs):     
  8.   print(kwargs)     
  10. super_function(name='John', age='45')   
  11. # {'name': 'John', 'age': '45'} --> Returns a dict       
In the JavaScript world, the ES6 rest parameters is used to extract all the arguments passed to the function. Another mental model created!


Scope in simple terms means “Which variables do I have access to ?”. This is the kind of question the interpreter asks when reading the code to find the scope of variables. In Python, variables have functionscope which means variables defined inside a function cannot be accessed outside of the function.
  1. num = 1   
  2. def confusing_function():  
  3.  num = 10  
  4.  return num  
  5.  print(num) # 1 => Global Scope  

  6. print(confusing_function()) # 10 => Local Scope    
These are the scope rules that the Python interpreter follows,
  • Start with local. Is the variable present? Then fetch the value. If not then proceed
  • Is the variable defined in the parent function local scope? Fetch value if present else proceed
  • Is the variable present in the global scope? Fetch value if present else proceed
  • Is the variable a built-in function? Fetch value else exit
That’s it for today. I have been able to cover most of the Python basics now. It’s time to dig deeper into the advanced topics but before that, I would like to explore and set up the developer environment and all the different kinds of tooling and programs available tomorrow to complete the roadmap for the first week.
I hope I tried to explain my learning process about the language in easy to understand words. Please let me know in the comments if something felt confusing or if you have any other suggestions, thoughts.
This post is part of a 30 part challenge series. In case you haven't checked out the previous posts, here they are,
Have a great one!