카테고리 보관물: Programming

[AS3] Custom Sliderbar

플래시 가로 슬라이더바

개발이유

플래시에서 제공하는 슬라이더 컴포넌트는 너무 플래시스럽지 않아 자체적으로 제작하여 사용하였습니다.

개발내용

  1. 슬라이더는 이미지를 사용하지 않고 Rectangle 객체를 이용하여 처리한다.
  2. 슬라이더의 값이 변경되면 이벤트를 발생한다.
  3. 슬라이더의 단계를 입력하여 단계별로 이벤트를 발생시킨다.

결과물

CustomSlider

소스

[HorizontalSlider.as]

package  {
    import flash.geom.Rectangle;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.GradientType;
    import flash.geom.Matrix;
    import flash.display.SpreadMethod;

    public class HorizontalSlider extends Sprite {

        public static const SLIDER_CHANGE:String = "sliderChange";

        var sliderBackground:Sprite;
        var sliderKnob:Sprite;

        var sliderKnobWidth:Number = 25;
        var sliderKnobHeight:Number = 40;

        var sliderBackgroundWidth:Number;
        var sliderBackgroundHeight:Number;

        var prevX:Number;
        var boundaries:Rectangle;

        var stepWidth:Number = 40;

        /**
        * 슬라이더 초기 좌표를 저장한다. StepIndex에 따라 슬라이더를 가운데에서 좌, 우로 이동한다.
        */
        var sliderKnobCenterPositionX:Number = 0;

        protected var _isPressed:Boolean;

        /**
        * 슬라이더 바를 생성하도록 한다. 슬라이더는 Rectangle Object 두개를 이용하도록 처리한다.
        * Background에 생성되는 Rectangle도 MOUSE_CLICK 이벤트를 수신하여 슬라이더 버튼을 이동시킨다.
        *
        * @param sliderWidth    슬라이더의 너비을 설정한다.
        * @param sliderHeight   슬라이더의 높이를 설정한다. 
        * @param stepCount      슬라이더 버튼을 Index의 위치에 맞게 이동시킨다.
        *                       슬라이더 이동 범위 (sliderWidth / stepCount) 룰을 따른다.
        *
        */
        public function HorizontalSlider(sliderWidth:Number, sliderHeight:Number, stepCount:Number) {
            _isPressed = false;

            this.sliderBackgroundWidth = sliderWidth;
            this.sliderBackgroundHeight = sliderHeight;

            this.sliderKnobWidth = Math.round(sliderBackgroundWidth / 15);
            this.sliderKnobHeight = Math.round(sliderHeight + 20);

            boundaries = new Rectangle(0, -10, sliderWidth - this.sliderKnobWidth, 0);          

            this.stepWidth = int(sliderWidth / stepCount);

            drawSliderBackground();
            drawSliderKnob();           
            bindSliderEvents();

        }

        private function bindSliderEvents() : void {
            this.sliderKnob.addEventListener(MouseEvent.MOUSE_DOWN, onSliderKnobMouseDownHandler);
            this.sliderKnob.addEventListener(MouseEvent.MOUSE_UP, onSliderKnobMouseUpHandler);

            this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler);
        }




        private function drawSliderBackground() : void {            
            sliderBackground = new Sprite();


            sliderBackground.graphics.lineStyle(2, 0xF298A2);
            sliderBackground.graphics.beginFill(0xFFFFFF);
            sliderBackground.graphics.drawRoundRect(0, 0, this.sliderBackgroundWidth, this.sliderBackgroundHeight, 5);          
            sliderBackground.graphics.endFill();
            sliderBackground.width = this.sliderBackgroundWidth;
            sliderBackground.height = this.sliderBackgroundHeight;
            trace(sliderBackground.width);
            trace(sliderBackground.height);

            this.addChild(sliderBackground);
            sliderBackground.x = 0;
            sliderBackground.y = 0;         
        }


        private function drawSliderKnob() : void {
            this.sliderKnob = new Sprite();
            this.addChild(sliderKnob);
            this.sliderKnob.graphics.beginFill(0xE53F00);
            this.sliderKnob.graphics.drawRoundRect(0, 0, sliderKnobWidth, sliderKnobHeight, 5);
            this.sliderKnob.graphics.endFill();     



            sliderKnob.x = (sliderBackground.width - sliderKnob.width) / 2;
            sliderKnob.y = sliderBackground.y - 10;

            //
            // 중간값을 저장하고 슬라이더 버튼을 이동시킨다.
            //
            sliderKnobCenterPositionX = sliderKnob.x;           
        }


        private function onSliderKnobMouseDownHandler(e:MouseEvent) : void {            
            this.sliderKnob.startDrag(false, boundaries);

            stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMoveHandler);
            this.prevX = this.sliderKnob.x;
            _isPressed = true;
            this.sliderBackground.removeEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler);

        }


        private function onStageMouseMoveHandler(e:MouseEvent) : void {
            var currentPositionX = this.sliderKnob.x;

            if (_isPressed) {               
                if (Math.abs(currentPositionX - prevX) > 0) {                                        
                    prevX = currentPositionX;
                    // dispatchEvent(new Event(HorizontalSlider.SLIDER_CHANGE));
                    e.updateAfterEvent();
                } 

            }
        }


        private function onStageMouseUpHandler(e:MouseEvent) : void {
            this.sliderKnob.stopDrag();
            stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler);
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseMoveHandler);
            _isPressed = false;
            this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler);

            this.calculatePositionX(sliderKnob.x);
        }


        private function onSliderKnobMouseUpHandler(e:MouseEvent) : void {
            this.sliderKnob.stopDrag();

            stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUpHandler);
            stage.removeEventListener(MouseEvent.MOUSE_DOWN, onStageMouseMoveHandler);
            _isPressed = false;
            this.sliderBackground.addEventListener(MouseEvent.MOUSE_UP, onSliderBackgroundMouseUpHandler);

            this.calculatePositionX(sliderKnob.x);

        }


        private function onSliderBackgroundMouseUpHandler(e:MouseEvent) : void {
            var target:Sprite = e.target as Sprite;                         
            sliderKnob.x = e.localX - (this.sliderKnob.width / 2);

            this.calculatePositionX(sliderKnob.x);
        }


        private function calculatePositionX(x:Number) : void {
            var stepIndex:int = int(sliderKnob.x / this.stepWidth) + 1;                                     
            var offsetCount:Number = stepIndex - (int(int(this.sliderBackgroundWidth / this.stepWidth) / 2)+1);         
            this.sliderKnob.x = this.sliderKnobCenterPositionX + (offsetCount * this.stepWidth);        



            var param:Object = {
                "index" : stepIndex
            };
            this.dispatchEvent(new HorizontalSliderEvent(HorizontalSliderEvent.HorizontalSliderEvent, param));

        }
    }

}

