количество повторений для вложенного цикла for

Екатерина Бун

Новичок
Пользователь
Сен 29, 2021
13
0
1
Я создала функцию, которая выгружает пользователей и соответствующие им группы пользователей в Линукс.
Организовала как два вложенных цикла. Т.е. для каждого пользовательского аккаунта выводится пользовательская группа в которой он состоит:
1638947942573.png
Мне необходимо изменить код так, чтобы выводились не все пользователи, а определенное число. Например, 5 пользователей и их группы. Помогите, пожалуйста? Пробовала применять for x in range(5). Не получается. Мой код ниже:

import pwd
import grp


def Option1 ():
count = 0
linesOfAccountsData=5 # это переменная в которой я храню количество нужных повторений
sortAccountsReverse = True
print("Getting account names and groups")
try:
writeFile = open("testFile.txt", "w")
writeFile.write("USER:" + '\t\t' + "GROUP:" + '\n\n')

allUsers = pwd.getpwall()
allUsersSorted = sorted(allUsers, reverse = sortAccountsReverse)

#print(allUsersSorted)

allGroups = grp.getgrall()

for user in allUsersSorted:

count +=1

userName = user.pw_name

#Get default group name

groupID = user.pw_gid

groupRecord = grp.getgrgid(groupID)



print(count, userName, groupRecord.gr_name)


writeFile.write(userName + ":" +'\n\t\t' + groupRecord.gr_name + '\n')


#Get other group membership

for group in allGroups:

#print(group.gr_mem)

if userName in group.gr_mem:

print("\t",group.gr_name)

writeFile.write('\n\t\t' + group.gr_name + '\n')

except:
print("Cannot write to a file")
finally:
writeFile.close()

Option1()
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 672
478
83
вставьте код как код, соблюдая отступы, подробнее тут как задать вопрос
 

Екатерина Бун

Новичок
Пользователь
Сен 29, 2021
13
0
1
Извините, копировала с отступами, сохранила и получился сплошной текст. Ознакомилась с правилами публикации кода, пробую:

Код:
import pwd
import grp


def Option1 ():
    count = 0
    linesOfAccountsData=5
    sortAccountsReverse = True
    print("Getting account names and groups")
    try:
        writeFile = open("testFile.txt", "w")
        writeFile.write("USER:" + '\t\t' + "GROUP:" + '\n\n')
    
        allUsers = pwd.getpwall()
        allUsersSorted = sorted(allUsers, reverse = sortAccountsReverse)

        #print(allUsersSorted)
        
        allGroups = grp.getgrall()
        
        for user in allUsersSorted:

            count +=1
            
            userName = user.pw_name

            #Get default group name

            groupID = user.pw_gid

            groupRecord = grp.getgrgid(groupID)
            
            
              
            print(count, userName, groupRecord.gr_name)
        
        
            writeFile.write(userName + ":" +'\n\t\t' + groupRecord.gr_name + '\n')

            #Get other group membership

            
            for group in allGroups:

                #print(group.gr_mem)

                if userName in group.gr_mem:

                    print("\t",group.gr_name)

                    writeFile.write('\n\t\t' + group.gr_name + '\n')
                
    except:
        print("Cannot write to a file")
    finally:
        writeFile.close()

Option1()
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 672
478
83
во первых, для открытия файла лучше использовать менеджер контекста with, он гарантирует, что объект будет закрыт по окончанию работы....
во вторых, делать try на такую обширную часть кода, это очень дорого...
в третьих, у вас allUsersSorted - список, вы можете сделать срез списка, и пройтись по нему, allUsersSorted[:5] - это первые пять пользователей...
тоже самое с allGroups...

PS
код не запускал, так посмотрел, дома юникса нет, только на работе...

upd
и except у вас не определен, то есть вы перехватите все ошибки, это не есть хорошо...
 
Последнее редактирование:
  • Мне нравится
Реакции: Екатерина Бун

Екатерина Бун

Новичок
Пользователь
Сен 29, 2021
13
0
1
во первых, для открытия файла лучше использовать менеджер контекста with, он гарантирует, что объект будет закрыт по окончанию работы....
во вторых, делать try на такую обширную часть кода, это очень дорого...
в третьих, у вас allUsersSorted - список, вы можете сделать срез списка, и пройтись по нему, allUsersSorted[:5] - это первые пять пользователей...
тоже самое с allGroups...

PS
код не запускал, так посмотрел, дома юникса нет, только на работе...

