Skip to content

3. The Basics

  

3.1. An example of a Python program

Below is a program demonstrating Python’s basic features.


The program (bases_01)

#    -*- coding=utf-8 -*-

# ----------------------------------
def affiche(chaine):
    #    chain poster
    print "chaine=%s" % (chaine)


# ----------------------------------
def afficheType(variable):
    #    displays variable type
    print "type[%s]=%s" % (variable,type(variable))

# ----------------------------------
def f1(param):
    #    add 10 to param
    return param+10

# ----------------------------------
def f2():
    #  returns 3 values
    return ("un",0,100);


#    -------------------------------- main program ------------------------------------
#  this is a comment
#    variable used without being declared
nom="dupont"

#    a screen display
print "nom=%s" % (nom)

#  a list with elements of different types
liste=["un","deux",3,4]

#  its number of elements
n=len(liste)

#    a loop
for i in range(n):
  print "liste[%d]=%s" % (i,liste[i])

#  initialize 2 variables with a tuple
(chaine1,chaine2)=("chaine1","chaine2")

#  concatenation of the 2 strings
chaine3=chaine1+chaine2

#    result display
print "[%s,%s,%s]" % (chaine1,chaine2,chaine3)

#  use function
affiche(chaine1)

#  the type of a variable can be known
afficheType(n)
afficheType(chaine1)
afficheType(liste)

#  the type of a variable can change at runtime
n="a change"
afficheType(n)

#    a function can return a result
res1=f1(4)
print "res1=%s" % (res1)

#  a function can return a list of values
(res1,res2,res3)=f2()
print "(res1,res2,res3)=[%s,%s,%s]" % (res1,res2,res3)

#  we could have retrieved these values in a
liste=f2()
for i in range(len(liste)):
    print "liste[%s]=%s" % (i, liste[i])

#    testing
for i in range(len(liste)):
    #    displays only channels
    if (type(liste[i])=="str"):
        print "liste[%s]=%s" % (i,liste[i])

#    other tests
for i in range(len(liste)):
    #    displays only integers >10
    if (type(liste[i])=="int" and liste[i]>10):
        print "liste[%s]=%s" % (i,liste[i])

#    a while loop
liste=(8,5,0,-2,3,4)
i=0
somme=0
while(i<len(liste) and liste[i]>0):
    print "liste[%s]=%s" % (i,liste[i])
    somme+=liste[i] #   sum=sum+t[i]
    i+=1 #   i=i+1
print "somme=%s" % (somme)
#    end of program

Note:

  • line 1: a special comment used to declare the script's encoding type, here UTF-8. This depends on the text editor used. Here with Notepad++:
 
  • line 4: the keyword def defines a function;
  • lines 5-6: the function’s body. It is indented one tab to the right. This indentation, combined with the colon (:) in the def statement, defines the function’s body. This applies to all statements with a body: if, else, while, for, try, except;
  • line 12: Python manages variable types internally. You can determine a variable’s type using the type(variable) function, which returns a variable of type 'type'. The expression '%s' % (type(variable)) is a string representing the variable’s type;
  • line 25: the main program. This comes after the definition of all the script’s functions. Its content is not indented;
  • Line 28: In Python, you don't declare variables. Python is case-sensitive. The variable Nom is different from the variable nom*. A string can be enclosed in double quotes " or single quotes '. So you can write 'dupont' or "dupont*";
  • line 31: the expression "xxxx%syyyy%szzzz" % (100, 200) is the string "xxxx100yyy200szzzz" where each %s has been replaced by an element of the tuple. %s is the string formatting specifier. There are other formats;
  • line 34: there is a difference between a tuple (1,2,3) (note the parentheses) and a list [1,2,3] (note the square brackets). The tuple is immutable, whereas the list is mutable. In both cases, element number i is denoted by [i];
  • line 40: range(n) is the tuple (0,1,2,...,n-1);
  • line 74: len(var) is the number of elements in the collection var (tuple, list, dictionary, ...);
  • line 86: the other Boolean operators are or and not.

The screen output is as follows:

nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<type 'int'>
type[chaine1]=<type 'str'>
type[['un', 'deux', 3, 4]]=<type 'list'>
type[a change]=<type 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13

3.2. Type conversions

Here we focus on type conversions involving data of type str (string), int (integer), float (floating-point), and bool (boolean).


The program (bases_01b)

#   -*- coding=utf-8 -*-

