서울시가 취약계층 유아에게 양질의 온라인 콘텐츠를 제공하는 ‘서울런 키즈’ 사업을 내년 1년간 시범 운영한다.
서울시 대표 복지 사업인 ‘서울런’을 이용할 수 있는 대상이 취약계층 만 4~5세 유아까지 확대됩니다. 2025년부터 시범운영할 ‘서울런 키즈’는 취약계층 유아의 건강한 발달을 돕기 위해 서울시가 민간업체 6곳과 협력해 제공합니다. 선발된 대상자에게는 양질의 온라인 콘텐츠, 기기, 교재 등이 무료로 지원됩니다. 해당 사업의 지원대상, 모집인원, 신청방법, 선발일정 등을 자세히 알아봅니다.
서울시가 취약계층 만4~5세 유아에게 창의력, 사고력 등을 촉진하는 양질의 온라인 콘텐츠를 제공해 건강한 정서적·신체적 발달을 돕는‘서울런 키즈’ 사업을내년 1년간 시범 운영한다.
서울시는 6개 민간업체(단비교육, 메가스터디교육, 아이스크림에듀, 에누마, 웅진씽크빅, 천재교과서)와 ‘서울런 키즈’ 업무협약을 체결했다. 11월 18일 업무협약식에는 서울시 평생교육국장, 주식회사 케이티(KT), 6개 업체 본부장 등 8명이 참석했다.
취약계층 유아에게 양질의 콘텐츠를 제공해야 할 필요성에 공감한 민간업체의 시범사업 참여로, 서울시에 거주하는 중위소득 60% 이하 가구의 만 4~5세 유아는 내년 1월부터 1년간 6개 민간업체의 유아 맞춤형 온라인 콘텐츠(총 약 10만 개), 기기, 교재 등을 무상으로 지원받는다.
‘서울런 키즈’에 제공되는 온라인 콘텐츠
시범사업에는리틀홈런(아이스크림에듀), 밀크T아이(천재교과서), 스마트올 키즈(웅진씽크빅), 엘리하이키즈(메가스터디교육), 윙크(단비교육), 토도원(에누마) 등의 콘텐츠가 제공된다.
‘서울런 키즈’ 온라인 콘텐츠 예시
콘텐츠 주요 내용으로는 ▲다양한 주제의 동화책을 읽고 한글 익히기 ▲동요를 따라 부르며 몸 움직이기 ▲기본생활 습관 실천하기 ▲영미권 유명 동화책을 통해 재미있게 영어와 친해지기 등이 있다.
참여를 희망하는 가구는 11월 22일부터 12월 6일까지서울런 누리집을 통해 신청할 수 있다. 자격요건을 갖춘 신청인원이 모집인원인 500여 명보다 많은 경우 선착순으로 선발한다.
중위소득 50% 이하 가구는 별도의 서류 준비 없이 누리집에서 실시간 온라인 자격 검증 서비스를 통해 신청할 수 있다. 중위소득 50% 초과 60% 이하 가구는 ①사회보장급여 결정통지서 또는 ②건강보험료 납부확인서, 건강보험 자격확인서, 주민등록등본 중 하나를 제출해야 한다. 문의 사항은서울런 학습지원센터를 이용하면 된다.
‘서울런 키즈’ 선발일정
참여 신청
➜
대상자 선정 발표
➜
콘텐츠 선택
➜
서비스 시작
11.22.~12.6.
12.16. ※변동가능
12.18.~12.20.
2025.1.~
한편 시는 추후 ‘서울런 키즈’ 시범사업의 단기 특화 프로그램으로 YBM넷의 온라인 영어도서관 연계 화상영어 수업인 ‘YBM 영어동화놀이터’ 대상자도 별도 모집해 서비스할 예정이다. 해당 서비스는 아이의 발달 과정과 선호도에 맞춰 애니메이션 동화 학습 후 화상으로 선생님과 수업하는 형식으로 진행된다.
구종원 평생교육국장은 “‘서울런 키즈’ 사업은 유해 미디어의 범람 속에서 아이들이 건강하게 자라날 수 있도록 유익한 미디어 환경을 제공하기 위해 출발했다”라며, “이번 시범사업이 성공적으로 자리 잡아 앞으로 더 많은 아이들에게 안전하고, 질 높은 미디어 학습 기회를 제공하게 되기를 바란다”라고 말했다.
‘서울런 키즈’ 모집안내
○ 지원대상 : 만 4~5세 유아(서울시 거주 중위소득 60% 이하) ※ 시범사업 기간(2025.1.~12.) 기준으로 출생일이 2020.1.1.~2021.12.31.에 해당하는 자 ○ 모집인원 : 500여명 ※ 신청 기간 중 신청인원이 모집인원을 초과할 경우 접수 선착순으로 선발 ○ 신청방법 :서울런 누리집 공지사항을 통해 신청 ○ 시범운영 : 2025.1.~12. (1년) ○ 제공혜택 : 6개 교육업체 중 선택한 1개 교육업체의 온라인 콘텐츠, 기기 등 무상 지원 ○ 교육업체 : 아이스크림에듀, 천재교과서, 웅진씽크빅, 메가스터디교육, 단비교육, 에누마 등 6개 업체 ○ 누리집 :서울런 ○ 문의 : 서울런 학습지원센터 1533-0909
This article explains the new features inPython 3.13, compared to3.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 ofperformance improvements. For full details, see thechangelog.
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 newinteractive interpreter, experimental support for running in afree-threaded mode(PEP 703), and aJust-In-Time compiler(PEP 744).
Error messages continue to improve, with tracebacks now highlighted in color by default. Thelocals()builtin now hasdefined semanticsfor 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 nowbeen removedfollowing 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 newinteractiveshell by default, based on code from thePyPy project. When the user starts theREPLfrom 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.
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 theglobal 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 asfree-threadedcan be installed as part of the officialWindowsandmacOSinstallers, or CPython can be built from source with the— disable-giloption.
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 informationare contained atTools/jit/README.md.
Improved Error Messages
The interpreter now uses color by default when displaying tracebacks in the terminal. This featurecan be controlledvia the newPYTHON_COLORSenvironment variable as well as the canonicalNO_COLORandFORCE_COLORenvironment variables. (Contributed by Pablo Galindo Salgado ingh-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 newreplace()function and thereplace protocolmake creating modified copies of objects much simpler. This is especially useful when working with immutable objects. The following types support thereplace()function and implement the replace protocol:
PEP 730: iOS is now aPEP 11supported 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 ingh-114099.)
PEP 738: Android is now aPEP 11supported 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 ingh-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 문화를 구축하려면 실험하고 학습하며 성과를 내려는 열정을 조성해야 한다.
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_())