불꽃남자의 생체 실험, 타임로그를 찍어보자!

아래 글은 내가 2009년 12월 29일에 지금은 존재하지 않는 랩내 비공개 블로그에 썼던 글이다. 이제서야 꺼내본다. 관련글

시리즈로 작성하고 있던 글들이 2010년 7월이후 멈춰버렸다. 아마도 그때 엄청나게 많은 일들에 시달리다가.. 글쓰기를 멈춘듯하다. 벌써 2년도 넘은 이야기.. 가물가물 이미지들도 지난해 5월 서버 해킹 사건 이후로 죄다 날라가서 아쉽기 그지없다.


안녕하세요. 불꽃남자 입니다. 아시는 분은 아시겠지만, 그 동안 혼자서 타임로그 찍으며, 생체 실험을 한지 만으로 한 달을 넘겼습니다. 그래서 그 한 달치 실험 결과를 공유 해드릴까 합니다. ㅋ 개인적인 치부도 많이 있는 결과라서, 조금 망설여 졌지만, 한 해를 마감하고, “다른 랩원들도 한번 해보면 도움이 될꺼야!” 라는 마음에 동기부여 되시라는 차원에서 가감 없이 정리 들어갑니다.

1. 생체 실험의 발단.

실험을 하겠다 맘먹은 것은 이미 꾀 오래 전 일입니다. 결정적인 계기는 승렬이의 생체실험 1차 공유 이후로, 아하 나도 한번 해봐야겠다. 싶었는데… 타임로그 적는 것 자체가 쉽지 않은 일이었습니다. 또, 일은 많이 하는 것 같은데.. 막상 뒤돌아 보면, 뭘 했는지 생각이 안나는 거죠. 스크럼 할때나, 주간보고 적을때나, 월 자기 평가서 적을때나.. ㅎㅎㅎ 작년 이맘때쯤엔 개인적으로 엄청나게 일을 했던 기억이 떠오릅니다. 그때의 하루 일과를 되짚어 보면, 야근 시간을 제외하고 하루 족히 7시간 이상은 일했을꺼다! 라는 생각은 들지만,남은 기록이 없으니 짐작만 하는 거죠.. 또, 한번 자리에 앉으면 잘 일어나는 않은 습관이 있어서, 이런 생활패턴으로 도저히 안되겠다. 바꾸고 싶은데..바꾸자 맘먹고 행동한 이후로, 이것이 진정 바뀐 생활 패턴인가? 하는 의문도 스스로 들었답니다. 그럼 세세한 사정은 나중에 다시 공유 하는 것으로 하고, 오늘은 그 결과만 살펴보도록 하죠~^^

2. 짧지만 긴 한달 간의 기록

생체실험로그
]1 생체실험로그
위 엑셀표는 제가 지난 12월 18일 금요일에 남긴 로그입니다. 왼쪽 라인 카운트를 보시면 아시겠지만, 벌써 290개 이상의 로그를 쌓았답니다. 현재 글쓰는 12월 29일은 360개 이상의 로그를 계속해서 쌓아가고 있습니다.

3. 작성 방법

이래저래 많은 시도를 했지만, 제가 작성한 방법은 비교적 간단했습니다. 사실 이거 저거 적는 것 자체가 귀찮으니까 간소화 한거죠. 날짜와 시간 그리고 내용만 적었고 나머지 정보는 되도록 자동으로 입력될 수 있도록 엑셀의 수식을 이용했다죠? ^^ 또 그 날짜 시간 마저도 입력이 귀찮아 단축키를 찾아서 단축키를 이용했습니다. 날짜는 하루에 한번만 입력을 했습니다. 날짜 단축키는 CTRL+세미콜론(;) 입니다. 그리고 시간과 내용은 제가 자리를 뜰 때 마다, 혹은 하고 있는 업무가 바뀔 때 마다 틈틈히 적었습니다. 전 이런 바뀌는 비용을 컨텍스트 스위칭 비용 이라고 칭했습니다. 컨텍스트 스위칭 비용에 대한 통계는 3차 생체 실험에 포함될 예정입니다. (앞으로2달 뒤입니다.) 아참, 현재 시간 단축키는 CTRL+콜론(:) 입니다.