[HorizontalSliderEvent.as]

package  {
    import flash.events.Event;

    /**
    * 슬라이더값 변경시 발생되는 이벤트
    * 
    * <사용법>
    * 
    *   //
    *   // Dispatch Event
    *   //
    *   var param:Object = {
    *       "index" : currentIndex
    *   };
    *   this.dispatchEvent(new HorizontalSliderEvent(HorizontalSliderEvent.HorizontalSliderEvent, param));
    *
    */
    public class HorizontalSliderEvent extends Event {

        public static const HorizontalSliderEvent:String = "HorizontalSliderEvent";

        public var param:Object;    


        public function HorizontalSliderEvent(type:String, param:Object, bubbles:Boolean = false, cancelable:Boolean = false) {
            super(type, bubbles, cancelable);
            this.param = param;
        }


        override public function toString() : String {
            return "HorizontalSliderEvent: " + param.toString();
        }

    }

}

[Javascript] How to Become a Great JavaScript Developer

번역 사이트

자바스크립트도 굉장히 매력적인 언어라 공부할 수 있는 방법을 정리해봤습니다.

[요점정리]

1. 책읽기

  • JavaScript: The Good Parts by Douglas Crockford
  • JavaScript: The Definitive Guide, 6th Edition be David Flanagan
  • Secrets of the JavaScript Ninja by John Resig’s

