>

채용 인은 채용 프로세스의 일환으로 숙제 문제를 겪었고 제출을받은 후 저와 함께 진행하지 않기로 결정했다고 말했습니다. 내가 그 이유를 물었을 때, 그는 저에게 숙련 된 파이썬 프로그래머에게 온라인 조언을 구해야한다고 말했습니다. 그는 "문제는 알고리즘 설계와 코드 구조"라고 말했다. 문제에 대한 간단한 설명과 코드는 이 요지 에 있습니다. 그가 생각하고있는 것을 알려주세요.

문제 설명 :

와이즈 비즈 와이즈 비즈

     

결과 :

     

Given a page of content with alphanumeric words, and a search phrase of N words, write an algorithm that will return the shortest snippet of content that contains all N words in any order. Example: The George Washington Bridge in New York City is one of the oldest bridges ever constructed. It is now being remodeled because the bridge is a landmark. City officials say that the landmark bridge effort will create a lot of new jobs in the city.

Search Terms:

솔루션 :

Landmark City Bridge

bridge is a landmark. City
  • 답변 # 1

    채용 인의 의견에 동의합니다.이 코드는 좋은 첫 인상을주지 않습니다.

    빨간 깃발

    이러한 문제 중 하나라도 처음 몇 초 안에 실격 될 수 있습니다.

    너무 많은 코드.누군가 프로그래밍 퍼즐을 제공하면 짧고 우아한 솔루션을 기대할 수 있습니다. 아무도 길고 답답한 답변을 읽고 싶지 않으므로 많은 코드가 필요한 질문을하지 않을 것입니다.

    대량의 코드는 하나의 긴 기능입니다. 해당 함수 내에서 코드 덩어리를 가리킬 수 없으며 해당 덩어리의 목적이 무엇인지 말할 수 없었습니다. 남겨둔 의견은 쓸모없는 정크입니다. 모두 디버깅을 위해 비활성화 된 print 문입니다.

    댓글과 빈 줄을 제외한 65 줄이 있습니다. 아래 제안 된 솔루션은 약 절반입니다.

    글로벌 변수.전역 변수는 최후의 수단으로 만 사용해야한다는 데 널리 동의합니다. 여기에는 그들에 대한 정당성이 없습니다. 부작용을 지역화하지 않음으로써 코드에 대한 추론을 어렵게 할뿐만 아니라 함수의 인터페이스가 느슨하다는 것을 나타냅니다. 함수의 입력 및 출력이 무엇인지 확실하지 않습니다.

    변수가 너무 많습니다. FindShortest() 내 , 우리는 : <올>

    CurrentTerm

    MatchIndexes  (글로벌?)

    LeftBorder  (전세계)

    RightBorder  (전세계)

    FinalLeftBorder  (전세계)

    FinalRightBorder  (전세계)

    SearchTerms

    OptimalRightBorderFound

    OldLeftBorder

    OldRightBorder

    인간의 마음은 한 번에 약 7 가지를 추적 할 수 있습니다. 이상적으로는 함수 당 약 3 개의 변수 만 있어야합니다.

    비 아이디 오틱 파이썬정규 표현식을 사용했습니다. 그 외에는 C 솔루션과 크게 다르지 않습니다. 보다 추상적 인 수준에서 생각하는 능력을 보여 주어야합니다.

    비표준 명명.함수 find_shortest 를 호출해야합니다. 및 해당 매개 변수 current_term 모든 변수에 대해 비슷합니다. 와이즈 비즈  식별자는 클래스 이름처럼 보입니다. Python의 표준 스타일 가이드 인 PEP 8을 참조하십시오.

    함수의 이름은 그 효과가 자신의 코드를 넘어 확장되기 때문에 특히 중요합니다. 방금 비표준 명명으로 미래의 동료들에게 부담을 줄 것이라고 방금 말씀하셨습니다.

    노란색 깃발

    이 또한 심각한 문제입니다. 언뜻보기에는 적기만큼 명확하지 않습니다.

    자유 플로팅 준비 코드가 많이 있습니다.파일 열기와 UpperCase 호출 사이에는 많은 코드가 있습니다 . 왜 그럴까요? 왜 기능에 포함되어 있지 않습니까?

    무심한 연결 FindShortest()  그 RegexVariable = r"\W" + Term + r"\W" 를 신뢰  정규식 내에서 특별한 의미를 가진 문자는 포함하지 않습니다. 한 줄의 부주의 한 연결에서 SQL 삽입, 크로스 사이트 스크립팅, 임의의 명령 실행, 헤더 분할 공격 등에 취약한 코드를 작성하는 것이 좋습니다.

    무책임한 재귀함수가 자신을 호출 할 때 재귀입니다. 그러나 재귀는 책임감있게 사용해야합니다. 불변, 잘 정의 된 함수 입력 및 출력, 기본 사례 및 재귀 사례가 있어야합니다. 그러나 당신은 그러한 요소가 없기 때문에 효과적으로 당신은 이상한 Term 를 가지고 있습니다. .

    제안 된 솔루션

    비교를 위해 내가 생각해 낸 것은 다음과 같습니다. 성능보다 단순성을 위해 최적화되어 있습니다. 일반적으로 해당 목표를 면담 자에게 전달하는 것이 좋습니다.

    잘 정의 된 입력과 출력을 가진 세 가지 기능을 연결하여 작업을 수행합니다.

    goto
    
    

  • 답변 # 2

    빠르다 ( "나는 미루다"와 같이) 팁 :

    표준 명명을 사용하십시오. 적어도 PEP 8에 따라 TheseFormsOfVariableNames를 these_forms_of_variable_names로 바꾸십시오.

    전역 변수의 상태는 거의 항상 나쁘다. 그 행동을 수익으로 캡슐화하십시오.

    파일은 안전해야합니다. 난 당신이 from collections import namedtuple from itertools import product import re WordPos = namedtuple('WordPos', ['start', 'end']) def find_all_words(text, words): """ For each word in the list, find all positions in which they appear in the text. Results are returned as a dict, with the words as keys. Each value is a list, with a WordPos object to mark each occurrence of the word in the text. """ def positions(text, word): word_re = re.compile(r'\b' + re.escape(word) + r'\b', re.IGNORECASE) return [WordPos(match.start(), match.end()) for match in word_re.finditer(text)] return { word: positions(text, word) for word in words } def cluster(found_words): """ Given a dict resulting from find_all_words(), pick the occurrence of each word that minimizes the length of the substring of text that contains them all. The result is a WordPos object that represents the span of the cluster. If any of the words does not appear in the text, then this function returns None. """ def bounds(combo): start = min(word.start for word in combo) end = max(word.end for word in combo) return WordPos(start, end) positions = found_words.values() combo_bounds = [bounds(combo) for combo in product(*positions)] if combo_bounds: # Find the shortest combo return min(combo_bounds, key=lambda span: span.end - span.start) else: # At least one search term was not found return None def excerpt(text, combo_bounds): """ Take the substring of text corresponding to the given span. """ if not combo_bounds: return None return text[combo_bounds.start : combo_bounds.end] test_text = """The George Washington Bridge in New York City…""" test_terms = 'Landmark City Bridge'.split() print(excerpt(test_text, cluster(find_all_words(test_text, test_terms)))) 를 찾는 것이 좋습니다  성명서. 사용합니다

    with
    
    

    문자열이나 목록 같은 구조에 명시 적으로 설계되지 않았거나알고충분히 알고 있지 않는 한 루프에서 문자열 또는 목록과 같은 구조에 추가를 사용하지 마십시오. 적용되지 않습니다. 와이즈 비즈  더 잘 작동했을 것입니다.

    with open(...) as myfile: do_stuff_with(myfile)  그냥 f.read() 를 작성하는 것이 좋습니다 .

    함수와 클래스에서 더 많은 것들을 캡슐화합니다.

    x[:len(x) - y]  사용하기에는 조금 이상합니다. 와이즈 비즈  제대로 작동하고 목록을 반환하는 기능 (인쇄없이)은 더 잘 작동했을 것입니다.

    모든 디버그 명령문으로 코드를 쉽게 읽을 수있는 것은 아닙니다.

    네가 놓친 것은 실제 코드에 대한 경험 일 뿐이라고 생각한다. 임의의 오픈 소스 Python 코드와 같은 내용을 읽거나 표준 라이브러리 관련 내용 ¹에 대해 이해하면 코드가느낌을 의미하는 방식을 파악하는 데 도움이됩니다. 코드를 읽음으로써 얻은 가장 큰 의미는 코드가 너무 다르기 때문에 파이썬이 아니라는 것입니다. 나는 알고리즘에 관심이있는 시점에 도달하지 못했습니다. 팀에서 일하고 있다면 비표준이기 때문에 많은 어려움을 겪을 것입니다.

    ¹ 임의로 선택;최근에 읽은 이러한 특정 내용을 추천하기에 충분한 바이트 크기로 기억했습니다.

    x[:-y]

  • 이전 algorithm - C의 피보나치 힙
  • 다음 ASPNet Core 21 preview1 HTTP 오류 5025 프로세스 실패