4. 로그 통계

기본 데이터 셋은 위처럼 작성했는데. 이게 어느 정도 많이 쌓이다 보니, 통계를 내보고 싶었습니다. 엑셀을 사용한 이유가 그런 이유였죠. 엑셀을 사용하면, 비교적 이런 통계를 내는데 쉽겠다. 한거죠.. 하지만 엑셀을 모르고서는 통계를 내는 것 자체가 쉽지 않터군요…. OTL..

액셀졸라어려워
]2 액셀졸라어려워

그래서 결국은 또 엑셀 통계 삽질로 이래저래 시간을 보내고, 결국 반수작업으로 통계를 냈습니다.

5. 출근 기록

처음 로그를 작성하던 11월 18일은 출근 기록이 없어서 11월 19일부터 기록했던 로그를 그래프로 그려보니 아래와 같은 모양이 나오네요..

출퇴근기록
]6 출퇴근기록
본래 출근시간은 10시 이지만, 오전에 스크럼을 하는 10시 15분을 기준으로 그래프를 그려봤습니다. 12월 들어서면서 스크럼에 지각하는 일이 아주 드문 일이 되었습니다. 그 이유는 12월 영어공부를 하겠다고 다짐하면서, 지각도 줄여보자는 다짐을 했다죠? 추세선을 그어보니 어느정도 다짐의 효과가 있었던듯 싶습니다. ^^

6. 퇴근 기록

퇴근 기록을 보니, 재밌는 그래프가 그려지네요. 뾰족 튀어나온 그래프가 명확히 뭘 의미하는지가 확실하네요. ㅋ  특이한 점은, 정자동으로 오면서, 진정 칼 퇴근(7시 정각에 엘리베이터 타기 그러므로 6시 58분에 로그찍고 나가야함.)이 없어졌습니다. 그 이유는 셔틀 버스 시간이 7시 30분이 넘어서 출발한다는 현실이죠. (여기서 발생한 overwork는 출근에 늦은 시간으로 보상받으면 좋으련만.. 지각은 그냥 지각인 거죠~ ㅋㅋ)

퇴근기록
]4 퇴근기록

7. 이번 생체실험의 핵심! 내가 일한 시간은???

이번 통계는 멋지게 파이 그래프도 그려보고 할려고 했는데, 어렵뜨라구요..ㅜㅜ.. 그래서 그냥 표로 작성 해봤습니다.

액셀작업로그
]5 액셀작업로그
제가 작성하는 로그는 아래와 같이 겹치지 않는 타입으로 총 3가지 정의 했습니다. 표 통계를 보면, 놀라운 결과를 보여주네요. (저만 놀랍나요? ㅇㅎㅎ)
로그타입
]6 로그타입

평균 일하는 시간이 0주차(3일치통계)를 제외하면 평균 약 6시간이 나옵니다. 후덜덜.. 메일로 소비하는 시작도 0주차를 제외하면 평균 1시간 시간 정도 나옵니다. 결국 일하는 시간의 약 16%는 메일작성 하는데 시간을 보내고 있었네요. 위 통계 기간 동안은 지도 2차 개선이 있었던 한 달이라서 그런지, 생각보다 회의시간은 평균적으로 적었습니다. 지난달은 주로 개발을 많이 한거죠. 노는 시간도 평균 1시간 30분이 나오네요.

※ 위 평균시간은 주당 일한 5일의 평균을 하루 평균으로 환산한 수치 입니다.

그밖에 재밌는 결과도 있었습니다.

