레이블이 파이썬인 게시물을 표시합니다. 모든 게시물 표시
레이블이 파이썬인 게시물을 표시합니다. 모든 게시물 표시

2018년 10월 19일 금요일

Python IDLE 실행 오류 해결

번역 중인 책 <Beginning Blockchain>의 해시 함수 예제를 테스트해보려고 Python 2.7 IDLE를 켰는데, Run Module 메뉴를 선택하니  Subprocess Startup Error가 발생했다.


기존에 설치된 2.7.14를 제거하고 2.7.15를 설치해봤지만 이 문제는 해결되지 않았다. 그래서 다음과 같이 Windows Defender의 방화벽 설정을 추가했다.


  • 제어판 - 시스템 및 보안 - Windows Defender 방화벽 - 허용되는 앱
  • 설정 변경 버튼 클릭
  • 다른 앱 허용 버튼 클릭
  • pythonw.exe 경로를 선택해 추가



이제 잘 된다.


2017년 10월 13일 금요일

Windows 10에 Python 2.7 설치 시 DLL 오류 해결 방법

윈도우 10에 파이썬 2.7을 설치할 때, 설치에 필요한 DLL 파일을 실행할 수 없다는 메시지가 뜨며 실패하는 경우의 해결 방법을 설명한다.




윈도우 탐색기의 메뉴에서 보기 --> 옵션을 선택하고 <폴더 옵션> 창의 <보기> 탭에서 <숨김 파일, 폴더 및 드라이브 표시> 항목을 체크하고 <확인> 버튼을 클릭한다.



탐색기에서 사용자의 홈 폴더 아래의 AppData\Local로 이동하고, Temp 폴더를 오른쪽 클릭하여 <속성>을 선택하면 <Temp 속성> 창이 뜬다. <보안> 탭으로 이동한다.


<편집> 버튼을 클릭하고, Everyone에 대하여 <모든 권한>의 <허용>에 체크한다. <보안 적용 오류> 메시지가 뜨면 <취소> 버튼을 클릭한다.


이제 파이썬 인스톨러를 다시 실행한다.

참고

2017년 8월 11일 금요일

Python에서 Switch Case

Python 언어에는 switch case 구문이 없다. 그와 관련한 질문이 올라온 것을 보고 궁금증이 생겨서 찾아보았다.

Proposal


집어 넣으려는 시도가 없지는 않았으나, 필요하지 않다고 생각하는 사람이 많은 모양이다.

DSL


꼭 필요하다면 Domain Specific Language를 만들 수도 있지 않을까하는 생각이 들긴 했지만, 너무 멀리 나가는 것 같다.


Package


혹시나 해서 찾아보니, 역시나 패키지가 있다.
간단히 테스트해보았다.

% pip3 install switch
% python3
>>> from switch import Switch
>>> x = 1
>>> with Switch(x) as case:
...     if case(1):
...         print('일')
...     if case(2):
...         print('이')
... 
일

2016년 2월 25일 목요일

웹 브라우저에서 Raspberry Pi 조작하기

스터디의 이번 과제는, 웹브라우저에서 Raspberry Pi의 주소로 접근하여 텍스트필드에 문자열을 입력하면, 그 문자열을 PiFaceCAD에 출력하는 것이었다. 서버는 node.js를 사용하여 구현하기로 했다.

node.js의 웹프레임워크인 express 모듈을 사용했고, PiFaceCAD를 다루는 Python 코드를 호출하기 위해 child_process 모듈을 사용했다.

server.js

var express = require('express');
var app = express();

app.use(express.static('public'));

app.get('/', function (req, res) {
   res.sendFile( __dirname + "/" + "form.html" );
})

app.get('/lcd_write', function (req, res) {
   text = "\"" + req.query.text + "\""
   var exec = require('child_process').exec;
   function puts(error, stdout, stderr) { console.log(stdout) }
   cmd = "python3 -c \"import sys, pifacecad; pifacecad.PiFaceCAD().lcd.write(sys.argv[1])\""
   exec(cmd + " " + text, puts);
   console.log(text);
   res.end(text);
})

var server = app.listen(8000, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("Example app listening at http://%s:%s", host, port)

})

form.html

<html>
<body>
<form action="/lcd_write" method="GET">
Input text here: <input type="text" name="text">  <br>
<input type="submit" value="Submit">
</form>
</body>
</html>


2016년 2월 14일 일요일

Raspberry Pi MP3 Player