#   type changes
#   int --> str, float, bool
x=4
print x, type(x)
x=str(4)
print x, type(x)
x=float(4)
print x, type(x)
x=bool(4)
print x, type(x)

#   bool --> int, float, str
x=True
print x, type(x)
x=int(True)
print x, type(x)
x=float(True)
print x, type(x)
x=str(True)
print x, type(x)

#   str --> int, float, bool
x="4"
print x, type(x)
x=int("4")
print x, type(x)
x=float("4")
print x, type(x)
x=bool("4")
print x, type(x)

#   float --> str, int, bool
x=4.32
print x, type(x)
x=str(4.32)
print x, type(x)
x=int(4.32)
print x, type(x)
x=bool(4.32)
print x, type(x)

#  type change error handling
try:
    x=int("abc")
    print x, type(x)
except ValueError, erreur:
    print erreur

#   various Boolean cases
x=bool("abc")
print x, type(x)
x=bool("")
print x, type(x)
x=bool(0)
print x, type(x)
x=None
print x, type(x)
x=bool(None)
print x, type(x)

Many type conversions are possible. Some may fail, such as those in lines 45–49, which attempt to convert the string 'abc' to an integer. We handled the error using a try/except block. A general form of this block is as follows:


try:
    actions
except Exception, Message:
    actions
finally:
    actions

If any of the actions within the try block throw an exception (signal an error), control immediately transfers to the **except clause. If the actions within the try block do not throw an exception, the except clause is ignored. The Exception and Message attributes of the except statement are optional. When present, Exception specifies the type of exception caught by the except statement, and Message contains the error message associated with the exception. There can be multiple except statements if you want to handle different types of exceptions within the same try block.

The finally statement is optional. If present, the actions in the finally block are always executed, regardless of whether an exception occurred or not.

We’ll come back to exceptions a little later.

Lines 52–61 show various attempts to convert data of type str, int, float, and NoneType to boolean. This is always possible. The rules are as follows:

  • bool(int i) is False if i is 0, True in all other cases;
  • bool(float f) is False if f is 0.0, True in all other cases;
  • bool(str string) is False if string has 0 characters, True in all other cases;
  • bool(None) is False. None is a special value that means the variable exists but has no value.

The screen output is as follows:

4 <type 'int'>
4 <type 'str'>
4.0 <type 'float'>
True <type 'bool'>
True <type 'bool'>
1 <type 'int'>
1.0 <type 'float'>
True <type 'str'>
4 <type 'str'>
4 <type 'int'>
4.0 <type 'float'>
True <type 'bool'>
4.32 <type 'float'>
4.32 <type 'str'>
4 <type 'int'>
True <type 'bool'>
invalid literal for int() with base 10: 'abc'
True <type 'bool'>
False <type 'bool'>
False <type 'bool'>
None <type 'NoneType'>
False <type 'bool'>
False <type 'bool'>

3.3. The scope of variables


Program (bases_02)

#    -*- coding=utf-8 -*-

#    variable scope
def f1():
    #  we use the global variable i
    global i
    i+=1
    j=10
    print "f1[i,j]=[%s,%s]" % (i,j)

def f2():
    #  we use the global variable i
    global i
    i+=1
    j=20
    print "f2[i,j]=[%s,%s]" % (i,j)

def f3():
    #  we use a local variable i
    i=1
    j=30
    print "f3[i,j]=[%s,%s]" % (i,j)

#    tests
i=0
j=0 #  these two variables are known only to a function f
    #  only if it explicitly declares with the global instruction
    #  she wants to use them
f1()
f2()
f3()
print "test[i,j]=[%s,%s]" % (i,j)

Results

1
2
3
4
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[1,30]
test[i,j]=[2,0]

Notes:

  • The script demonstrates the use of the variable i, declared as global in the functions f1 and f2. In this case, the main program and the functions f1 and f2 share the same variable i.

3.4. Lists, tuples, and dictionaries

3.4.1. One-dimensional lists


Program (bases_03)

#   -*- coding=utf-8 -*-

#   1-dimensional lists
#   initialization
list1=[0,1,2,3,4,5]

#   routes - 1
print "list1 a %s elements" % (len(list1))
for i in range(len(list1)):
    print "list1[%s]=%s" % (i, list1[i])

list1[1]=10;
#   routes - 2
print "list1 a %s elements" % (len(list1))
for element in list1:
    print element

#   addition of two elements
list1[len(list1):]=[10,11]
print ("%s") % (list1)

#   deletion of last two items
list1[len(list1)-2:]=[]
print ("%s") % (list1)