2. 라이브러리 배우기, 사용하기, 읽기

  • jQuery
  • Backbone (recommended)
  • Underscore

3. 연습하고, 스스로에게 질문하기

  • Closures
  • Prototypes
  • Array Extras(Map, Filter)
  • Prototype을 사용한 상속은 어떻게 동작하는가?
  • Closure의 정의는 무엇인가?
  • this 키워드 의미는 어떻게 변하는가?
  • apply/bind/map/filter/call은 어떻게 사용하는가?

[질문]

"bind를 두번 썼을 때, `this`는 무엇을 의미하는가? 어떻게 jQuery는 `this` 키워드를 전역 object가 아닌 jQuery Object로 만드는가?

4. 표준 배우기

5. 웹에 있는 자료 활용

[Python] netstat

개발 내용

네트워크 프로그래밍을 하다 보면 서버에서 어떤 클라이언트가 접속했는지 확인을 해야 하는데 Windows 환경에서 제공하는 netstat 으로 목록을 출력하고 findstr command를 이용하여 필터링하는 과정을 주기적으로 하는 프로그램을 Python 으로 구현

개발 및 동작 환경

  • OS: Windows 7 64Bit
  • Python: 2.7.10

소스 코드

# -*- coding: utf-8 -*-
# ===================================================================
# Author: coozplz@gmail.com
# File: netstat.py
# Date: 2015. 10. 16
# Desc: Windows command "netstat -anp tcp | findstr [PORT]" 를 주기적으로 하는 프로그램
# ===================================================================

import subprocess
import time
from time import localtime, strftime
import datetime

PORT = '12084'
SLEEP_SEC = 5


class NetstatInfo:
    def __init__(self, protocol, local_addr, remote_addr, status):
        self.protocal = protocol
        self.local_addr = local_addr
        self.remote_addr = remote_addr
        self.status = status

    def __str__(self):
        return '%s %s %s %s' % (self.protocal, self.local_addr, self.remote_addr, self.status)


if __name__ == '__main__':
    while True:
        print '-' * 70
        print '%40s' % strftime('%Y-%m-%d, %H:%M:%S', localtime())
        print '-' * 70
        out, err = subprocess.Popen("netstat -anp tcp", stdout=subprocess.PIPE).communicate()
        result = out.splitlines()
        filtered_line = []
        for line in result:
            if PORT in line:
               splitted_value = filter(lambda x: len(x) > 0, line.split(' '))
               n = NetstatInfo(splitted_value[0], splitted_value[1], splitted_value[2], splitted_value[3])
               print n
        time.sleep(SLEEP_SEC) 

[Java] Dropbox API(Upload, Download, List)

Dropbox API 사용법

iOS Ad-hoc 버전 릴리즈 및 팀의 파일 공유를 위해 Dropbox를 사용하는데 이번에 CI(continuous integration)를 하려고 마음을 먹어서 단계별 기능을 확인하고 있다.

Dropbox API 사용법

https://www.dropbox.com/developers-v1/core/start/java 링크에 상세하게 설명되어 있다.

위의 단계에서 주의해야 할 사항은 AccessToken을 얻는 부분이다. 예제대로 따라 하면 AccessToken을 매번 새로 생성하기 때문에 재사용이 안된다.

그렇기 때문에 App Home – Settings – Generated access token 을 이용하여 AccessToken을 생성한다.

[DropboxAPI.java]

import com.dropbox.core.DbxClient;
import com.dropbox.core.DbxEntry;
import com.dropbox.core.DbxException;
import com.dropbox.core.DbxWriteMode;

import java.io.*;

public class DropboxAPI {   