평균작업시간
]7 평균작업시간

  • 하루에 가장 많이 작업한 시간 : 10시간 05분 (당근 야근을 한날이겠죠?)
  • 하루에 가장 많이 일한 시간(작업+메일+회의) : 11시간 10분
  • 하루에 가장 적게 작업한 시간 : 2시간 02분
  • 하루에 가장 적게 일한 시간 : 2시간 46분

위 통계를 보면, 저의 최대 속도는(하루에 일할수있는 최대)는 10시간 입니다. 그리고 하나 더 하자면, 이날 엄청 피곤했다는 기억이 있습니다. 기억만 있고, 로그는 없다눈…-_- 그래서 다음 생체실험엔 이런 상태로그도 남길껍니다. (기타 개인시간에 대한 통계는 내지 않았습니다.)

8. 통계 후기 그리고 그 이후 계획

이렇게 한 달을 되짚어 보니, 스스로의 다짐이 통하는 구나 하는 느낌이 듭니다. 그리고 엑셀을 좀 더 잘 하고 싶은 욕심도 생기구요. 엑셀로 로그 작성을 하기 전까지 타임 로그 프로그램을 만들겠다고, 고민하고 삽질한 시간을 떠올려보면, 역시나 그냥 잘 모르는 것을 첨부터 만드는 것보다, 잘 할 수 있고, 쉽게 시작 할 수 있는 것부터 해라 라는 교훈을 얻은 것 같습니다. 로그를 남기다 보니, 몇 가지 생체 실험에 대한 아이디어와 목표가 생겼습니다.

-1. 일하는 시간과 개발자 스트레스와의 관계
-2. 컨텍스트 스위칭 비용과 효율적 일 하기와의 관계

위 2가지를 하기 위해서 타임로그에 몇 가지 로그를 더 추가적으로 남길 예정입니다. 객관적인 자료가 되려면 시간이 꾀나 걸리겠죠? 하지만 오늘부터 또 차곡차곡 쌓아갈 예정입니다. 그때 까지도 여전히 엑셀을 잘 모르고 있다면, 통계 내는데 엄청난 시간이 걸리겠죠? OTL .. 도와주십쇼~ 탄산 쏘겠습니다. 사실 엑셀로 하는 이유 중 하나는 결국 타임로그 프로그램을 만들꺼라는 개인 욕심도 있습니다. 그냥 엑셀로 RawData만 축적해놓고, 나중에 프로그램에 한꺼번에 이식해서 통계를 내려는 거죠? 하지만 현실성은 없네요.. ㅋㅋㅋ 언제 그런 날이 올지.. 아마도 엑셀로 해답을 얻지 못하면 그때 가서나 하겠죠? ㅋㅋ 그날을 기다려보죠..ㅋㅋ 여기까지 입니다. 앞으로도 불꽃남자의 생체실험은 계속됩니다.!! 기대해주세요~ 본 실험자료는 불꽃남자와 황색신문과 독점 계약한 내용이니, 일정산정이나 기타 다른 이유로 참고 하지 마세요!! ㅋㅋ

주말 요리사.

지난주에 이어 이번주에도 요리를 해봤다. 오늘의 요리는 토마토 파스타.
생각보다 어렵진 않다. 하지만 이번엔 양조절 실패~ -_-;;;
파스타면이 익으니까 생각보다 양이 많터라.. 뭐 첫판부터 잘 될리 없지..ㅋㅋ
다음엔 해물이나 버섯같은 양념도 넣어서 해봐야겠다.
덕분에 너무 많이 먹었더니 배부르네.. 꺼이꺼익~

원래 있었던 일정도 취소되서 덕분에 지난 한주 모자란 잠도 자두고..
책도 읽고 간만에 푹 쉬었네~ 유후~

html5 Canvas를 이용해 png 이미지 파일 만들기

캔버스에 그린 이미지를 PNG 이미지로 저장하는 방법이 필요해 찾아봤다. 평소에 구현해본게 아니라서 약간의 삽질이 있었지만 파일 구조를 좀 알고 있다면 그다지 어려운 일은 아니다. 참고로 본 설명은 Windows8 스토어 앱 개발에 필요했던 작업이라 WinJS 기준으로 설명하겠지만, 기본 원리는 다른 플랫폼이라도 동일할 것으로 생각된다.

