반응형
반응형

2025-05-26. 팔굽혀펴기 100개

반응형
반응형

[python] 유튜브 자막 가져오기 

 

 

""" 유튜브 자막 가져오기 
    pip install youtube-transcript-api
    
    -- 최신 버전으로 업데이트
    pip install --upgrade youtube-transcript-api

    https://www.youtube.com/watch?v=XyljmT8dGA4
    
    자막있는 동영상 : https://www.youtube.com/watch?v=zRz9q8dPjC4
"""


from youtube_transcript_api import YouTubeTranscriptApi
# youtube_transcript_api._errors 에서 TooManyRequests를 제외하고 임포트합니다.
# TooManyRequests는 더 이상 직접 임포트할 수 없는 것으로 보입니다.
from youtube_transcript_api._errors import NoTranscriptFound, TranscriptsDisabled, VideoUnavailable

def get_youtube_transcript(video_id, languages=['ko', 'en']):
    """
    주어진 YouTube 동영상 ID와 언어 목록에 대해 자막을 가져옵니다.
    자동 생성 자막과 공식 자막을 모두 시도합니다.
    """
    try:
        # 우선 공식 자막을 시도
        transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)

        # 사용 가능한 언어 목록에서 요청한 언어 중 하나를 찾아 가져옵니다.
        chosen_transcript = None
        for lang_code in languages:
            for transcript in transcript_list:
                if transcript.language_code == lang_code:
                    chosen_transcript = transcript
                    break
            if chosen_transcript:
                break

        if chosen_transcript:
            print(f"[{video_id}] {chosen_transcript.language} ({chosen_transcript.language_code}) 자막을 가져옵니다.")
            # fetch()는 이제 FetchedTranscript 객체를 반환하며, 이는 이터러블합니다.
            transcript_segments = chosen_transcript.fetch()
            return transcript_segments
        else:
            raise NoTranscriptFound(
                f"No suitable official transcript found for video {video_id} in languages {languages}.",
                video_id
            )

    except NoTranscriptFound:
        print(f"[{video_id}] 공식 자막을 찾을 수 없습니다. 자동 생성 자막을 시도합니다.")
        try:
            for lang_code in languages:
                try:
                    # get_transcript() 역시 이터러블한 객체를 반환하는 것으로 가정합니다.
                    transcript_segments = YouTubeTranscriptApi.get_transcript(video_id, languages=[lang_code], preserve_formatting=True)
                    print(f"[{video_id}] {lang_code} 자동 생성 자막을 가져왔습니다.")
                    return transcript_segments
                except NoTranscriptFound:
                    continue # 다음 언어로 시도
            print(f"[{video_id}] 요청된 언어 ({languages})로 자동 생성 자막도 찾을 수 없습니다.")
            return None # 적합한 자막을 찾지 못함
        except TranscriptsDisabled:
            print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
            return None
        except VideoUnavailable:
            print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
            return None
        except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
            # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
            print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
            return None

    except TranscriptsDisabled:
        print(f"[{video_id}] 이 동영상은 자막이 비활성화되어 있습니다.")
        return None
    except VideoUnavailable:
        print(f"[{video_id}] 동영상을 사용할 수 없거나 비공개/삭제되었습니다.")
        return None
    except Exception as e: # TooManyRequests를 포함한 모든 예외를 잡습니다.
        # 이 부분에서 TooManyRequests 에러를 포함하여 일반적인 오류를 처리합니다.
        print(f"[{video_id}] 자막을 가져오는 중 예기치 않은 오류가 발생했습니다: {e}")
        return None