    public DbxEntry.File uploadFile(DbxClient client, String fileName, long fileLength, byte[] fileBytes) throws IOException, DbxException {
        ByteArrayInputStream bais = new ByteArrayInputStream(fileBytes);
        DbxEntry.File uploadedFile = client.uploadFile("/CoozplzFile/" + fileName, DbxWriteMode.add(), fileLength, bais);
        return uploadedFile;
    }


    public DbxEntry.WithChildren listAllFiles(DbxClient client) throws DbxException {
        DbxEntry.WithChildren children = client.getMetadataWithChildren("/CoozplzFile");
        return children;
    }


    public DbxEntry.File downloadFile(DbxClient client, String sourceFile, File downloadedPath) throws IOException, DbxException {
        FileOutputStream fos = new FileOutputStream(downloadedPath);
        DbxEntry.File downloadedFile = client.getFile("/CoozplzFile/"+ sourceFile, null, fos);
        fos.close();
        return downloadedFile;
    }
}

[DropboxAPITest.java]

import com.dropbox.core.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.*;
import java.util.List;
import java.util.Locale;

public class DropboxAPITest {

    public static String ACCESS_TOKEN = "ACCESS_TOKEN";

    DbxClient client;


    @Before
    public void setup() {
        DbxRequestConfig config = new DbxRequestConfig("Sample/1.0", Locale.getDefault().toString());
        client = new DbxClient(config, ACCESS_TOKEN);
    }


    @Test
    public void testListFiles() throws DbxException {

        DropboxAPI dropboxAPI = new DropboxAPI();
        DbxEntry.WithChildren children = dropboxAPI.listAllFiles(client);
        Assert.assertNotNull(children);
        List<DbxEntry> list = children.children;
        System.out.println(list);
        Assert.assertNotNull(list);
    }


    @Test
    public void testUpload() throws IOException, DbxException {
        DropboxAPI dropboxAPI = new DropboxAPI();


        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        InputStream in = DropboxAPITest.class.getResourceAsStream("101-N101_c.ai");

        byte[] buf = new byte[1024];
        while (true) {
            int readSize = in.read(buf);
            if (readSize < 0) {
                break;
            }
            baos.write(buf, 0, readSize);
        }
        DbxEntry.File uploadedFile = dropboxAPI.uploadFile(client, "101-N101_c.ai", baos.size(), baos.toByteArray());
        Assert.assertEquals(baos.size(), uploadedFile.numBytes);
        System.out.println("Numbers of bytes = " + uploadedFile.numBytes);
        baos.close();
    }


    @Test
    public void testDownload() throws IOException, DbxException {
        DropboxAPI dropboxAPI = new DropboxAPI();

        DbxEntry.File file = dropboxAPI.downloadFile(client, "101-N101_c.ai", new File("D:/101-N101_c.ai"));

        String url = client.createShareableUrl(file.path);
        System.out.println(url);

        Assert.assertTrue(url.contains("https://www"));

    }


}

이 글은 java 카테고리에 분류되었고 태그가 있으며 님에 의해 에 작성되었습니다.

[InnoSetup] C# WebView 브라우저 버전

[문제점]

폰갭으로 생성한 HTML 파일을 로딩하는 런처를 C#의 WebView Component를 이용하여 개발하였는데 실행 시에 JavaScript 오류가 발생되며 정상적인 동작이 안되는 문제가 발생됨.

[원인]

C#의 WebView는 실행 환경의 최신 IE브라우저를 사용하는 것이 아닌 내장된 브라우저를 사용하기 때문에 버전이 낮아 발생됨.

[해결]

레지스트리 위치

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION\

InnoSetup 을 이용한 인스톨 시점에 Registry 값을 추가해줌으로 문제를 해결 할 수 있음.

주의사항
Windows Vista 이후부터는 64Bit 운영체제의 경우 HKEY_LOCAL_MACHINE의 경로가 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ 로 변경됨.

스크립트