#  addition at the beginning of a tuple list
list1[:0]=[-10, -11, -12]
print ("%s") % (list1)

#   mid-list insertion of two elements
list1[3:3]=[100,101]
print ("%s") % (list1)

#  deletion of two items in the middle of a list
list1[3:4]=[]
print ("%s") % (list1)

Notes:

  • the notation array[i:j] refers to elements i through j-1 of the array;
  • the notation [i:] refers to elements i and subsequent elements of the array;
  • the notation [:i] refers to elements 0 through i-1 of the list;
  • Line 20: print (%s) % (list1) displays the string: "[ list1[0], list1[2], ..., list1[n-1]]".

Results

list1 a 6 elements
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 elements
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]

The previous code can be written differently (bases_03b) using certain list methods:

#   -*- coding=utf-8 -*-

#   1-dimensional lists

#   initialization
list1=[0,1,2,3,4,5]

#   routes - 1
print "list1 a %s elements" % (len(list1))
for i in range(len(list1)):
    print "list1[%s]=%s" % (i, list1[i])

list1[1]=10
#   routes - 2
print "list1 a %s elements" % (len(list1))
for element in list1:
    print element

#   addition of two elements
list1.extend([10,11])
print ("%s") % (list1)

#   deletion of last two items
del list1[len(list1)-2:]
print ("%s") % (list1)

#  addition at the beginning of a tuple list
for i in (-12, -11, -10):
    list1.insert(0,i)
print ("%s") % (list1)

#   mid-list insertion
for i in (101,100):
    list1.insert(3,i)
print ("%s") % (list1)

#   mid-list deletion
del list1[3:4]
print ("%s") % (list1)

The results are the same as with the previous version.

3.4.2. The dictionary


The program (bases_04)

#    -*- coding=utf-8 -*-

def existe(conjoints,mari):
    #  checks whether the husband key exists in the joint dictionary
    if(conjoints.has_key(mari)):
        print "La cle [%s] existe associee a la valeur [%s]" % (mari, conjoints[mari])
    else:
        print "La cle [%s] n'existe pas" % (mari)


#    ----------------------------- Main
#    dictionaries
conjoints={"Pierre":"Gisele", "Paul":"Virginie", "Jacques":"Lucette","Jean":""}

#    routes - 1
print "Nombre d'elements du dictionnaire : %s " % (len(conjoints))
for (cle,valeur) in conjoints.items():
    print "conjoints[%s]=%s" % (cle,valeur)

#    list of dictionary keys
print "liste des cles-------------"
cles=conjoints.keys()
print ("%s") % (cles)

#  list of dictionary values
print "liste des valeurs------------"
valeurs=conjoints.values()
print ("%s") % (valeurs)

#    key search
existe(conjoints,"Jacques")
existe(conjoints,"Lucette")
existe(conjoints,"Jean")

#  deleting a key-value
del (conjoints["Jean"])
print "Nombre d'elements du dictionnaire : %s " % (len(conjoints))
print ("%s") % (conjoints)

Notes:

  • line 17: couples.items() returns the list of (key, value) pairs in the couples dictionary;
  • line 22: conjoints.keys() returns the keys of the conjoints dictionary;
  • line 27: conjoints.values() returns the values of the conjoints dictionary;
  • line 7: spouses.has_key(husband) returns True if the key husband exists in the spouses dictionary, False otherwise;
  • line 38: a dictionary can be displayed on a single line.

Results

Nombre d'elements du dictionnaire : 4
conjoints[Paul]=Virginie
conjoints[Jean]=
conjoints[Pierre]=Gisele
conjoints[Jacques]=Lucette
liste des cles-------------
['Paul', 'Jean', 'Pierre', 'Jacques']
liste des valeurs------------
['Virginie', '', 'Gisele', 'Lucette']
La cle [Jacques] existe associee a la valeur [Lucette]
La cle [Lucette] n'existe pas
La cle [Jean] existe associee a la valeur []
Nombre d'elements du dictionnaire : 3
{'Paul': 'Virginie', 'Pierre': 'Gisele', 'Jacques': 'Lucette'}

3.4.3. Tuples


Program (bases_05)

#   -*- coding=utf-8 -*-

#   tuples
#   initialization
tab1=(0,1,2,3,4,5)

#   routes - 1
print "tab1 a %s elements" % (len(tab1))
for i in range(len(tab1)):
    print "tab1[%s]=%s" % (i, tab1[i])