if __name__ == "__main__":
    # 예시 동영상 ID (실제 존재하는 동영상 ID로 변경해야 합니다)
    # 제가 추천해 드렸던 URL에서 ID를 추출했습니다.
    video_id_with_subtitle = "XyljmT8dGA4" # "모바일 유튜브 자동번역 한글자막 보는 방법"
    video_id_auto_caption = "XyljmT8dGA4" # 짧은 영상 (자동 생성 자막 가능성)
    #video_id_invalid = "invalid_video_id_123"
    video_id_invalid = "XyljmT8dGA4"

    print("--- 예제 1: 자막이 있는 동영상 ---")
    transcript_data = get_youtube_transcript(video_id_with_subtitle, languages=['ko', 'en'])
    if transcript_data:
        # segment.start, segment.duration, segment.text와 같이 속성으로 접근합니다.
        for i, segment in enumerate(transcript_data[:5]): # 슬라이싱은 여전히 가능해야 합니다.
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data))}개 세그먼트)") # len()을 위해 list로 변환

        # 전체 자막 텍스트만 추출하고 싶다면:
        full_text = " ".join([segment.text for segment in transcript_data])
        print("\n--- 전체 자막 텍스트 (예제 1) ---")
        print(full_text[:500] + "...")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 2: 자동 생성 자막을 시도할 수 있는 동영상 ---")
    transcript_data_auto = get_youtube_transcript(video_id_auto_caption, languages=['en', 'ko'])
    if transcript_data_auto:
        for i, segment in enumerate(transcript_data_auto[:5]):
            print(f"[{segment.start:.2f}-{segment.start + segment.duration:.2f}] {segment.text}")
        print(f"... (총 {len(list(transcript_data_auto))}개 세그먼트)")
    else:
        print("자막을 가져오지 못했습니다.")

    print("\n--- 예제 3: 존재하지 않는 동영상 ID ---")
    transcript_data_invalid = get_youtube_transcript(video_id_invalid)
    if transcript_data_invalid:
        print("자막을 가져왔습니다.")
    else:
        print("자막을 가져오지 못했습니다.")
반응형
반응형

당신의 '화목한' 팀이 실패하는 이유

Why Your ‘Harmonious’ Team Is Actually Failing

 

https://terriblesoftware.org/2025/03/12/why-your-harmonious-team-is-actually-failing/

 

🔹 심리적 안전감의 오해와 진짜 의미

  • 오해: 갈등이 없는 조용하고 화목한 분위기가 심리적 안전감이라 착각함.
  • 진짜 의미: 아이디어, 질문, 우려, 실수를 처벌 없이 표현할 수 있는 믿음이 있는 상태.
    (하버드대 Amy Edmondson 교수의 정의)

🔹 심리적 안전이 높은 팀의 특징

  • 발언이 자유롭고, 격렬한 논쟁도 환영됨.
  • 아이디어에 대한 도전이 신분과 상관없이 가능.
  • 실수를 학습의 기회로 삼음.
  • 문제에 대해 빠르게 인식하고 공유.
  • 사람보다 문제아이디어 내용에 집중.

🔹 생산적인 토론이 이루어지는 팀 문화

  • 문제를 조기에 드러냄 (예: 엔지니어가 사소한 문제도 먼저 언급)
  • 설계나 기술적 이견에 대해 격렬하게 토론하더라도 관계에 문제 없음.
  • Postmortem 회고 시 실수한 당사자가 주도적으로 나섬.

🔹 갈등 없는 '착한' 팀이 놓치는 것

  • 겉으론 평화로우나 비판적 사고 부족으로 평균적인 성과에 그침.
  • 회의에서는 동의했지만 실제 실행에서는 불일치 발생.
  • 의사소통 부족 → 숨은 갈등 → 성과 저하.

🔹 심리적 안전과 갈등의 균형을 위한 리더의 역할

  1. 취약성 드러내기: 리더 스스로 모르는 걸 인정.
  2. 토론 규칙 만들기: 사람 아닌 아이디어를 비판하고, 결정과 토론은 구분.
  3. 도전 장려: 어려운 질문을 던진 사람을 공식적으로 칭찬.

🔹 결론: 건강한 충돌이 팀을 성장시킨다

  • 갈등을 자유롭게 표현하는 팀은 오히려 갈등이 적고 신뢰가 높음.
  • 조용한 팀보다 다양한 시각과 기술적 논쟁이 있는 팀이 더 강함.
  • 검증 없는 아이디어는 실패의 원인이며, 논쟁 없는 팀도 실패를 부른다.
반응형
반응형

"이 기분을 잊지 말렴.
네가 태어난 건 정말 기적같은 일이란 걸
한시도 잊지 말거라. 그리고 네가 태어나서
온 세상이 기뻐하고 있다는 것도 꼭 기억해!
매일 살아 있음이 얼마나 놀라운 일인지,
모든 곳에 친척과 친구가 있음이 얼마나
놀라운 일인지, 네가 꼭 알기를 바란다.
인간, 동물, 식물, 돌도 다 우리의
친구란다. 이제 알겠니?
진정한 마법이
무엇인지?