[Code]
function InitializeSetup(): Boolean;
var V:String;
var subkey:String;
var ieVersionValue:Cardinal;
begin
    // 현재 브라우저 버전을 조회한다. IE11: 11.0.9600.18015
    RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Internet Explorer', 'svcVersion', V);

    // 브라우저 버전의 두자리를 가져온다. 11 or 10
    v := Copy(V, 0, 2);      

    subkey := 'SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION';
    ieVersionValue := 11001;
    if v = '10' then
    begin
        ieVersionValue := 10001;
    end;

    // 레지스트리에 쓰고 저장한다.
    RegWriteDWordValue(HKLM, subkey, '{#MyAppExeName}', ieVersionValue);
    Result := True;    
end;

[OSX] eyeD3를 이용한 태그 변환

iTunes를 이용하다 보면 다수의 가수의 들어가 있는 VA 앨범의 경우 아티스트로 정렬하는 경우 쓸데 없이 많이 나오는 경우가 많아 가능하면 MP3 TAG를 정리해서 넣는다.

Windows에서는 기존에 사용하는 툴이 있어 문제가 없었는데 OSX에서는 사용하는 툴이 없어 불편함이 있었는데 오늘 검색해보니 편리하게 있어 정리한다.

시스템 환경

  1. OSX El Capitan (10.11)
  2. Python 2.7.10

툴 이름은 eyeD3

사용순서

  1. pip를 이용하여 eyeD3를 설치한다.
  2. eyeD3명령을 이용하여 태그를 변경한다.
  3. iTunes 에 태그 변환된 파일을 추가한다.

1. pip를 이용한 eyeD3 설치

$ sudo pip install eyed3

아래와 같이 출력되면 성공이다.

Successfully installed eyed3-0.7.8

2. eyeD3를 이용하여 태그를 변경

eyeD3 -a 김필 -A "Feel Free" *.mp3

3. 변환된 파일을 iTunes에 추가한다.

[참조]

http://eyed3.nicfit.net

이 글은 OS 카테고리에 분류되었고 태그가 있으며 님에 의해 에 작성되었습니다.

오픈소스 파일별 라인수

집에서 동영상으로 코딩 가이드에 대한 강좌를 보는 과정중에 재미난 내용이 있어 python을 사용해서 분석해 보았습니다.

해당 동영상에 나온 내용은 빠른 시일내에 블로그에 정리해서 올릴려고 합니다. 좋은 내용들이 많아서…

프로그래밍 가이드에는 왜 한 라인에 80자만 사용하라고 하는 것인가?

동영상 강좌에 나온 내용으로는 예전 환경은 콘솔 + 작은 모니터 + IDE없는 이어서 한 줄에 80라인을 넘기면 보기가 어려워서 그렇다고 설명을 하였습니다.

그러면서 나온게 최근에 사용되는 오픈소스 프로젝트인 JUnit, Ant와 몇몇가지를 예를 들어 최근에는 80자가 넘는 소스들도 많이 있다고 하였습니다.

그렇지만 한 줄에 너무 많은 글자를 쓰면 가독성이 떨어진다고 단지 좌우스크롤이 안될 정도로만 하라고 설명하셨습니다.

분석

그렇다면 제가 자주 사용하는 라이브러리들은 한 줄에 어느정도의 평균 글자수 와 한 파일에 몇라인이 포함되어 있는지 확인을 해보았습니다.

분석은 소스 폴더에 포함된 java로 확장자를 가지는 파일을 대상으로 하였습니다.

[분석도구]

  1. python 2.7
  2. matplotlib
  3. OSX(Yosemite)

[분석대상]

  1. commons-lang
  2. commons-net
  3. Ant
  4. Open JDK7

결과

결과는 어느정도 예상한대로 commons-lang 과 commons-net의 경우는 평균 100자를 넘지 않는 수치가 나왔습니다. 그렇지만 의외로 open-jdk7에서 평균 400자를 넘는 파일이 있어 확인을 해보니 그럴만한 이유가 있었습니다. 기타 참조

commons-lang

commons-lang_result

commons-net

commons-net_result

open-jdk7

jdk_result

분석 소스

import os
import fnmatch
import matplotlib.pyplot as plt

