Pages

Thursday, February 23, 2023

How to Iterate Over a List and Get Indexes with 'enumerate' Function in Python

'enumerate' function

There are different ways of accessing the data from a list like using range and then index or accessing the element of a list directly from for loop and so on. 

One other powerful way is by using 'enumerate' function. One major advantage of using 'enumerate' is this function returns both index and corresponding element at once. So, we don't have to maintain a counter to calculate the index or need to retrieve the element from a index. This makes the code easy to maintain and understand. 

In this post, we will see how to use 'enumerate' function and looping over a list to access index and elements as a tuple and also by using tuple unpacking

Syntax

enumerate(iterable, start=0)

'enumerate' function accepts two parameters. 
  • 'iterable' - This is a mandatory parameter. An iterable (E.g.: list, tuple, string...) on which we need to run the loop and retrieve index and element.
  • 'start' - This is an optional parameter. 'start' specifies the number of the first index (This works more like a counter than index). Default value is '0'. 
Let's have a look at an example for looping over a list using enumerate. 

1

2

3

4

5

fruits = ['apple', 'banana', 'cherry']


for index, fruit in enumerate(fruits):

   print(index, fruit)



In the above example, we are only passing the list to the enumerate function, so start index would be considered as '0' and returns the index and element combination for every iteration. Below is the result. 

0 apple

1 banana

2 cherry


Let's have another example by passing an optional parameter 'start'. 

1

2

3

4

5

fruits = ['apple', 'banana', 'cherry']


for index, fruit in enumerate(fruits, 1):

   print(index, fruit)



In the above example, we are passing '1' as the start. One thing to here is, it is not like slicing where the loop is iterated from the index passed for 'start'. Instead, enumerate start indexing from '1'. It is better understood by looking at the result. 

1 apple

2 banana

3 cherry


This can be useful in the cases where we need to start numbering from '1' (or any other number instead of zero) and continue till the end of the list. 

In the above examples, we are directly unpacking the tuple from 'enumerate' function as index and fruit. 

We can also use it as a tuple instead. 

1

2

3

4

5

fruits = ['apple', 'banana', 'cherry']


for fruit_tuple in enumerate(fruits, 1):

   print(fruit_tuple)



Unlike previous examples, we are not using two different variables (for index and element) in for loop, instead we are only passing one variable. In this case, index and element combination is returned as a tuple. Below is the result.

(1, 'apple')

(2, 'banana')

(3, 'cherry')



As we have seen in the above examples, we can loop over an iterator with index and element combination as a tuple or directly assigning to two different variables as required in the loop and either to start the counter from default '0' or by specifying the required start position. 

I hope this post has provided a good insight on how to iterate over a list and get index and element from an iterator using 'enumerate' function.


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Saturday, February 18, 2023

*OMIT vs *NOPASS: Understanding the Key Differences - IBM i

*OMIT v/s *NOPASS

In RPGLE, *OMIT and *NOPASS are the two options used to specify the optional parameters for the procedures. It is essential to understand the difference between *OMIT and *NOPASS because knowing which keyword to use for the specific case helps in writing the clean code. 

Before we jump on to the key differences, let's have a look at the use of each of the keywords.

*OMIT

By using the *OMIT on the parameter while declaring a procedure, we can make this parameter an optional parameter. 

We could either pass the data to this parameter or simply pass '*OMIT' to while calling the procedure. 

Dcl-PR SampleProcedure;                              

  MandatoryParameter1 Char(1);                       

  OptionalParameterWithOmit Char(1) Options(*Omit);  

  MandatoryParameter2 Packed(1);                     

End-PR;                                              

                                                     

Dcl-Proc SampleProcedure Export;                     

  Dcl-PI SampleProcedure;                            

    MandatoryParameter1 Char(1);                     

    OptionalParameterWithOmit Char(1) Options(*Omit);

    MandatoryParameter2 Packed(1);                   

  End-PI;                                            

                              

  // Code to be run in the procedure         

                                        

End-Proc;                               


This procedure can be called in one of the two ways,
  • Either by passing the data for the optional parameter. 
  • Or by passing '*OMIT' to avoid passing this parameter. 

// Passing the data

SampleProcedure('A' : 'B' : 1);                      


// Passing *Omit

SampleProcedure('A' : *Omit : 1);


*NOPASS