- 디르크 그로서, 제니 아펠의《너는 절대 혼자가 아니야》중에서 -


* 친구 하나를 얻는 것도
마법 같은 일입니다. 하물며 한 생명이
탄생한다는 것은 그 자체만으로 마법입니다.
또 하나의 작은 우주가 태어난다는 뜻이니까요.
자연물도 같습니다. '꽃을 한 송이 꺾으면 지구가
전율한다'는 시구는 과장된 표현이 아닙니다.
한 알의 모래알에서 우주를 보고 영원을
읽어야 합니다. 모든 것은 친구처럼
더불어 살아가며, 더불어
기뻐합니다.

 

잊지 마렴, 네가 태어난 건 기적이야!

"이 기분을 잊지 말렴. 네가 태어난 건 정말 기적 같은 일이란 걸 한시도 잊지 말거라. 그리고 네가 태어나서 온 세상이 기뻐하고 있다는 것도 꼭 기억해!"

이 아름다운 문장은 디르크 그로서와 제니 아펠의 《너는 절대 혼자가 아니야》에 나오는 구절입니다. 우리는 이 세상에 태어난 순간부터 이미 기적 그 자체였습니다. 우리가 존재한다는 것만으로 온 세상이 기뻐하고 있다는 사실, 늘 기억해야 할 소중한 진실이죠.

살아있음의 놀라운 마법

매일 숨 쉬며 살아간다는 것, 그 자체로 얼마나 놀라운 일인가요? 우리 주변에 있는 가족, 친구들과 함께한다는 것은 또 얼마나 감사한 일인가요. 인간뿐만 아니라 동물, 식물, 심지어 길가의 돌멩이 하나까지도 모두 우리의 친구입니다. 이 모든 존재와 더불어 살아가는 것이 바로 진정한 마법이 아닐까요?

작고 사소한 것에서 우주를 보다

친구 한 명을 얻는 것조차 마법 같은 일인데, 한 생명이 탄생한다는 것은 그야말로 우주가 새로 생겨나는 것과 같습니다. 이렇듯 자연의 모든 것도 마찬가지입니다. **'꽃을 한 송이 꺾으면 지구가 전율한다'**는 시구는 결코 과장된 표현이 아닙니다.

우리는 한 알의 모래알에서 우주를 보고 영원을 읽을 수 있어야 합니다. 모든 존재는 서로 친구처럼 더불어 살아가며, 함께 기뻐하는 놀라운 연결고리를 가지고 있습니다. 작은 것 하나에서도 큰 의미를 발견하는 삶, 그것이 바로 우리가 누릴 수 있는 가장 큰 행복일 것입니다.

 

 

반응형

'아침편지' 카테고리의 다른 글

아버지를 이해할 수 있는 나이  (0) 2025.05.28
늙은 바위와 씨앗  (0) 2025.05.27
공분  (0) 2025.05.26
94세 할머니 화가  (0) 2025.05.23
꽃에 둘러싸여 있으면  (0) 2025.05.22
반응형

공분

 

활활 타오른다

 

반응형

'아침편지' 카테고리의 다른 글

늙은 바위와 씨앗  (0) 2025.05.27
진짜 마법 같은 일  (0) 2025.05.26
94세 할머니 화가  (0) 2025.05.23
꽃에 둘러싸여 있으면  (0) 2025.05.22
스스로를 이기는 사람  (0) 2025.05.21
반응형

[PYTHON] Streamlit: 데이터 과학자의 쉬운 웹 제작 도구

 

vscode에서 streamlit 디버깅 하기

 

 

// conda env list
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "streamlit debug (p_ai env)",
            "type": "python",
            "request": "launch",
            "module": "streamlit",
            "args": ["run", "${file}"],
            "justMyCode": true,
            "python": "C:\\ProgramData\\anaconda3\\envs\\p_ai\\python.exe" // <--- 이 줄을 추가합니다. 
        }
    ]
}

 

 

https://github.com/ngio/py_ai/blob/main/README.md

반응형

+ Recent posts