1. 캔버스(Canvas)에 여러장의 이미지 로드하기

먼저 canvas를 이용해 이미지를 올려보자. HTML에 <canvas> 태그를 삽입하고 다음과 같은 코드를 이용해 이미지를 로드해본다.

var canvas = document.getElementById('canvas');
var cx = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function () {
    cx.drawImage(imageObj, 69, 50);
}
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';

document.getElementById('save').onclick = function () {
    saveToFile('test.png');
}

document.getElementById('load').onclick = function () {
    loadFromFile("test.png");
}

2. 캔버스 이미지 데이터 뽑아내기

이제 저장하기 버튼을 눌러서 캔버스에 그린 녀석들을 PNG 파일로  저장해보자. 저장할때는 캔버스에 있는 .toDataURL(‘image/png’) 이라는 메소드를  사용한다. 단, 원격지에 있는 이미지를 로드한 경우 보안 문제로 인해 다음과 같은 에러 메시지를 출력할 것이다.

Error: SECURITY_ERR: DOM Exception 18

따라서 .toDataURL() 메소드를 사용하려면 캔버스에 로드된 파일이 반드시 로컬에 위치해 있어야한다. 여튼 이 메소드는 캔버스의 픽셀 이미지를 Base64로 인코딩해서 다음과 같은 형태의 문자열 데이터로 출력해준다.

"data:image/png;base64,iVBORw0KGgoAAAANSuhEUgAAArwAAAH0......"

참고로 이 값을 이미지 태그의 src 주소에 넣으면 바로 이미지가 로드된다. 하지만 파일로 저장하려면 약간의 트릭이 필요하다. 먼저 PNG 데이터를 끄집어 내야한다.

3. PNG 이미지 데이터로 Blob 데이터 파일 만들기

PNG 파일에는 실제 이미지 데이터가 저장되어야 하기때문에 toDataURL() 로 출력된 문자열에서 “data:image/png;base64,” 이후로 나열된 문자열을 다시 디코딩해서 저장한다. 이런 이미지 데이터를 블럽(Blob) 데이터라고 얘기한다. WinJS의 경우 다음과 같은 메소드를 이용해 디코딩할수있다.

Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(인코드데이터)

파일로 저장하기위한 전체 메소드는 다음과 같이 작성했다. localFolder 객체는 앱 안에 저장되는 위치다.

var saveToFile = function (path) {
    var canvas = document.getElementById('canvas'),
        data = canvas.toDataURL('image/png'),
        localFolder = Windows.Storage.ApplicationData.current.localFolder,
        encodeData = data.replace("data:image/png;base64,", ""),
        decode = Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(encodeData);

    // mySample.txt의 이름으로 파일을 생성하고 동일한 이름이 있을 경우, 덮어쓴다.
    localFolder.createFileAsync(path, Windows.Storage.CreationCollisionOption.replaceExisting)
        .then(function (file) {
            // writeTextAsync메소들 통해 파일에 텍스트를 쓴다.
            return Windows.Storage.FileIO.writeBufferAsync(file, decode);
        });        
    };

4. 이미지 파일 로드하기

서두에도 잠깐 언급했지만, 이미지 파일을 로드는 간단하다. 그냥 이미지 파일 패스를 이미지 태그의 src 주소로 넣으면 끝이다. 일단 localFolder에 저장했으므로 localFolder에서 이미지 패스를 구해서 넣으면 끝! 코드는 아래와 같다.

var loadFromImage = function (path) {
    var localFolder = Windows.Storage.ApplicationData.current.localFolder;

    localFolder.getFileAsync(path).done(function (file) {
        var elTest = document.getElementById('test'), 
            img = new Image();

        img.src = URL.createObjectURL(file);
        elTest.appendChild(img);
    });    
};