반응형
반응형

What’s New in Python 3.13

https://medium.com/@rdhankhar899/whats-new-in-python-3-13-45516e6568a8

 

What’s New in Python 3.13

This article explains the new features in Python 3.13, compared to 3.12. Python 3.13 was released on October 7, 2024, marking a significant…

medium.com

https://docs.python.org/ko/3.13/whatsnew/3.13.html#what-s-new-in-python-3-13

 

What’s New In Python 3.13

Editors, Adam Turner and Thomas Wouters,. This article explains the new features in Python 3.13, compared to 3.12. Python 3.13 was released on October 7, 2024. For full details, see the changelog. ...

docs.python.org

This article explains the new features in Python 3.13, compared to 3.12. Python 3.13 was released on October 7, 2024, marking a significant advancement for the language. Many of the most impactful changes occur behind the scenes, so they may take time to notice.

Python 3.13 is setting the stage for future enhancements, particularly in terms of performance improvements. For full details, see the changelog.

Python 3.13 is the latest stable release of the Python programming language, with a mix of changes to the language, the implementation and the standard library. The biggest changes include a new interactive interpreter, experimental support for running in a free-threaded mode (PEP 703), and a Just-In-Time compiler (PEP 744).

Error messages continue to improve, with tracebacks now highlighted in color by default. The locals() builtin now has defined semantics for changing returning mapping, and type parameters now support values.

The library changes contain removal of deprecated APIs and modules, as well as the usual improvements in user-friendliness and correctness. Several legacy standard library modules have now been removed following their deprecation in Python 3.11 (PEP 594).

Here is a list of major features and improved modules.

· Improved REPL

· Free Threading Cpython

· An Experimental just-in-time (JIT)

· Improved Error Messages

· Copy’s Replace

· Support for Mobile Platforms

Improved REPL

Python now uses a new interactive shell by default, based on code from the PyPy project. When the user starts the REPL from an interactive terminal, the following new features are now supported:

  • Multiline editing with history preservation.
  • Direct support for REPL-specific commands like help, exit, and quit, without the need to call them as functions.
  • Prompts and tracebacks with color enabled by default.
  • Interactive help browsing using F1 with a separate command history.
  • History browsing using F2 that skips output as well as the >>> and  prompts.
  • “Paste mode” with F3 that makes pasting larger blocks of code easier (press F3 again to return to the regular prompt).

Free Threading Cpython

CPython now has experimental support for running in a free-threaded mode, with the global interpreter lock (GIL) disabled. This is an experimental feature and therefore is not enabled by default. The free-threaded mode requires a different executable, usually called python3.13t or python3.13t.exe. Pre-built binaries marked as free-threaded can be installed as part of the official Windows and macOS installers, or CPython can be built from source with the — disable-gil option.

An Experimental just-in-time (JIT)

When CPython is configured and built using the — enable-experimental-jit option, a just-in-time (JIT) compiler is added which may speed up some Python programs. On Windows, use PCbuild/build.bat — experimental-jit to enable the JIT or — experimental-jit-interpreter to enable the Tier 2 interpreter. Build requirements and further supporting information are contained at Tools/jit/README.md.

Improved Error Messages

The interpreter now uses color by default when displaying tracebacks in the terminal. This feature can be controlled via the new PYTHON_COLORS environment variable as well as the canonical NO_COLOR and FORCE_COLOR environment variables. (Contributed by Pablo Galindo Salgado in gh-112730.)

The error message now tries to suggest the correct keyword argument when an incorrect keyword argument is passed to a function.