#   routes - 2
print "tab1 a %s elements" % (len(tab1))
for element in tab1:
    print element

#   element modification
tab1[0]=-1


The results

tab1 a 6 elements
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 6 elements
0
1
2
3
4
5
Traceback (most recent call last):
  File "exemple_05.py", line 18, in <module>
    tab1[0]=-1
TypeError: 'tuple' object does not support item assignment

Notes:

  • Lines 15–18 of the results: show that a tuple cannot be modified.

3.4.4. Multidimensional lists


Program (bases_06)

#   -*- coding=utf-8 -*-

#   multidimensional lists

#   initialization
multi=[[0,1,2], [10,11,12,13], [20,21,22,23,24]]

#   route
for i1 in range(len(multi)):
    for i2 in range(len(multi[i1])):
        print "multi[%s][%s]=%s" % (i1,i2,multi[i1][i2])

#   multidimensional dictionaries
#   initialization
multi={"zero":[0,1], "un":[10,11,12,13], "deux":[20,21,22,23,24]}

#   route
for (cle,valeur) in multi.items():
    for i2 in range(len(multi[cle])):
        print "multi[%s][%s]=%s" % (cle,i2,multi[cle][i2])

Results

multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi[zero][0]=0
multi[zero][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24


Program (bases_07)


# -*- coding=Utf-8 -*-
 
# chaîne vers liste
chaine='1:2:3:4'
tab=chaine.split(':')
print type(tab)
 
# affichage liste
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
 
# liste vers chaîne
chaine2=":".join(tab)
print "chaine2=%s" % (chaine2)
 
# ajoutons un champ vide
chaine+=":"
print "chaine=%s" % (chaine)
tab=chaine.split(":")
 
# affichage liste
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
 
# ajoutons de nouveau un champ vide
chaine+=":"
print "chaine=%s" % (chaine)
tab=chaine.split(":")
 
# affichage liste
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
 

Notes:

  • line 5: the method string.split(separator) splits the string string into elements separated by separator and returns them as a list. Thus, the expression '1:2:3:4'.split(":") returns the list ('1','2','3','4');
  • line 13: 'separator'.join(list) returns the string 'list[0]+separator+list[1]+separator+...'.

Results

<type 'list'>
tab a 4 elements
['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
tab a 5 elements
['1', '2', '3', '4', '']
chaine=1:2:3:4::
tab a 6 elements
['1', '2', '3', '4', '', '']

3.5. Regular expressions


Program (bases_09)

#    -*- coding=utf-8 -*-

import re

# --------------------------------------------------------------------------
def compare(modele,chaine):
    #  compares chain chain with model chain
    #    displaying results
    print "\nResultats(%s,%s)" % (chaine,modele)
    match=re.match(modele,chaine)
    if match:
        print match.groups()
    else:
        print "La chaine [%s] ne correspond pas au modele [%s]" % (chaine,modele)


#  regular expressions in python
#  retrieve the various fields of a string
#  the model: a sequence of numbers surrounded by any characters
#  you only want to retrieve the sequence of digits
modele=r"^.*?(\d+).*?$"

#  the chain is compared with the
compare(modele,"xyz1234abcd")
compare(modele,"12 34")
compare(modele,"abcd")

#  the model: a sequence of numbers surrounded by any characters
#  we want the sequence of digits and the fields that follow and precede them
modele=r"^(.*?)(\d+)(.*?)$"

#  the chain is compared with the
compare(modele,"xyz1234abcd")
compare(modele,"12 34")
compare(modele,"abcd")

#  the template - a date in dd/mm/yy format
modele=r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modele,"10/05/97")
compare(modele," 04/04/01 ")
compare(modele,"5/1/01")

#  the model - a decimal number
modele=r"^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modele,"187.8")
compare(modele,"-0.6")
compare(modele,"4")
compare(modele,".6")
compare(modele,"4.")
compare(modele," + 4")
#    end

Notes:

  • Note the module imported on line 3. It contains the functions for handling regular expressions;
  • line 10: comparing a string to a regular expression (pattern) returns True if the string matches the pattern, False otherwise;
  • line 12: match.groups() is a tuple whose elements are the parts of the string that match the elements of the regular expression enclosed in parentheses. In the pattern:
  • ^.*?(\d+).*?, match.groups() will be a one-element tuple;
  • ^(.*?)(\d+)(.*?)$, match.groups() will be a 3-element tuple.

Results

Resultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)

Resultats(12 34,^.*?(\d+).*?$)
('12',)

