2016-08-25 3 views
0

시스템의 복잡한 백엔드가 있지만 간단한 예제를 만들려고 했으므로 내가 무슨 말을하고 있는지 알 수 있습니다.목록 요소를 점검하고 오류가없는 목록의 끝에서 멈출 수있는 방법이 있습니까?

본질적으로 나는 ID 목록을 가지고 있으며, 사용자는 GUI를 통해 ID를 생성하는이 목록을 순환합니다.

어느 시점에서, 그들은 엉망이되거나 건너 뛴 모든 것을 고치고 수정하려고합니다 (이들은 모두 동일한 ID를가집니다). 이것은 내가 문제가있는 곳입니다.

정확하게 (나쁜 ID의 목록을 확인하는) 내용을 작성했지만 문제는 목록 끝에 도달하면 색인 오류가 발생합니다. 나는 깨끗하게 동안 루프, 대신

def nextID(): 
    ''' 
     increment counter until we find a junk ID 
    ''' 
    global tindx 

    skips = 0 
    while IDs[tindx] != 'junk_id' and tindx != len(IDs): 
     print 'This ID is good: %s' %IDs[tindx] 
     skips+=1 
     tindx+=1  
    print 'Skipped %i IDs' %(skips), 'tindx is now',tindx 

이 설계되는 함수 (다시 거대한 단순화)

tindx = 0 

IDs = ['abc','bcd','cde','junk_id','junk_id','def','efg','junk_id','fgh','ghi'] 

# This is all hadled with in an interactive GUI 
# User wants next ID 
nextID() 
# User changes ID 
IDs[tindx] = 'good_id!' 
# User wants next ID 
nextID() 
# User changes ID 
IDs[tindx] = 'another_good_id' 
# etc .... 

은 내가 전환하는 경우 알고 다음과 같은 방법으로 사용될를 종료 할 while 루프 조건의 순서는 자동 IndexError을 피할 수 있지만 사용자는 목록의 끝에 도달했는지 알 수 없으며 ID를 변경하려고 시도합니다 (동일한 오류가 발생 함).

사용자에게 완료되었음을 알리고 save_IDs() 함수를 실행하고 프로그램을 종료하고 싶습니다. 소프트웨어를 재 설계의이면, 다음 if 조건을 추가하는 것보다 더 좋은 방법이있다

while ... 

    if tindx == len(IDs): 
     print 'you\'re done' 
     save_IDs() 
     return None 

답변

1

당신이 언급 한 것처럼, 당신은 반면에 인수를 전환해야 할 그렇지 않으면

while tindx != len(IDs) and IDs[tindx] != 'junk_id': 
    ... 

을 먼저 ID [tindx]에 액세스 한 다음 유효하지 않은지 확인합니다.

def nextID(last_offset): 
    offset = last_offset 

    while offset < len(IDs) and IDs[offset] != 'junk_id' 
     offset += 1 

    if offset >= len(IDs): 
     return None 

    if offset > last_offset: 
     print("Skipped %d IDs" % (offset - last_offset)) 

    return offset 

이 그 다음을 사용 :

current_offset = 0 
while doing things: 
    current_offset = nextID(current_offset) 
    if current_offset == None: 
     # All done. 
     break 

    print("New offset: %d" % (offset)) 

    if user changes id: 
     IDs[current_offset] = 'good_id!' 
    else: 
     # If the user didn't change the ID for whatever reason, 
     # you'll need to manually increment current_offset. 
     current_offset += 1 

print("All done, saving..") 
saveIDs() 

당신이 내부 콜백에 있다면 그 끝에 도달 할 때 문제에 대한

, 당신은 nextID 새로운 인덱스 또는 없음을 반환 할 수 GUI라면 다음과 같은 것을 가질 수 있습니다 :

def userChangedID(new_value): 
    global current_offset 

    IDs[current_offset] = new_value 
    current_offset = nextID(current_offset) 

    if current_offset == None: 
     finish() 

def userSkippedID(): 
    global current_offset 

    current_offset = nextID(current_offset + 1) 

    if current_offset == None: 
     finish() 

def finish(): 
    global finished 

    finished = True 
    print("All done, saving...") 
    saveIDs() 

이상적인 방법은 효과가 있어야 할 일을 수행해야합니다.

원본 코드에서 nextID()는 '다음 ID 찾기'뿐만 아니라 전체 프로세스의 상태를 변경하고있었습니다.

이것은 다음 ID를 찾아서 반환하기 위해 nextID()를 기대하는 개발자의 관점에서 상당히 오도 된 것입니다.

+0

나는 nextID에 대한 나의 정의에 대해 고맙게 생각합니다. 이것은 주로 스스로 가르치기 때문에 만나는 공통적 인 문제입니다. 예제는 훨씬 더 잘 읽고, 대신에 필자가 사용한 함수를 재구성한다고 생각합니다. 그것은 약간의 일이 될 것이지만, 나중에 나 자신에게 감사 할 것입니다. 이것을 설명해 주셔서 감사합니다. – FriskyGrub