class FileVO:
def __init__(self, filename, file_size, line_of_file, avg_char):
self.file_size = file_size
self.line_of_file = line_of_file
self.avg_char = avg_char
self.filename = filename

def __str__(self):
return '%-20s / size=%5d, line=%5d, chars(AVG)=%5d' % (self.filename, self.file_size, self.line_of_file, self.avg_char)

if __name__=='__main__':
matches = []
source_path = '/Users/coozplz/Downloads/sources/src-jdk'
for root, dirnames, filenames in os.walk(source_path):
for filename in fnmatch.filter(filenames, '*.java'):
found_file = os.path.join(root, filename)
file_size = os.path.getsize(found_file)
js_file = open(found_file)
lines = js_file.readlines()
sum_of_chars = 0
for line in lines:
sum_of_chars += len(line)
vo = FileVO(filename, file_size, len(lines), sum_of_chars / len(lines))
# print vo
matches.append(vo)
js_file.close()

plt.title("%s(%d files)" % (source_path, len(matches)))
for match_file in matches:
plt.scatter(match_file.line_of_file, match_file.avg_char)
plt.ylabel("Average chars of line")
plt.xlabel("Lines per file")
plt.grid()
plt.show()

기타

평균글자수가 가장 많은 파일 : launcher.java
아래와 같은 코딩이 되어 있어 평균 글자수 길이가 비약적으로 많이 나오는거 같습니다. 나머지 파일들도 마찬가지라고 생각합니다.

소스코드

package sun.launcher.resources;

import java.util.ListResourceBundle;

public final class launcher extends ListResourceBundle {
protected final Object[][] getContents() {
return new Object[][] {
{ "java.launcher.X.macosx.usage", "nThe following options are Mac OS X specific:n -XstartOnFirstThreadn run the main() method on the first (AppKit) threadn -Xdock:name="n override default application name displayed in dockn -Xdock:icon=n override default icon displayed in docknn" },
{ "java.launcher.X.usage", " -Xmixed mixed mode execution (default)n -Xint interpreted mode execution onlyn -Xbootclasspath:n set search path for bootstrap classes and resourcesn -Xbootclasspath/a:n append to end of bootstrap class pathn -Xbootclasspath/p:n prepend in front of bootstrap class pathn -Xdiag show additional diagnostic messagesn -Xnoclassgc disable class garbage collectionn -Xincgc enable incremental garbage collectionn -Xloggc: log GC status to a file with time stampsn -Xbatch disable background compilationn -Xms set initial Java heap sizen -Xmx set maximum Java heap sizen -Xss set java thread stack sizen -Xprof output cpu profiling datan -Xfuture enable strictest checks, anticipating future defaultn -Xrs reduce use of OS signals by Java/VM (see documentation)n -Xcheck:jni perform additional checks for JNI functionsn -Xshare:off do not attempt to use shared class datan -Xshare:auto use shared class data if possible (default)n -Xshare:on require using shared class data, otherwise fail.n -XshowSettings show all settings and continuen -XshowSettings:alln show all settings and continuen -XshowSettings:vm show all vm related settings and continuen -XshowSettings:propertiesn show all property settings and continuen -XshowSettings:localen show all locale related settings and continuennThe -X options are non-standard and subject to change without notice.n" },
{ "java.launcher.cls.error1", "Error: Could not find or load main class {0}" },
{ "java.launcher.cls.error2", "Error: Main method is not {0} in class {1}, please define the main method as:n public static void main(String[] args)" },
{ "java.launcher.cls.error3", "Error: Main method must return a value of type void in class {0}, please ndefine the main method as:n public static void main(String[] args)" },
{ "java.launcher.cls.error4", "Error: Main method not found in class {0}, please define the main method as:n public static void main(String[] args)" },
{ "java.launcher.ergo.message1", " The default VM is {0}" },
{ "java.launcher.ergo.message2", " because you are running on a server-class machine.n" },
{ "java.launcher.init.error", "initialization error" },
{ "java.launcher.jar.error1", "Error: An unexpected error occurred while trying to open file {0}" },
{ "java.launcher.jar.error2", "manifest not found in {0}" },
{ "java.launcher.jar.error3", "no main manifest attribute, in {0}" },
{ "java.launcher.opt.datamodel", " -d{0}t use a {0}-bit data model if availablen" },
{ "java.launcher.opt.footer", " -cp n -classpath n A {0} separated list of directories, JAR archives,n and ZIP archives to search for class files.n -D=n set a system propertyn -verbose:[class|gc|jni]n enable verbose outputn -version print product version and exitn -version:n require the specified version to runn -showversion print product version and continuen -jre-restrict-search | -no-jre-restrict-searchn include/exclude user private JREs in the version searchn -? -help print this help messagen -X print help on non-standard optionsn -ea[:...|:]n -enableassertions[:...|:]n enable assertions with specified granularityn -da[:...|:]n -disableassertions[:...|:]n disable assertions with specified granularityn -esa | -enablesystemassertionsn enable system assertionsn -dsa | -disablesystemassertionsn disable system assertionsn -agentlib:[=]n load native agent library , e.g. -agentlib:hprofn see also, -agentlib:jdwp=help and -agentlib:hprof=helpn -agentpath:[=]n load native agent library by full pathnamen -javaagent:[=]n load Java programming language agent, see java.lang.instrumentn -splash:n show splash screen with specified imagenSee http://www.oracle.com/technetwork/java/javase/documentation/index.html for more details." },
{ "java.launcher.opt.header", "Usage: {0} [-options] class [args...]n (to execute a class)n or {0} [-options] -jar jarfile [args...]n (to execute a jar file)nwhere options include:n" },
{ "java.launcher.opt.hotspot", " {0}t is a synonym for the "{1}" VM [deprecated]n" },
{ "java.launcher.opt.vmselect", " {0}t to select the "{1}" VMn" },
};
}
}

[OSX-Terminal] Welcome Message

맥을 사용하면서 가장 많이 보는 화면중에 하나인 터니널 화면…

기본 화면이 너무 무난해서 싫기 때문에 멋진 글 보다는 내가 사용하는 이니셜을 추가해봤습니다.

맥에서는 이모티콘을 사용할 수 있기 때문에 저와 같이 할려면 텍스트를 아스키로 변환하고 이모티콘을 추가해야 합니다.

웰컴 메시지 수정 순서