Resultats(abcd,^.*?(\d+).*?$)
La chaine [abcd] ne correspond pas au modele [^.*?(\d+).*?$]

Resultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')

Resultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')

Resultats(abcd,^(.*?)(\d+)(.*?)$)
La chaine [abcd] ne correspond pas au modele [^(.*?)(\d+)(.*?)$]

Resultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')

Resultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')

Resultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaine [5/1/01] ne correspond pas au modele [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]

Resultats(187.8,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')

Resultats(-0.6,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')

Resultats(4,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')

Resultats(.6,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')

Resultats(4.,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')

Resultats( + 4,^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')

3.6. Function parameter passing mode


Program (bases_10)

#    -*- coding=utf-8 -*-

def f1(a):
    a=2

def f2(a,b):
    a=2
    b=3
    return (a,b)

#    ------------------------ hand
x=1
f1(x)
print "x=%s" % (x)
(x,y)=(-1,-1)
(x,y)=f2(x,y)
print "x=%s, y=%s" % (x,y)

Results

x=1
x=2, y=3

Notes:

  • Everything is an object in Python. Some objects are called "immutable": they cannot be modified. This is the case for numbers, strings, and tuples. When Python objects are passed as arguments to functions, it is their references that are passed, unless these objects are "immutable," in which case it is the value of the object that is passed;
  • The functions f1 (line 3) and f2 (line 6) are intended to illustrate the passing of an output parameter. We want the actual parameter of a function to be modified by the function;
  • Lines 3–4: The function f1 modifies its formal parameter a. We want to know if the actual parameter will also be modified.
  • lines 12–13: the actual parameter is x = 1. The result from line 1 shows that the actual parameter is not modified. Thus, the actual parameter x and the formal parameter a are two different objects;
  • lines 6–9: the function f2 modifies its formal parameters a and b, and returns them as results;
  • lines 15–16: the actual parameters (x, y) are passed to f2, and the result of f2 is assigned to (x, y). Line 2 of the results shows that the actual parameters (x, y) have been modified.

We conclude that when "immutable" objects are output parameters, they must be part of the results returned by the function.

3.7. Text files


Program (bases_11)

#    -*- coding=utf-8 -*-

import sys

#    sequential operation of a text file
#  this is a set of lines of the form login:pwd:uid:gid:infos:dir:shell
#  each line is put into a dictionary in the form login => [uid,gid,infos,dir,shell]

# --------------------------------------------------------------------------
def afficheInfos(dico,cle):
    #  displays the value associated with key in the dico dictionary if it exists
    valeur=None
    if dico.has_key(cle):
        valeur=dico[cle]
    if 'list' in str(type(valeur)):
        print "[{0},{1}]".format(cle,":".join(valeur))
    else:
        #  key is not a dictionary key dico
        print "la cle [{0}] n'existe pas".format(cle)           


def cutNewLineChar(ligne):
    #  delete the end-of-line mark if it exists
    l=len(ligne);
    while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
        l-=1
    return(ligne[0:l]);

#  set the file name
INFOS="infos.txt"

#  we open it in creation
try:
    fic=open(INFOS,"w")
except:
    print "Erreur d'ouverture du fichier INFOS en écriture\n"
    sys.exit()

#    generate arbitrary content
for i in range(1,101):
    ligne="login%s:pwd%s:uid%s:gid%s:infos%s:dir%s:shell%s" % (i,i,i,i,i,i,i)
    fic.write(ligne+"\n")

#  close the file
fic.close()

#  open it for reading
try:
    fic=open(INFOS,"r")
except:
    print "Erreur d'ouverture du fichier INFOS en écriture\n"
    sys.exit()

#    empty dictionary at start
dico={}

#  line reading  
ligne=fic.readline()  
while(ligne!=''):
    #  remove the end-of-line character
    ligne=cutNewLineChar(ligne)

    #  put the line in a table
    infos=ligne.split(":")

    #    retrieve login
    login=infos[0]

    #  remove the first two elements [login,pwd]
    infos[0:2]=[]

    #    create a dictionary entry
    dico[login]=infos

    #  line reading  
    ligne=fic.readline()  

#  close the file
fic.close()

#  using the dictionary
afficheInfos(dico,"login10")
afficheInfos(dico,"X")

Notes:

  • Line 37: to terminate the script in the middle of the code.

Results

The infos.txt file:

login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99

Screen output:

[login10,uid10:gid10:infos10:dir10:shell10]
la cle [X] n'existe pas