Raspberry Pi와 PiFaceCAD를 사용하여 MP3 플레이어를 만들어보았다. 이것도 역시 스터디 숙제. 음악 파일의 재생을 위해 pygame.mixerpygame.mixer.music을 사용했다.



소스 코드:

#!/usr/bin/python3

from pygame import mixer
import time

class Player:
    def __init__(self):
        self.isOn = True
        self.isPlaying = False
        self.isPaused = False

        show("MP3 Player")
        mixer.init()
        self.musicVolume = round(mixer.music.get_volume(), 1)
        import glob
        self.musicFiles = tuple(sorted(glob.glob("*.mp3")))
        self.musicNum = 0
        filename = self.musicFiles[self.musicNum]
        show(filename + "\nReady")

    def listen(self, sw_id, func, always=False):
        if cad.switches[sw_id].value == 1 and (always or self.isOn):
            while cad.switches[sw_id].value == 1: pass
            print('self.%s()' % func)
            exec('self.%s()' % func)

    def playPause(self):
        if self.isPlaying:
            self.pause()
        else:
            if self.isPaused:
                self.resume()
            else:
                self.play()

    def play(self):
        filename = self.musicFiles[self.musicNum]
        mixer.music.load(filename)
        self.musicTitle = filename
        show(self.musicTitle + "\nPlaying")
        mixer.music.play()
        self.isPlaying = True

    def pause(self):
        self.isPlaying = False
        mixer.music.pause()
        show(self.musicTitle + "\nPaused")
        self.isPaused = True

    def resume(self):
        self.isPlaying = True
        show(self.musicTitle + "\nPlaying")
        mixer.music.unpause()
        self.isPaused = False

    def prev(self):
        self.musicNum = (self.musicNum - 1) % len(self.musicFiles)
        self.play()

    def next(self):
        self.musicNum = (self.musicNum + 1) % len(self.musicFiles)
        self.play()

    def randomPlay(self):
        import random
        self.musicNum = random.choice(range(len(self.musicFiles)))
        self.play()

    def volumeUp(self):
        self.setVolume("up")

    def volumeDown(self):
        self.setVolume("down")

    def setVolume(self, action):
        min, max, delta = 0.0, 1.0, 0.1
        vol = mixer.music.get_volume()
        vol = round(vol, 1)

        if action is "up" and vol < max:
            vol = round(vol + delta, 1)
            mixer.music.set_volume(vol)
            show(self.musicTitle + "\nvol: " + str(vol))
            self.musicVolume = vol
        elif action is "down" and vol > min:
            vol = round(vol - delta, 1)
            mixer.music.set_volume(vol)
            show(self.musicTitle + "\nvol: " + str(vol))
            self.musicVolume = vol
        elif action is "mute":
            if vol == min:
                vol = self.musicVolume
                mixer.music.set_volume(vol)
                show(self.musicTitle + "\nvol: " + str(vol))
            else:
                vol = min
                mixer.music.set_volume(vol)
                show(self.musicTitle + "\nMuted")
        else:
            pass

    def mute(self):
        self.setVolume("mute")

    def onOff(self):
        if self.isOn:
            if self.isPlaying:
                mixer.music.stop()
            show('Bye...')
            time.sleep(2)
            cad.lcd.backlight_off()
            time.sleep(1)
            cad.lcd.clear()
            self.isOn = False
        else:
            self.__init__()

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()
cad.lcd.cursor_off()
cad.lcd.blink_off()

def show(text):
    cad.lcd.clear()
    cad.lcd.write(text)

p = Player()

while True:
    p.listen(0, 'playPause')
    p.listen(1, 'prev')
    p.listen(2, 'next')
    p.listen(3, 'randomPlay')
    p.listen(4, 'onOff', True)
    p.listen(5, 'mute')
    p.listen(6, 'volumeDown')
    p.listen(7, 'volumeUp')

2016년 2월 10일 수요일

PiFaceCAD

올해 초부터 우분투 한국 사용자모임에서 시작한 Raspberry Pi 스터디에 매주 나가고 있다. Pi에서 node.js를 구동하여 웹을 통해 이런저런 장치를 제어하는 것을 목표로 하는데, 작업의 편의를 위해 PiFaceCAD(PiFace Control and Display)라는 제품을 구입해서 사용하기로 했다. 들고다니다가 망가뜨리지 않을까 걱정이 되어, Raspberry Pi에 PiFaceCAD를 꽂은 채로 넣을 수 있는 케이스도 함께 샀다.