upd
и except у вас не определен, то есть вы перехватите все ошибки, это не есть хорошо...
Большое спасибо за ответ! Про try except спасибо за замечание. Еще не проходила глубже как использовать. Не могли бы Вы пояснить что это значит "дорого"?
Спасибр за подсказку о срезе. Мне это помогло. Так как количество пользователей сколько мне нужно вывести берется из переменной linesOfAccountsData (это считанное значение из файла конфигурации, которое считывается в другой функции) и там может быть цифра, а может быть слово All(если мне нужно вывести всех пользователей), то я значение из linesOfAccountsData переприсвоила переменной end и применила метод .isnumeric(). Но он работает с типом стринг. Я явно переопределила новую переменную end в строковую.Сейчас у меня блок первый с условием "ЕСЛИ это цифры - то распечатай нужный диапазон пользовательских аккаунтов" работает.
А второе "ELSE" ( если не цифры - то будет False - распечатай всех пользователей) не работает. Вы не подскажете почему второе условие не срабатывает? Я выделила красным цветом то, о чем говорю.

Код:
import pwd
import grp


def Option1 ():
    count = 0
    linesOfAccountsData=All
    sortAccountsReverse = True
    print("Getting account names and groups")
    try:
        writeFile = open("testFile.txt", "w")
        writeFile.write("USER:" + '\t\t' + "GROUP:" + '\n\n')
    
        allUsers = pwd.getpwall()
        allUsersSorted = sorted(allUsers, reverse = sortAccountsReverse)

        #print(allUsersSorted)
        
        allGroups = grp.getgrall()
        
        start = 0
        end = linesOfAccountsData
        end = str(end)
        print(end)
        
        #print(end.isnumeric())
        if end.isnumeric() == True:
        
            for user in allUsersSorted[start:linesOfAccountsData]:

                count +=1
                
                userName = user.pw_name

                #Get default group name

                groupID = user.pw_gid

                groupRecord = grp.getgrgid(groupID)
                  
                  
                print(count, userName, groupRecord.gr_name)
            
            
                writeFile.write(userName + ":" +'\n\t\t' + groupRecord.gr_name + '\n')

                #Get other group membership

                
                for group in allGroups:

                    #print(group.gr_mem)

                    if userName in group.gr_mem:

                        print("\t",group.gr_name)

                        writeFile.write('\n\t\t' + group.gr_name + '\n')

            else:
                if end.isnumeric() == False:
        
                    for user in allUsersSorted:

                        count +=1
                        
                        userName = user.pw_name

                        #Get default group name

                        groupID = user.pw_gid

                        groupRecord = grp.getgrgid(groupID)
                          
                          
                        print(count, userName, groupRecord.gr_name)
                    
                    
                        writeFile.write(userName + ":" +'\n\t\t' + groupRecord.gr_name + '\n')

                        #Get other group membership

                        
                        for group in allGroups:

                            #print(group.gr_mem)

                            if userName in group.gr_mem:

                                print("\t",group.gr_name)

                                writeFile.write('\n\t\t' + group.gr_name + '\n')
                        
            
              
                  
    except:
        print("Cannot write to a file")
    finally:
        writeFile.close()


Option1()
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 672
478
83
Не могли бы Вы пояснить что это значит "дорого"?
в с++ конструкция try/catch очень затратная в плане производительности кода (это и есть дорого), вместо нее лучше использовать условия if/else...
в питоне try/except работают не так, как в с++ (в предыдущем сообщении я ошибся по поводу дороговизны try/except)...
у вас проблема в том, что except не определен, вы перехватываете все ошибки, которые возникнут в участке кода под try, так как там большой участок кода, ошибок может быть море...
и в finally у вас потенциальная ошибка, так как может случиться исключение в самом начале блока try и переменная writeFile не будет существовать...

и применила метод .isnumeric()
linesOfAccountsData=All, в этой строке у вас должна быть ошибка, потому что All не определена в вашем коде, либо это какая то переменная, которая вернула вам другая функция как вы сказали, что она возвращает какой тип данных?
если строка, или какой то тип который можно преобразовать в строку, то все должно работать
Python:
linesOfAccountsData = "4"

if linesOfAccountsData.isnumeric():
    print("число")
else:
    print("All")

есть еще метод isdigit() - он делает почти тоже самое, что и isnumeric, возвращает true, если в строке есть цифры
Python:
linesOfAccountsData = "4"

if linesOfAccountsData.isdigit():
    print("число")
else:
    print("All")


дальше
for user in allUsersSorted[start:linesOfAccountsData]: - тут позиция старт не нужна, она у вас всегда 0, если ее не указывать, то срез будет с нулевой позиции по умолчанию


Python:
end = linesOfAccountsData
end = str(end)
print(end)

#print(end.isnumeric())
if end.isnumeric() == True:
зачем вам переменная end? дальше вы ее не используете, можно работать сразу с переменной linesOfAccountsData


if end.isnumeric() == True: - можно не сравнивать с true, if end.isnumeric()



Python:
else:
    if end.isnumeric() == False:
можно убрать второй if
 
Последнее редактирование:

Форум IT Специалистов