# Incorrect usage of the built-in sorted() function
sorted([3, 1, 2], reversed=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    sorted([3, 1, 2], reversed=True)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
TypeError: sorted() got an unexpected keyword argument 'reversed'. Did you mean 'reverse'?

Copy’s Replace

The new replace() function and the replace protocol make creating modified copies of objects much simpler. This is especially useful when working with immutable objects. The following types support the replace() function and implement the replace protocol:

Any user-defined class can also support copy.replace() by defining the __replace__() method. (Contributed by Serhiy Storchaka in gh-108751.)

Support for Mobile Platforms

PEP 730: iOS is now a PEP 11 supported platform, with the arm64-apple-ios and arm64-apple-ios-simulator targets at tier 3 (iPhone and iPad devices released after 2013 and the Xcode iOS simulator running on Apple silicon hardware, respectively). x86_64-apple-ios-simulator (the Xcode iOS simulator running on older x86_64 hardware) is not a tier 3 supported platform, but will have best-effort support. (PEP written and implementation contributed by Russell Keith-Magee in gh-114099.)

PEP 738: Android is now a PEP 11 supported platform, with the aarch64-linux-android and x86_64-linux-android targets at tier 3. The 32-bit targets arm-linux-androideabi and i686-linux-android are not tier 3 supported platforms, but will have best-effort support. (PEP written and implementation contributed by Malcolm Smith in gh-116622.)

반응형
반응형

PyQt5와 requests 및 BeautifulSoup를 이용해 URL을 입력하고, 해당 웹 페이지의 내용을 크롤링하여 보여주는 기본 프로그램.

입력한 URL의 HTML 내용과 크롤링된 특정 텍스트 내용을 보여주는 두 개의 영역

import sys
import requests
from bs4 import BeautifulSoup
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QScrollArea, QTextBrowser, QTextEdit
from PyQt5.QtCore import Qt

class WebCrawlerApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 창 설정
        self.setWindowTitle("URL Web Crawler")
        self.setGeometry(300, 300, 800, 600)
        
        # 메인 레이아웃 설정
        layout = QVBoxLayout()

        # URL 입력창 및 버튼 추가
        self.url_input = QLineEdit(self)
        self.url_input.setPlaceholderText("Enter URL here...")
        layout.addWidget(self.url_input)
        
        self.submit_button = QPushButton("Submit", self)
        self.submit_button.clicked.connect(self.fetch_web_content)
        layout.addWidget(self.submit_button)
        
        # HTML 내용 표시 (링크 지원을 위해 QTextBrowser 사용)
        self.html_label = QLabel("Page HTML Content:")
        layout.addWidget(self.html_label)
        
        self.html_content = QTextBrowser(self)
        self.html_content.setOpenExternalLinks(False)  # QTextBrowser 내부에서 링크 클릭 이벤트를 처리
        self.html_content.anchorClicked.connect(self.handle_link_click)
        html_scroll = QScrollArea(self)
        html_scroll.setWidgetResizable(True)
        html_scroll.setWidget(self.html_content)
        layout.addWidget(html_scroll)

        # 크롤링된 내용을 보여줄 텍스트 창
        self.crawl_label = QLabel("Crawled Data:")
        layout.addWidget(self.crawl_label)
        
        self.crawled_content = QTextEdit(self)
        self.crawled_content.setReadOnly(True)
        crawl_scroll = QScrollArea(self)
        crawl_scroll.setWidgetResizable(True)
        crawl_scroll.setWidget(self.crawled_content)
        layout.addWidget(crawl_scroll)
        
        # 레이아웃 설정
        self.setLayout(layout)

    def fetch_web_content(self):
        # URL 가져오기
        url = self.url_input.text().strip()
        if not url:
            self.html_content.setText("Please enter a valid URL.")
            return
        
        try:
            # 웹 페이지 요청 및 파싱
            response = requests.get(url)
            response.raise_for_status()
            html_text = response.text
            
            # HTML 내용을 보여줌
            self.html_content.setHtml(html_text)
            
            # BeautifulSoup으로 HTML 파싱
            soup = BeautifulSoup(html_text, 'html.parser')
            
            # 특정 태그 내용 크롤링 예시 (모든 <p> 태그 내용)
            paragraphs = soup.find_all('p')
            crawled_data = "\n\n".join([p.get_text(strip=True) for p in paragraphs])
            
            # 크롤링된 내용 표시
            if crawled_data:
                self.crawled_content.setText(crawled_data)
            else:
                self.crawled_content.setText("No <p> tags found on the page.")

        except requests.exceptions.RequestException as e:
            self.html_content.setText(f"Error fetching the URL: {e}")
            self.crawled_content.setText("")

    def handle_link_click(self, url):
        # 링크를 클릭하면 URL 입력창에 설정하고 자동으로 Submit
        self.url_input.setText(url.toString())
        self.fetch_web_content()

# 애플리케이션 실행
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = WebCrawlerApp()
    window.show()
    sys.exit(app.exec_())
반응형
반응형

변혁을 이끄는 CIO는 혁신 달성, 비즈니스 영향력 확대, 운영 및 보안 위험 감소에 있어 IT 문화가 중요하다는 점을 알고 있다. 견고한 IT 문화가 없다면 IT팀이 일상 ‘비즈니스 운영’ 책임을 넘어 비즈니스 부서 동료, 데이터 과학자, 파트너와의 협력하는 영역으로 확장하도록 동기를 부여하기가 어렵다.

고성과 팀 문화 조성에 관한 데일 카네기(Dale Carnegie) 연구에 따르면, 리더와 구성원이 팀 문화를 보는 방식에 차이가 있었다. 리더의 73%는 팀의 책임감 문화가 ‘매우 좋음’ 이상이라고 평가한 반면, 같은 응답을 한 팀원은 48%에 그쳤다. 또한 리더의 84%가 조직의 팀워크가 강하다고 믿었지만, 팀원은 60%만이 동의했다.

높은 성과를 내는 팀을 육성하고, 유능한 인재를 채용 및 유지하고, 디지털 KPI를 꾸준히 개선하는 것이 견고한 IT 문화의 특징이지만, 이런 지표는 CIO가 추진하는 문화 개선 프로그램의 실제 효과를 즉각 반영하지 못하는 경우가 많다. 더욱 우려되는 점은 IT 문화를 저해하는 요인들이 KPI나 직원 만족도 조사에서 수개월 동안 드러나지 않을 수 있다는 것이다.

경험상 CIO는 대개 올바른 의도를 가지고 있지만, 때로는 의도치 않은 실수를 저질러 IT 문화를 해칠 수 있다. 최근 ‘CIO가 우려해야 할 5가지 IT 리스크’에 관한 기사에서도 팀 소진, 기술 부채 증가, 계속되는 위기 관리 등 몇 가지 IT 팀 문화 문제를 강조한 바 있다. CIO가 IT 문화를 해치는 10가지 길과 이를 방지하는 방법을 소개한다.

마이크로매니지먼트 또는 명령 및 통제에 의존
클라리오(Clario)의 EVP 겸 정보기술제품 책임자인 제이 페로는 “마이크로매니지먼트(micromanagement)는 IT 문화를 파괴하는 가장 빠른 방법”이라고 말했다. 그는 “CIO가 팀의 의사결정을 믿지 않거나 모든 세부 사항을 감시할 때 창의성과 혁신은 저해된다. 고성과 전문가는 자율성을 원하며, 마이크로매니지먼트로 인해 숨이 막힌다고 느끼면 업무에 몰입하지 않거나 더 나은 환경을 찾아 떠날 것”이라고 진단했다.

경험 많은 CIO는 명령과 통제 방식을 지양하지만, 혁신을 달성하고 기한을 맞춰야 하는 압박 속에서 이를 피하기는 어려울 수 있다. 이런 압박에 굴복하는 대신, 다음과 같이 협력하는 접근 방식을 고려해야 한다.

경직된 배포 로드맵을 피하고, 집중할 가치가 있는 성과 개선 영역을 강조하며, 주요 릴리스 이후에는 팀이 재정비할 시간을 제공함으로써 애자일 팀에게 권한을 부여하고 영감을 불어넣는다.
팀이 릴리스 약속을 얼마나 잘 이행하는지, 설계 동료 검토를 얼마나 장려하는지, 그리고 실험의 영향을 어떻게 입증하는지를 통해 소프트웨어 개발자의 영향력을 측정한다.
팀 리더, 엔터프라이즈 아키텍트, 제품 관리자가 모범 사례를 장려하고 설계 원칙을 수립하는 자체 표준 개발을 촉진한다.
의견을 구한 뒤 피드백 무시
CIO가 세세하게 관리하지 않더라도 IT 직원들은 리더가 자신의 피드백과 제안을 경청하지 않는다는 사실을 쉽게 알아차릴 수 있다.

텐엑스뉴코(10Xnewco)의 성장 전략가이자 임시 CIO인 조 푸글리시는 “‘당신의 의견이 중요하다’라는 생각을 철칙으로 삼고 있지만, 팀의 의욕을 꺾고 사기를 저하시키고 싶다면 의견을 구한 뒤 계속 무시하면 된다. 곧 직원들은 침묵하고 좌절하게 될 것”이라고 전했다.

CIO는 즉시는 아니더라도 의견과 피드백에 응답해 문화를 망치는 길을 피할 수 있다. 우수한 리더는 들은 내용을 다시 언급하고 관리 도구에 피드백을 기록한다. 이를 통해 리더는 옵션을 검토하고, 피드백이 변화를 이끌어낸 시점을 보여주며, 직원의 의견에 관심을 갖고 있음을 보여줄 수 있다.

하이브리드 근무 및 일과 삶의 균형 무너뜨리기
CIO가 IT 직원의 의견을 수렴해야 하는 분야 중 하나가 하이브리드 근무, 원격 근무 및 관련 정책이다. 일과 삶의 균형에 관한 직원의 목표와 회사 정책 간의 충돌, 또는 리더가 근무 원칙을 강요하면 IT 문화를 해칠 수 있다. 이런 갈등은 일과 삶의 균형을 우선순위로 꼽는 젊은 인력에게 특히 큰 영향을 미친다. 딜로이트의 ‘2024년 Z세대와 밀레니얼 세대’ 조사에 따르면 Z세대가 조직을 선택하는 3가지 주요 이유는 일과 삶의 균형, 학습과 발전 기회, 긍정적인 업무 문화였다.

시스코 콜라보레이션(Cisco Collaboration)의 SVP 겸 총괄 매니저인 아누라그 딩그라는 “인재는 모든 조직에 경쟁 우위를 제공하는 핵심 차별화 요소다. 리더는 직원에 집중해야 한다. 하이브리드 근무나 사무실 복귀 정책에 신중하지 않으면 일부 인재 계층을 소외시킬 수 있다. 직원들은 팀과 소통하고 창의적인 작업을 하고 싶을 때 사무실에 출근할 수 있기를 희망하지만, 동시에 집중이 필요한 업무 시간도 원한다”라고 말했다.

따라서 CIO는 인사 책임자와 협력해 직원 경험 개선을 주도해야 하며, 특히 IT 근무 환경이 다른 부서와는 차별화될 필요가 있는 경우라면 더 그렇다.

변화를 이끌 실용적 비전의 부재
커넥티드마인즈(Connektedminds)의 CEO이자 박사인 조앤 프리드먼은 “모든 혁신은 미래 지향적이며 디지털 비즈니스로서 달성하고자 하는 성과를 명확히 표현해야 한다”라고 말했다. 그는 “CIO는 큰 그림을 그리고, 세부 사항까지 리버스 엔지니어링하도록 팀을 이끈 다음, 이를 변화를 이끄는 실용적인 비전으로 다시 전달해야 한다”라고 조언했다.

프리드먼이 실용적 비전의 중요성을 강조하는 이유는 다음과 같다.

명확한 미션과 비전이 없으면 IT 팀은 자신들의 노력이 조직의 성과에 어떤 영향을 미치는지 알 수 없어 문화가 저해된다.
모호한 비전을 전달하면 팀이 조직의 목표를 추측해야 하고, 조직의 우선순위를 해석하는 과정에서 비효율이 발생한다.
지나치게 상세한 비전은 팀을 차선책에 가두고 혁신의 자유를 제한할 수 있다.
우수한 CIO는 IT 팀, 직원, 이해관계자, 경영진이 변화를 실험하고 추진하는 데 영감을 주는 혁신 비전의 일부로 IT를 재정립한다. 또한 이런 CIO는 IT 팀이 최종 사용자의 채택을 주도하고, 피드백을 수집하며, 솔루션을 꾸준히 개선하도록 이끌어 디지털 트랜스포메이션의 변화 관리 실수를 피한다.

과도한 약속과 보호받지 못하는 팀
혁신을 추구하는 CIO가 직면하는 주요 어려움은 더 많거나 큰 규모의 이니셔티브를 맡고 임박한 기한에 맞춰야 한다는 요구 사항이다. IT가 합리적으로 달성 가능한 수준 이상을 약속하는 것도 문제지만, 이해관계자들이 좌절하거나 경영진이 진행을 방해할 때 CIO가 프로그램 리더를 무방비 상태로 방치하는 것도 IT 문화를 망치는 길이다.

듀넬름 어소시에이츠(Dunelm Associates)의 매니징 파트너인 마틴 데이비스는 “IT 팀 역량과 관계없이 모든 비즈니스 요청에 CIO가 동의하고 IT 전략이나 방향성이 부족할 때 IT 사기가 저하된다. 하지만 실망하거나 화를 내는 비즈니스 고위 경영진과 이해관계자로부터 팀을 보호하지 않을 때 IT 문화는 완전히 파괴된다”라고 지적했다.

디지털 트랜스포메이션을 이끄는 뛰어난 CIO는 전략적인 우선순위에 대한 합의를 이끌어내고 추가 이니셔티브를 수행할 역량을 전달해 우선순위를 정한다. 모든 혁신 이니셔티브에는 디지털 리더십이 필요하다. 뛰어난 CIO는 더 큰 범위의 이니셔티브를 성공으로 이끌려면 디지털 트랜스포메이션을 주도할 인재 풀을 늘려야 한다는 사실을 알고 있다.

CIO는 혁신 리더와 팀이 화가 나거나 실망한 이해관계자 및 경영진을 혼자 상대하도록 방치해선 안 된다. 뛰어난 CIO는 어떤 변화가 필요한지 논의하고 되돌아보는 토론에 직접 참여한 다음, 혁신 리더가 비즈니스 이해관계자와 의미 있는 관계를 발전시키는 데 도움을 줄 방법을 고려한다.

이해관계자가 받아들이지 않는 애자일 문화 추진
회고(Retrospectives)는 애자일 스프린트 종료 시 팀이 성과와 개선 기회를 논의하기 위해 사용하는 의식과 같다. 실망하거나 화가 난 이해관계자가 있을 때는 대개 애자일에서 이해관계자의 역할, 제품 관리의 책임, 애자일 팀이 인식하는 성과 사이에 단절이 발생한 경우가 많다.

많은 CIO가 기술 구현 조직에 애자일 방법론을 도입했지만, 이는 “정시에, 범위 및 예산 내에서, 품질을 갖추는” 전통적인 프로젝트 관리 약속을 요구하는 이해관계자들의 생각과는 상당한 격차가 있을 수 있다. 디지털AI(digital.ai)의 17차 애자일 현황 보고서에 따르면, 설문 응답자의 약 절반(47%)은 비즈니스 부서에서 애자일을 채택하지 않는 이유로 조직 변화에 대한 ‘일반화된’ 반감이나 ‘문화 충돌’을 지적했다.

이해관계자 교육 없이 IT의 애자일 도입을 추진하면 문화를 해칠 수 있다. 변화 관리에 대한 책임이 팀에 전가되기 떄문이다. 애자일팀에게 이해관계자의 애자일 실천 방안 조율을 요구하면, 특히 팀이 조직의 변화 관리 문제를 다루는 데 숙련되지 않은 경우 생산성이 저하된다. 따라서 CIO는 애자일 관행 및 기타 디지털 트랜스포메이션 역량의 이유와 방법을 이해관계자에게 교육하는 조치를 취해야 한다.

전환과 전략 변화에 대한 소통 실패
CIO의 소통 문제도 IT팀의 문화 장벽이 될 수 있다. 경영진이 우선순위를 전환하거나 주요 조직 개편을 발표할 때, CIO는 포럼을 열고 변경 사항을 전달해 유대를 다져야 한다. 원래 목표를 향해 열심히 일하던 IT팀은 변화가 일어나고 조직이 우선순위를 재설정한 이유에 의문을 가질 수 있다.

클라리오의 페로는 “CIO가 의도치 않게 의사 결정 ‘이유’를 소통하지 못한다면 IT 문화를 해칠 수 있다. 팀의 의견을 수렴하거나 투명성 없이 변화가 이뤄지면 불확실성과 분노가 생긴다. 신뢰와 협력에 기반한 문화를 구축하려면 CIO가 열린 대화를 촉진하고 팀이 회사의 더 큰 비전을 이해하고 조율할 수 있도록 지원해야 한다”라고 설명했다.

뛰어난 CIO는 소통 전략을 세우고 팀과 정기적으로 대화를 계획한다. 팀이 피드백과 아이디어를 공유하도록 적극 경청하는 자세가 필요하다. 회사의 전략 방향에 대한 업데이트가 있을 때는 소식을 전하고 질문에 답할 포럼을 마련해야 한다.

기술 전문 용어의 과다 사용으로 신뢰도 하락
보안 개선, 인프라 업그레이드 또는 기술 부채 감소를 위해 경영진과 이사회를 설득하고 투자를 이끌어내지 못하는 CIO는 해당 업무로 매일 문제를 겪는 IT 직원의 사기를 떨어뜨릴 수 있다. CIO는 혁신 리더들을 멘토링할 때 모범을 보여야 한다. 특히 대규모 투자 제안을 준비하는 과정에서는 전문 기술 용어 사용을 자제하고, 경영진이 이해하기 쉬운 언어로 설명해야 한다. 이를 통해 의사결정권자들이 비즈니스상 필요성을 명확히 이해할 수 있도록 해야 한다.

페이저듀티(PagerDuty)의 CIO인 에릭 존슨은 “CIO는 이사회 및 경영진과 소통할 때 기술 용어를 남발하는 실수를 자주 저지른다. CIO는 기술 개념을 비즈니스 성과로 표현해야 하며, IT와 기술팀의 중요 업무가 조직 내 다른 업무와 분리되지 않도록 해야 한다”라고 조언했다.

CIO는 이사회 회의에서 질문에 복잡하게 답변하거나 보안 투자를 설득할 때 공포를 유발하는 전술을 사용하는 등의 실수를 할 수 있다. 잘못된 소통은 신뢰도를 손상시키며 IT문화에 파급 효과를 가져올 수 있다.

존슨은 “소통 격차는 혁신을 저해할 뿐만 아니라 IT 이니셔티브와 더 넓은 비즈니스 목표 간 불일치를 초래한다. 이는 IT 문화를 약화시키고 기술을 진정한 비즈니스 혁신 동력으로 자리매김할 기회를 놓치게 할 수 있다”라고 말했다.

팀과 개인의 저조한 성과 용인
듀넬름 어소시에이츠의 데이비스는 “팀 분위기를 심각하게 저해하는 핵심 구성원에 대해 적절한 조치를 취하지 않는 것”이 문화를 해치는 주요 요인이라고 지적했다. 이는 다른 CIO들도 언급한 요인인데, 혼란과 저성과가 팀에 영향을 미치고 CIO의 우유부단한 대응이 신뢰를 손상시키기 때문이다.

클라리오의 페로는 “IT 문화를 해치는 해로운 주요 원인이 저성과자를 너무 오래 붙잡아두는 것이다. 낮은 기준이 용인될 때 고성과자들의 동기 부여는 약화되고 분노로 이어진다. CIO는 개선을 위해 필요한 지원을 제공하되, 전반적인 팀 분위기를 유지하기 위해 때로는 결단을 내릴 시점을 알아야 한다”라고 말했다.

저성과 관리 권장 사항에는 신속한 조치, 변경할 사항 명료화, 측정 가능한 개선 계획 수립, 성과 기준에 대해 팀과 소통하는 방법 등이 있다. CIO는 또한 성과 개선 계획을 관리할 절차를 인사 담당자와 상의해야 한다.

실수에 대한 책임 전가와 공로 독점
텐엑스뉴코의 퓰리시는 “공은 독차지하면서 실수는 팀원을 공개 지목하는 행위가 팀의 사기를 쉽게 꺾는다”라고 말했다.

중요한 교훈은 CIO가 팀 중심 접근 방식으로 리더십을 발휘해야 한다는 점이다. 문제에 대응하고, 최종 사용자 요청을 처리하고, 조직 보안 태세를 개선하고, 혁신을 제공하고, 디지털 트랜스포메이션을 주도하는 것이 바로 팀이다. CIO에게는 의욕적이고 꾸준히 발전하는 팀이 필요하다. 올바른 IT 문화를 구축하려면 실험하고 학습하며 성과를 내려는 열정을 조성해야 한다.

https://www.cio.com/article/3604847/%ec%82%ac%ea%b8%b0-%ec%a0%80%ed%95%98-%ec%8b%a0%eb%a2%b0%eb%8f%84-%ec%83%81%ec%8b%a4%c2%b7%c2%b7%c2%b7-it-%eb%ac%b8%ed%99%94%eb%a5%bc-%eb%a7%9d%ec%b9%98%eb%8a%94-%ea%b8%b8-10.html

 

‘사기 저하, 신뢰도 상실’··· IT 문화를 망치는 행동 10가지

세세한 참견부터 실용적 비전 부재에 이르기까지, IT 리더는 비즈니스 성과를 창출할 IT 문화 조성에 의도치 않게 악영향을 미칠 수 있다.

www.cio.com

 

 

반응형
반응형

 

입력받은 url을 다운로드 받고, MP3로 변환하고 싶으면 변환버튼.

다운 받은 파일 리스트 페이지 에서 파일 더블 클릭시 실행.

 

 

 

 

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit, QScrollArea, QMessageBox
import yt_dlp
import threading
from moviepy.editor import AudioFileClip
 

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # 윈도우 설정
        self.setWindowTitle("YouTube Downloader & MP4 to MP3 Converter")
        self.setGeometry(300, 300, 600, 400)

        # 메인 레이아웃 설정
        self.main_layout = QVBoxLayout()

        # 버튼 레이아웃 (좌에서 우로 배치)
        button_layout = QHBoxLayout()

        # 버튼 1: YouTube URL 다운로드 버튼
        self.youtube_button = QPushButton("Download YouTube Video", self)
        self.youtube_button.clicked.connect(self.show_youtube_download_form)
        button_layout.addWidget(self.youtube_button)

        # 버튼 2: MP4 to MP3 변환 버튼
        self.convert_button = QPushButton("Convert MP4 to MP3", self)
        self.convert_button.clicked.connect(self.confirm_convert_form)  # 확인 창 함수 연결
        button_layout.addWidget(self.convert_button) 

        # 버튼 3: Downloads 폴더의 파일 리스트 보기 버튼
        self.show_files_button = QPushButton("Show Downloaded Files", self)
        self.show_files_button.clicked.connect(self.show_downloaded_files)
        button_layout.addWidget(self.show_files_button)

        # 버튼 레이아웃 추가
        self.main_layout.addLayout(button_layout)

        # YouTube URL 입력 필드 (초기에는 숨김)
        self.url_input = QLineEdit(self)
        self.url_input.setPlaceholderText("Enter YouTube URL here...")
        self.url_input.setVisible(False)  # 초기에는 숨김
        self.main_layout.addWidget(self.url_input)

        # 상태 및 결과 표시 레이블 (스크롤 가능)
        self.result_label = QLabel(self)
        self.result_label.setWordWrap(True)
        
        scroll_area = QScrollArea(self)
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(self.result_label)
        self.main_layout.addWidget(scroll_area)

        # 메인 레이아웃 설정
        self.setLayout(self.main_layout)

    def show_youtube_download_form(self):
        # 입력 필드가 이미 있는지 확인 후 없을 때만 추가
        # 입력 필드를 보이도록 설정하고, 플레이스홀더 텍스트 설정
        self.url_input.setVisible(True)
        self.url_input.setPlaceholderText("Enter YouTube URL here...")
        self.url_input.clear()  # 이전 입력값 지우기
        self.result_label.setText("Enter a YouTube URL to download:") 

    def download_video(self):
        url = self.url_input.text().strip()
        if url:
            self.result_label.setText("Downloading... Please wait.")
            threading.Thread(target=self.youtube_download_process, args=(url,)).start()
        else:
            self.result_label.setText("Please enter a valid YouTube URL.")

    def youtube_download_process(self, url):
        ydl_opts = {
            'format': 'best',
            'outtmpl': './downloads/%(title)s.%(ext)s',
            'progress_hooks': [self.progress_hook]
        }
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])

    def progress_hook(self, d):
        if d['status'] == 'downloading':
            percent = d['_percent_str']
            speed = d.get('speed', 'Unknown')
            eta = d.get('eta', 'Unknown')
            self.result_label.setText(f"Downloading: {percent} - Speed: {speed} - ETA: {eta}s")
        elif d['status'] == 'finished':
            self.result_label.setText(f"Download complete!")

    def confirm_convert_form(self):
        # 확인/취소 메시지 박스를 생성
        reply = QMessageBox.question(self, 'Convert MP4 to MP3',
                                     "Are you sure you want to convert all MP4 files in the folder to MP3?",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

        # 사용자가 Yes를 선택한 경우에만 변환 함수 실행
        if reply == QMessageBox.Yes:
            self.show_convert_form()

    def show_convert_form(self):
        # URL 입력창 숨김
        self.url_input.setVisible(False)
        
        # MP4 파일 선택 및 MP3로 변환 메시지 설정
        self.result_label.setText("Converting all MP4 files in the folder to MP3...")
        threading.Thread(target=self.convert_mp4_to_mp3).start()

    def convert_mp4_to_mp3(self):
        folder_path = './downloads'  # MP4 파일이 있는 폴더
         

        for filename in os.listdir(folder_path):
            if filename.endswith(".mp4"):
                mp4_path = os.path.join(folder_path, filename)
                mp3_path = os.path.join(folder_path, f"{os.path.splitext(filename)[0]}.mp3")
                
                if os.path.exists(mp3_path):
                    self.result_label.setText(self.result_label.text() + f"\nSkipping {filename}: MP3 already exists.")
                    continue

                audio_clip = AudioFileClip(mp4_path)
                audio_clip.write_audiofile(mp3_path)
                audio_clip.close()
                self.result_label.setText(self.result_label.text() + f"\nConverted: {filename} to MP3.")

        self.result_label.setText(self.result_label.text() + "\nAll MP4 files converted to MP3.")

    def show_downloaded_files(self):
        # URL 입력창 숨김
        self.url_input.setVisible(False)
        
        # ./downloads 폴더의 파일 리스트를 표시
        folder_path = './downloads'
        if not os.path.exists(folder_path):
            self.result_label.setText("No files found. The downloads folder does not exist.")
            return

        files = os.listdir(folder_path)
        if files:
            file_list = "\n".join(files)
            self.result_label.setText(f"Files in {folder_path}:\n{file_list}")
        else:
            self.result_label.setText("No files found in the downloads folder.")



# PyQt 애플리케이션 실행
if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())
반응형
반응형