PiFaceCAD에 친숙해지기 위해 Python으로 스코어보드를 만들어보는 숙제가 있었다. LCD에 두 팀의 점수를 보여주는 기능을 하며, 각 팀의 점수를 올리기 위한 스위치 한 개 씩과, 점수를 리셋하는 용도의 스위치 한 개를 사용한다.


위의 영상과 같이 동작하며, 내가 짠 코드는 다음과 같다. (먼저 셋업이 필요하다)

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

score = [0, 0]
show()

while True:
    if cad.switches[0].value == 1:
        score[0] = score[0] + 1
        while cad.switches[0].value == 1: pass
        show()
    elif cad.switches[1].value == 1:
        score[1] = score[1] + 1
        while cad.switches[1].value == 1: pass
        show()
    elif cad.switches[4].value == 1:
        score = [0, 0]
        while cad.switches[4].value == 1: pass
        show()

스위치를 한 번 누르는 동안 여러 점이 올라가는 것을 막기 위해, 손을 뗄 때까지 pass시키는 작은 while 문을 넣었다. 다른 사람들은 time.sleep()을 사용해서 처리했다. 이때, 일반적으로 0.25 초 정도의 sleep이 적당하다고 한다.

작성해놓고 보니 while 블록에서 중복으로 나타나는 것들을 정리하고 싶어져서 아래와 같이 바꾸었다.

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

def listen(i, func):
    global score
    if cad.switches[i].value == 1:
        if func == 'add': score[i] = score[i] + 1
        elif func == 'reset': score = [0, 0]
        while cad.switches[i].value == 1: pass
        show()

score = [0, 0]
show()

while True:
    listen(0, 'add')
    listen(1, 'add')
    listen(4, 'reset')

다음의 코드는, 위쪽에 붙은 로커 스위치를 테스트해보기 위해 수정한 버전이다.

#!/usr/bin/python3

import pifacecad

cad = pifacecad.PiFaceCAD()
cad.lcd.backlight_on()

def show():
    cad.lcd.clear()
    cad.lcd.write('A team:' + str(score[0]) + '\n'
                  + 'B team:' + str(score[1]))

def listen(i, func, team=None):
    global score
    if cad.switches[i].value == 1:
        if func == 'add': score[team] = score[team] + 1
        elif func == 'reset': score = [0, 0]
        while cad.switches[i].value == 1: pass
        show()

score = [0, 0]
show()

while True:
    listen(5, 'reset')
    listen(6, 'add', 0)
    listen(7, 'add', 1)

2016년 2월 3일 수요일

PyAudio

앞의 글에서는 Raspberry Pi에 USB 마이크를 연결하고 arecord와 aplay 명령을 사용하여 소리의 녹음과 재생을 해보았는데, 이번에는 같은 일을 Python에서 시도해 보았다. 사용한 라이브러리는 PyAudio라는 것으로, PortAudio의 Python 바인딩이다.


PyAudio 설치


다음의 명령으로 라이브러리를 설치한다.

$ sudo apt-get install python-pyaudio


Wav 파일 재생


PyAudio 홈페이지에 소개된, wav 파일을 재생하는 예제를 실행해보았다.
http://people.csail.mit.edu/hubert/pyaudio/#play-wave-example

경고 메시지가 많이 뜨긴 하지만 일단 무시했다. 소리가 많이 끊어져 들렸는데, CHUNK 값을 2048로 조정하니 조금 좋아졌지만 여전히 끊기는 듯한 느낌이 든다.


Wav 파일 녹음


이번에는 소리를 wav 파일로 녹음하는 예제를 실행해보았다.
http://people.csail.mit.edu/hubert/pyaudio/#record-example

IOError 메시지가 떴는데, 역시 CHUNK 값을 조정하여 해결했다. 이번에는 4096으로 설정. 그리고, 모노 마이크를 사용하기 때문에 CHANNELS = 1로 설정했다.

2015년 7월 30일 목요일

Python 종강

뜻하지 않게 학교에서 Python을 강의할 기회가 주어져서 강의 자료를 만들고 수업을 하며 한 달 여를 보냈다. 정규 과목에는 Python이 없지만 방학 특강을 통해 학생들에게 소개하고자 수업을 구상하고 강사를 찾던 학부장님과 출판사를 통해 이어진 것이다.

잘 해낼 수 있을지 걱정이 되었지만 흔치 않은 기회를 놓치고 싶지 않았기에 덤벼들었다. 덕분에 수업 준비에 많은 시간을 쏟았고, 그 와중에 꼭 필요하지도 않은 맥북을 구입하고 스타벅스에서도 돈을 많이 썼다. 내가 알고 있는 것을 다른 사람에게 설명하고 글로 풀어내는 것과는 또 다른 것이 바로 수업자료 만들기였다.