By using the *NOPASS on the parameter while declaring a procedure, we can make this parameter an optional parameter. 

We could either pass the data to this parameter or not pass this parameter at all while calling the procedure. 

Dcl-PR SampleProcedure;                                  

  MandatoryParameter1 Char(1);                           

  MandatoryParameter2 Packed(1);                         

  OptionalParameterWithNoPass Char(1) Options(*NoPass);  

End-PR;                                                  

                                                         

Dcl-Proc SampleProcedure Export;                         

  Dcl-PI SampleProcedure;                                

    MandatoryParameter1 Char(1);                         

    MandatoryParameter2 Packed(1);                       

    OptionalParameterWithNoPass Char(1) Options(*NoPass);

  End-PI;                                                

                                                         

  // Code to be run in the procedure;                  

                                                         

End-Proc;                                                


This procedure can be called in one of the two ways,
  • Either by passing the data for the optional parameter. 
  • Or by not passing the parameter at all.

// Passing the data

SampleProcedure('A' : 1 : 'B');                      


// Not passing the optional parameter

SampleProcedure('A' : 1);


The Difference

There are couple of main differences between using *OMIT and *NOPASS. 
  • *OMIT can be used on any parameter, whereas *NOPASS can only be used on the last parameter(s) i.e., no mandatory parameter can be declared after *NOPASS is specified. 
  • *OMIT needs to passed to avoid passing the parameter declared with *OMIT, whereas no parameter needs to be passed when specified using *NOPASS (considering it is the last parameter). 

I hope this post has help in understanding what is the use of *OMIT, *NOPASS and the difference. 


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

Tuesday, February 7, 2023

Python File I/O: Reading, Writing, and Creating Files

Reading, Writing, and Creating Files in Python

Python provides different built-in functions and methods for working with files. These features, widely known as file I/O (input/output), allows reading and writing data to and from the files located on local computer or network. 

Reading and writing data from and to the files is essential for any  application, as it allows storing  and retrieving data that can be used by the programs/application.

Some of the basic functions are opening and closing files, reading and writing data, and creating the new files. Let's start with opening and closing files before we move on to reading and writing. 

Opening a file

Before we get to reading and writing data from and to the file, we would first have to open a file. 

We can use function 'open()' to open a file. We would need to pass two arguments to this function.
  • Name of the file to be opened.
  • Mode in which we need to open the file. 

Syntax 

file_object = open("sample_file.txt", "r")

This would create a file object which we would be opening through out the program  (until it is closed) to read or write the data. 

There are different modes for opening files which we can use as required in the program. 
  • "r" (read) - Used to open the file for reading. An error would be thrown if the file does not already present. 
  • "w" (write) - Used to open the file for writing. Opening the file with "w" would create a file if not already exist and overwrite the file if already exist. One thing to remember is, this mode should not be used when we want to append the data to the existing file. 
  • "a" (append) - Used to open the file for writing. Opening the file with "a" would create a file if not already exist and data can be appended to the current file if already exist. 
  • "x" (exclusive) - Used to create a new file for writing. An error would be thrown if the file already exist. 
These are the basic modes that allow either one of the two (reading and writing) functions. We could add "+" and "b" to the above modes as required. 
  • Adding "+" would enhance the functionality of the mode. E.g.: mode "r+" would open the file for both read and write where as using the mode "r" would open the file exclusively for reading. 
  • Adding "b" would open the file for reading/writing in binary mode (mostly used for image or audio files). 

Closing a file

We would need to close a file once we are done working with a file to free up the system resources and to make sure the code is clean.

We can use the method 'close()' to close the file. This method needs to be used on the file object opened using the 'open()' function.

Syntax

file_object.close()

Below is an example of opening and closing a file. 

file_object = open("sample_file.txt", "r+")
# read/write data from/to file & any other process required
file_object.close()

There is another way to close a file without explicitly using 'close()'.

This is by using 'open()' function in combination with 'with'. Opening the file in this manner, file object would only be accessible to the block of code under 'with' statement. Once the block is executed, file would be automatically closed and file object cannot be accessed outside the block. 

with open("sample_file.txt", "r+") as f:
    # read/write data from/to file & any other process required

Reading a file

As mentioned in the 'Opening a file' section, file needs to be opened in 'read (r)' mode and create a file object before reading the file. 