[python]  폴더 안의 모든 mp4 파일을 mp3로 변환하기

 

 

import os
from pathlib import Path
 

from moviepy.editor import *

# MP4 파일이 있는 폴더 경로 지정
folder_path = './downloads'

import file_rename_underbar as fru

# 폴더내의 파일명 rename
fru.replace_spaces_in_filenames(folder_path)


# 폴더 내의 모든 파일 확인
for filename in os.listdir(folder_path):
    if filename.endswith('.mp4'):
        mp4_path = os.path.join(folder_path, filename)
        mp3_path = os.path.join(folder_path, filename.replace('.mp4', '.mp3'))
        
        # 비디오에서 오디오 추출 후 MP3로 저장
        video = VideoFileClip(mp4_path)
        video.audio.write_audiofile(mp3_path)
        video.close()  # 명시적으로 close 호출하여 자원 해제

        print(f"Converted: {filename} to MP3")
    else:
        print(f"Converted Not: {filename} to MP3")

 

 

 

 

반응형
반응형

[python] youtube download 입력받은 url로 다운받기

 

yt-dlp는 YouTube 및 기타 비디오 플랫폼에서 동영상을 다운로드하는 강력한 명령줄 도구입니다. 

pytube보다 다양한 기능을 제공하며, Python 스크립트와 통합하여 사용할 수도 있습니다.

import yt_dlp

def main():
    # 다운로드할 YouTube 비디오의 URL
    #url = 'https://www.youtube.com/watch?v=vjcuQLjSUz4'
    
    
    # 사용자로부터 YouTube 비디오 URL 입력받기
    url = input("다운로드할 YouTube 비디오의 URL을 입력하세요: ")

    # 다운로드 옵션 설정
    ydl_opts = {
        'format': 'best',                   # 최고 화질 선택 (audio와 video 포함)
        'outtmpl': './downloads/%(title)s.%(ext)s',  # 다운로드 파일 경로 및 이름 템플릿
    }

    # yt-dlp를 사용하여 다운로드
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.download([url])

    print("Video has been downloaded successfully!")


# 메인 함수 호출
if __name__ == "__main__":
    main()

 

반응형

+ Recent posts