준비가 된 상태에서 수업에 임하는 것은 힘들지 않고 재미있고 보람 있었다. 학생들 앞에서 떨지나 않을까 걱정도 했지만, 전혀 그렇지 않았다. 하지만 제대로 공부하지 않고 섣부르거나 잘못된 말을 했을 때 학생들이 나를 어떻게 생각할 지에 대해선 신경이 쓰였고, 정신을 차리게 하는 채찍 역할을 했다.

강의 자료를 처음엔 종이에 출력했다가 슬라이드셰어에 올려서 공유하는 것으로 바꾸었다. 종이도 아끼고 편리하지만, 불특정 다수의 리뷰를 받는 셈이라 어설픈 내용으로 나쁜 이미지를 얻지 않기 위해 신경을 더 써야했다. 그리고 나눔고딕코딩 글꼴로 작성한 부분이 슬라이드셰어에서는 다른 폰트로 대체되어버리기 때문에 추가적인 손질이 필요했다.

http://slideshare.net/sk8erchoi/

2015년 7월 20일 월요일

Python 강의

전에 책을 내었던 출판사를 통해 한 전문대학과 인연이 되어 방학 동안의 특강을 맡게 되었다. 2주 동안 Python에 대한 수업을 하는데, 그 중에서 1주일은 학교 교수님이, 나머지 1주일은 내가 수업을 하기로 했다. 지난 주에 개강을 했고, 모레부터는 내 차례이다.

내 책을 교재로 채택하기는 했지만 수업을 위한 슬라이드는 책을 요약하지 않고 인터넷의 자료를 찾아가면서 완전히 새로 만들었다. 지난 한 달 동안 많은 시간을 들였다(덕분에 스타벅스의 매상도 약간 올라갔을 것이다). 직장을 다니고 있었다면 그만큼 시간을 투자하기가 쉽지 않았을 것이다.

수업 시간만 따지면 벌이가 나쁘지 않지만, 준비에 몇 배의 시간이 들어갔다. 겉보기에 그럴 듯해 보이는 일이라 해도, 실속이 없을 수 있겠다는 생각이 들었다. 그렇기는 해도 이참에 Python의 요즘 흐름을 따라잡고 자료도 만들었으니, 나로서는 그리 손해는 아니다. 오히려 학교에서 강의를 하는 특별한 경험을 할 수 있다는 것만으로 감사한다.

강의 개설과 폐강의 기준이 되는 인원수를 아슬아슬하게 오가고 있어서 폐강을 고려할 정도의 상황이지만 다행히 내 차례가 없어지지는 않았다.

수업을 듣는 학생들 스스로는 아직 잘 모를 수도 있겠지만, 이번에 배우는 것들이 그들의 커리어에 있어서 큰 도움이 될 수도 있을 것이다. 강의를 개설한 학교와 교수님, 나는 그들을 물가에 데려다주는 역할을 하는 것이고, 그 후에 일어나는 일은 학생들의 몫이다.

오늘은 슬라이드의 분량이 부족하다는 피드백이 있었다. 한 시간에 30 페이지 정도 나간다고. 수업 리허설도 해보고 싶었지만 슬라이드 쓰기도 벅찬 현실. 첫술에 배부르랴.

2014년 9월 3일 수요일

해커의 언어, 치명적 파이썬

도서관에 <해커의 언어, 치명적 파이썬>이라는 책이 있길래 빌려두고서 잊어버리고 있다가 문득 눈에 띄어서 들춰보았다.

2013년에 BJ퍼블릭에서 출간하였고, 저자는 미국 국방부의 정보보안 전문가인 TJ 오코너, 역자는 Ahnlab에서 취약점 분석을 담당하는 김선국이다.

책은 일곱 개의 장으로 구성되어 있고 그 중 첫째 장은 Python 언어에 대한 소개인데, 여기에 등장하는 첫 번째 Python 예제부터가 Unix의 passwd 파일 크래킹이다. 각 장마다 보안 분야에서 실제로 일어났던 공격이나 범죄 수사의 실례를 들고, 그것을 Python의 표준 라이브러리나 외부 라이브러리를 이용하여 재연하는 과정이 흥미진진하다.


또한, 원제와 번역서의 제목도 잘 붙였다는 생각이 든다.

Python 2를 기준으로 쓰여졌는데, 만약에 개정판이 나온다면 Python 3에 맞게 수정이 되면 더 좋을 것이다.