Contents of the file can then be read from file object. There are couple of different ways of reading the data from a file. 
  • Reading the full content of a file at once. 
  • Reading one line at a time from a file. 

Reading the full content of a file at once

Using the 'read()' method on the file object, we can read the full content of a file in single statement.

This method returns a string with the content of a file. 

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')

 

# Read the contents of a file at once

contents = file_object.read()

print(contents)

 

# Close the file

file_object.close()

 


In the above example, 'read()' method on 'file_object' returns the full content as a string and is stored in 'content' variable. Below is the output. 

First Line

Second Line

Third Line


Another way to read the full content at once is by using 'readlines()' method on file object. 
Main difference between 'read()' and 'readlines()' is, 
  • read() returns the full content as a string. 
  • readlines() returns the full content as a list with each line as an element in the list. 
Below is the example by using readlines() instead of read().

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')

 

# Reading the contents of a file at once

contents = file_object.readlines()

print(contents)

 

# Close the file

file_object.close()

 


readlines() returns the list with every line as an element. Below is the result.

['First Line\n', 'Second Line\n', 'Third Line']


Reading one line at a time from a file

Using the 'readline()' method on the file object, we can read one line at a time from the file. 

1

2

3

4

5

6

7

8

9

10

# Open a file for reading

file_object = open('sample_file.txt', 'r')


# Reading one line from a file

line = file_object.readline()

print(line)# First Line


# Close the file

file_object.close()



Running 'readline()' method next time would return the next line from the file. 

Another way of reading one line is by looping through the file object. 

1

2

3

4

5

6

7

8

9

10

11

# Open a file for reading

file_object = open('sample_file.txt', 'r')


# Reading one line at a time

# in a loop using file object

for line in file_object:

   print(line)


# Close the file

file_object.close()



One thing to note here is that, file should be present on the system to be able to open the file for reading. If the file not already present, an error 'FileNotFoundError' (No such file or directory) would be thrown. 

So, error handling should be done to capture this error.

Writing (and creating) to a file

File needs to be opened in either 'w', 'a' or 'x' modes to be able to write the content into a file. 

'write()' method on file object can be used to write the content into a file. The way write method works depends on the mode used. 

Using the mode 'w' would open the file for writing, creates the file if not already present and overwrites the content of the file if already present. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'w')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt' is created if not already present and write() method adds a string "File is created...". 

Content of the file would remain same irrespective of the number of times this program is run. As, every time file is opened in 'w' mode file would be cleared followed by adding a line to the file. 

Using the mode 'a' would open the file for writing, creates the file if not already present and appends the data if file already present. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'a')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt" is created if not already present and write() method adds a string "File is created...".

Unlike for the 'w' mode, string "File is created..." is added to the file every time the program is run. If this is program is run for 100 times, this string would be added to the file 100 times. 

Using mode 'x' would create and open the file for writing. If the file already present, program would throw 'FileExistsError' when trying to open with this mode. 

1

2

3

4

5

6

7

8

9

# Open a file for writing

file_object = open('sample_file.txt', 'x')


# Write a line to the file

file_object.write("File is created...")


# Close the file

file_object.close()


In the above example, a new file 'sample_file.txt" is created if not already present and 'FileExistsError' would be thrown if file already exist. 

Unlike for the modes 'w' and 'a', if this program runs for the second time (without removing the file created), program would throw 'FileExistsError'. 

By using the 'write()' we can only write one string at a time. By using 'writelines()' method we can write multiple strings (list of strings) at a time. 

1

2

3

4

5

6

7

8

9

10

11

12

# Open a file for writing

file_object = open('sample_file.txt', 'w')


strings_list = ["First Line\n", "Second Line\n", "Third Line\n"]


# Write a list of strings

file_object.writelines(strings_list)


# Close the file

file_object.close()



In the above example, 'writelines()' writes all the lines in the list passed to the file. This is same as looping over a list and writing one element at a time using 'write()' method. 

Conclusion

Reading and writing from/to a file is an important part of any applications and the use of python's built-in functions makes it easy to create, open a file, read from a file and write to a file. 

I hope this post has provided a good insight on opening a file, reading from a file and writing (and creating) to a file.


If you have any Suggestions or Feedback, Please leave a comment below or use Contact Form.

How to Iterate Over a List and Get Indexes with 'enumerate' Function in Python

'enumerate' function There are different ways of accessing the data from a list like using range and then index or accessing the ele...