  1. http://ascii.mastervb.net/ 에서 원하는 문구를 생성한다.
  2. /etc/motd 파일을 수정한다.
  3. 터미널을 실행해서 테스트 한다.

수정 파일 위치


sudo vi /etc/motd

수정할 내용 추가


💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋

          .oooooo.                                             oooo             
         d8P'  `Y8b                                            `888             
        888           .ooooo.   .ooooo.    oooooooo oo.ooooo.   888    oooooooo 
        888          d88' `88b d88' `88b  d'""7d8P   888' `88b  888   d'""7d8P  
        888          888   888 888   888    .d8P'    888   888  888     .d8P'   
        `88b    ooo  888   888 888   888  .d8P'  .P  888   888  888   .d8P'  .P 
         `Y8bood8P'  `Y8bod8P' `Y8bod8P' d8888888P   888bod8P' o888o d8888888P  
                                                     888                        
                                                    o888o                       

                                                            주인님^^..오늘도 화이팅하시고 즐기세요..🙆                                                   
💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋 💋

[Python] 018/067 Maximum Path Sum

밤에 잠이 안와서 시작한 문제 풀이가 어느덧 3시간이 지났다.
그래서 풀어서 기분은 좋다..^^

문제를 보고 잘못 생각해서 위에서 아래로 큰 수를 찾아가는 거로 계산을 하고 제출을 했는데 오답 표시.

문제를 다시 읽어보니 어떻게 풀어야 할지 조금 막막하다.. 구글신의 도움을 받아 다른 사람이 어떻게 풀었는지를 찾아보았다.

http://www.mathblog.dk/project-euler-18/

위의 링크에 보면 Dynamic Programming 이라는 섹션에 어떤식으로 풀어야 되는지 표시가 되어 있다.

풀이과정

[초기값]

8 5 9 3
2 4 6
7 4
3

[가공값]

  1. 8+2 와 5+2 를 비교하여 큰값을 2행 1열(2)위치에 입력
  2. 5+4 와 9+4 를 비교하여 큰값을 2행 2열(4)위치에 입력
  3. 9+6 과 3+6 을 비교하여 큰값을 2행 3열(6)위치에 입력
  4. 1~3의 스텝을 반복한다.

[소스코드]

import unittest


class TestMaximumPathSumClass(unittest.TestCase):

    def testExample(self):
        input_str = '''
                    3
                    7 4
                    2 4 6
                    8 5 9 3'''
        value = self.maximum_path_sum(input_str)
        self.assertEqual(value, 23)

    def testPE67(self):
        f = open("/Users/p/Downloads/p067_triangle.txt")
        lines = f.readlines()
        value = self.maximum_path_sum(''.join(lines))
        print(value)
        f.close()

    def testPE18(self):
        input_str = '''
                    75
                    95 64
                    17 47 82
                    18 35 87 10
                    20 04 82 47 65
                    19 01 23 75 03 34
                    88 02 77 73 07 63 67
                    99 65 04 28 06 16 70 92
                    41 41 26 56 83 40 80 70 33
                    41 48 72 33 47 32 37 16 94 29
                    53 71 44 65 25 43 91 52 97 51 14
                    70 11 33 28 77 73 17 78 39 68 17 57
                    91 71 52 38 17 14 91 43 58 50 27 29 48
                    63 66 04 68 89 53 67 30 73 16 69 87 40 31
                    04 62 98 27 23 09 70 98 73 93 38 53 60 04 23'''
        value = self.maximum_path_sum(input_str)
        print("Maximum path sum = ", value)

    def maximum_path_sum(self, input_str):
        input_str = input_str.strip()
        lines = input_str.split('n')
        array = []
        for line in lines:
            if len(line) == 0:
                continue
            nums_array = line.strip().split(" ")
            array.insert(0, nums_array)

        for i in range(0, len(array) - 1):
            nums_array = array[i]
            changed_array = []
            for j in range(0, len(nums_array)-1):
                v1 = int(array[i][j]) + int(array[i+1][j])
                v2 = int(array[i][j+1]) + int(array[i+1][j])
                changed_array.append(max(v1, v2))
            array[i+1] = changed_array
            print(changed_array)

        return array[len(array)-1][0]

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestMaximumPathSumClass)
    unittest.TextTestRunner(verbosity=2).run(suite)

[Python] 53_combinatoric_selections

문제링크

문제풀이

  1. 조합을 구하는 함수를 정의한다
  2. 팩토리얼을 구하는 함수를 정의한다. (팩토리얼을 lambda를 이용한다)
  3. 조합의 공식에 따라 구해진 값이 1,000,000이 넘는 값을 카운팅 한다.
import unittest
import functools


class TestCombination(unittest.TestCase):

    def testCombination(self):
        value = self.combination(5, 3)
        self.assertEqual(value, 10)

        value = self.combination(23, 10)
        self.assertEqual(value, 1144066)

    def combination(self, a, b):
        v1 = self.fact(a)
        v2 = (a == b and 1 or (self.fact(b) * (self.fact(a - b))))
        return v1 / v2

    def fact(self, a):
        if a == 0:
            return 0
        fact_value = functools.reduce(lambda x, y: x * y, range(1, a + 1))
        return fact_value

    def testOverMillionCount(self):
        count = 0
        for i in range(1, 101):
            for j in range(1, i):
                combi_value = self.combination(i, j)
                if combi_value > 1000000:
                    # print("%d, %d, combi_value=%d" % (i, j, combi_value))
                    count += 1
        print("Over 1million counts = ", count)

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestCombination)
    unittest.TextTestRunner(verbosity=2).run(suite)