자바스크립트(ECMAScript 5) 객체의 공용 멤버와 공용 메소드는 다음과 같이 만드는 것이 일반적인 것 같다.


var A = function(name) {
   console.log("constructor A.");
   this.name = name; //공용 멤버
}
A.prototype = {
   who: function() { //공용 메소드
       console.log("I'm "+this.name);
   },
};


즉 공용 멤버는 생성자 함수 안에서 this 키워드로 만들어지고 공용 메소드는 prototype 객체 안에 정의한다.


 이제 이렇게 생성된 객체 A를 상속해서 새로운 객체 B를 정의하는 방법을 알아보자. 상속이란 기존 객체의 모든 공용 멤버를 복사하여 그대로 사용하면서 거기에 새로운 멤버나 메소드를 추가하는 방식으로 객체를 재사용하는 방법이다. 여러 방법 중에서 ECMAScript5 에서 도입된 Object.create() 함수를 사용하는 일반적인 방법은 다음과 같다.


var B = function(name, age) {
   console.log("constructor B.");
   A.call(this, name); // (1)공용멤버를 상속(복사)한다.
   this.age = age; // 새로운 멤버 추가
}
B.prototype = Object.create(A.prototype); //(2)공용메소드를 상속(복사)
B.prototype.constructor = B; //(3)생성자를 복원한다.
B.prototype.who2 = function() { // 새로운 메소드 추가
   console.log("I'm "+this.age+" years old.");
}


위에서 보면 세 가지 단계가 필수적이다.


(1) 공용 멤버를 상속(복사)하기 위해서 생성자 함수 내부에서 A.call() 함수나 A.apply()함수를 호출하여 공용 멤버들을 복사하는 단계

(2) 공용 메소드들을 복사하기 위해서 Object.create() 함수를 호출하는 단계

(3) 생성자를 복원하는 단계


만약 상속받는 객체의 생성자 함수의 인자들과 원 객체의 생성자 함수 인자들이 동일하다면 A.apply() 함수를 이용하여 인자 전체를 넘긴다.


A.apply(this, arguments);


그렇지 않고 일부만 선택적으로 사용한다면 예제와 같이 A.call()함수를 사용할 수 있다.





Posted by 살레시오
,

 자바스크립트에서 불리언 결과가 false로 판명되는 것들은 다음과 같다.


  • undefined, null

  • NaN

  • 0 (숫자 리터럴) , -0

  • “” (빈 문자열)

  • false


주의할 점은 빈 문자열은 false 이지만 빈 배열, 빈 객체는 true라는 것이다.


> Boolean("")
false
> Boolean([])
true
> Boolean({})
true


그리고 NaN은 그 자신과 같지 않은 유일한 자료형이다.


> undefined == undefined
true
> null == null
true
> NaN == NaN
false


논리 or (||) 연산자를 이용하여 자바스크립트에는 지원하지 않는 default parameter 를 구현할 수 있다.


function func(a) {
  if (a == undefined) a = 1; //(*)
  ...
}


위와 같이 하면 func(0)이라고 호출하면 변수 a는 사용자가 지정한 대로 0값을 가지지만 func() 라고 호출해도 내부 변수 a는 1값을 가지게 된다.


 루아 프로그래머는 위의 (*)를 다음과 같이 더 간단하게 할 수 있지 않느냐고 생각할 지 모른다.


a = a || 1


하지만 func(0) 으로 호출하면 a는 내부적으로 1로 바뀌어 버린다. 0은 false로 간주하기 때문이다. (루아에서는 숫자 0은 true이다.) 주의해야 한다.




Posted by 살레시오
,

 자바스크립트 파일을 컴파일하여 (단일) 실행 파일을 생성하려면 enclose 를 이용한다.



설치는 다음과 같이 한다.


npm install -g enclose


기본적으로 -o 옵션으로 출력파일을 지정해 줄 수 있다.


enclose -o 출력파일 소스파일


그리고 --loglevel 옵션으로 정보 출력 단계를 조절할 수 있다.


한 줄짜리 간단한 js프로그램도 이것으로 실행 파일을 만들어보면 10M 가까운 용량을 차지한다. 외부 라이브러리가 사용되었다면 그것까지 포함되기 때문에 용량을 더 늘어난다. 하지만 js파일을 간단하게 윈도 실행 파일로 변환할 수 있다.

Posted by 살레시오
,

 Koding에서 node.js 를 이용하여 http서버를 실행시킬 수 있으며 외부에서 접속도 가능하다. 다음과 같이 작성한 후 적당한 이름(test002.js)로 저장한다.


var http = require('http');

var server = http.createServer(function (req, res) {
 res.writeHead(200, { 'Content-Type' : 'text/plain' });
 res.end('Hello nodejs');
});

server.listen(8000);


이제 터미털에서 다음과 같이 실행한다.


$node test002.js


그러면 http 서버가 동작하기 시작한다. 외부에서 접속하려면 브라우저에서 다음과 같은 주소를 입력하면 된다.


http://hostname.koding.io:8000


자신의 hostname은 터미널에서 hostname 명령어로 알 수 있다.



만약 arduinoharp라면 다음과 같이 주소를 입력한다.


http://arduinoharp.koding.io:8000


그러면 ‘Hello node.js’라는 문자열이 브라우저에 표시될 것이다.





Posted by 살레시오
,

 C#으로 chart 컨트롤을 사용하는 기본적인 방법에 대해서 이전 포스트에서 알아보았는데 여기에서는 여러 개의 그래프를 하나의 창에 도시하는 방법과 축의 분리에 대해서 알아보도록 하겠다.


 Chart 객체는 여러 개의 Series 그리고 한 개 이상의 ChartArea 객체를 콜렉션 멤버로 가지고 있으며 chart1.Series 와 chart1.ChartArea 같이 접근할 수 있다.


  • Series 객체는 도시할 그래프를 구성하는 점의 집합

  • ChartArea 객체는 그래프를 보여줄 영역


ChartArea는 초기에 한 개가 미리 생성되어 있고 chart1.ChartArea[0] 혹은 chart1.ChartArea[“ChartArea1”]와 같이 인덱스나 이름(문자열)로 접근할 수 있다. Series 객체도 초기에 하나가 생성되어 있으며 ChartArea[0]에 연결되어 있다. 그리고 사용자가 새로 생성되는 Series 객체는 이 default ChartArea와 자동으로 연결이 된다.


private void Form1_Load(object sender, EventArgs e)
{
   chart1.Series.Clear(); //default series를 삭제한다.
   Series series1 = chart1.Series.Add("graph1");
   series1.ChartType = SeriesChartType.Line;
   for (double k=0;k<2*Math.PI;k+=0.1)
   {
       series1.Points.AddXY(k, Math.Sin(k));
   }

   Series series2 = chart1.Series.Add("graph2");
   series2.ChartType = SeriesChartType.Line;
   for (double k = 0; k < 2 * Math.PI; k += 0.1)
   {
       series2.Points.AddXY(k, Math.Cos(k) - 2.0);
   }
}


위와 같이 생성된 Series객체 두 개 모두 ChartArea[0]로 (자동으로) 연결되며 이전 포스트에서 보여준 바와 같이 x축과 y축이 모두 공유된다.


 그런데 같은 영역의 두 그래프의 축을 분리할 수도 있다. 예를 들어 y축 스케일이 다른 두 개의 그래프를 하나의 영역에 겹쳐서 도시하고 싶다면 다음과 같이 하면 된다.


series2.YAxisType = AxisType.Secondary;


이렇게 하면 두 개의 그래프의 x축은 공통이고 분리된 y축의 스케일이 그래프 우측에 표시된다.



이 결과를 보면 그래프영역 우측의 y축에 secondary 축의 단위가 표시됨을 알 수 있다. Series.XAxisType 이나 Seires.YAxisType 프로퍼티는 별도로 지정하지 않으면 AxisType.Primary 로 자동 지정된다.


여기서 한 가지 알아두어야 할 것은 series1과 series2는 y축만 분리되었고 x축은 공통이기 때문에 다음과 같이 x축의 범위를 변경하면 둘 다 영향을 받는다는 점이다.


chart1.ChartAreas[0].AxisX.Minimum = 2.0;
chart1.ChartAreas[0].AxisX.Maximum = 4.0;



하지만 AxisY의 범위를 조절하면 series1만 영향을 받는다.


chart1.ChartAreas[0].AxisY.Minimum = -0.5;
chart1.ChartAreas[0].AxisY.Maximum = 0.5;



series2의 y축 범위를 조절하려면 다음과 같이 하면 된다.


chart1.ChartAreas[0].AxisY2.Minimum = -2.5;
chart1.ChartAreas[0].AxisY2.Maximum = -1.5;



이번에는 series2의 y축 범위만 조정되었음을 알 수 있다.


이와 같이 하나의 ChartArea에 여러 개의 Series 들을 도시할 수 있는데 각 Series의 축을 분리할 수 있으며 x축만 분리할 수도 있고 y축만 분리할 수도 있으며 둘 다 분리할 수도 있다.





Posted by 살레시오
,

 윈도우스 폼프로그래밍에서 그래프나 차트를 그리기 위한 콘트롤로 chart 라는 것이 있다. (.net 4.5부터인가 지원하기 시작함) 이것을 이용하면 간단한 그래프를 작성하는데 외부 라이브러리(예를 들어 oxyplot)를 사용할 필요가 없다.


 비주얼 스튜디오로 winForm 프로젝트를 하나 생성하여 도구상자에서 chart를 끌어다가 적당히 위치시킨 후 docking 시킨다.



그러면 chart1이라는 인스턴스가 생성되는데 이것를 이용하여 그래프를 제어할 수 있다.



using System.Windows.Forms.DataVisualization.Charting;
private void Form1_Load(object sender, EventArgs e)
{
 chart1.Series.Clear(); //default series를 삭제한다.
 Series sSin = chart1.Series.Add("sin"); //새로운 series 생성
 sSin.ChartType = SeriesChartType.Line; //그래프 모양을 '선'으로 지정
 //데이터 포인트 저장
 for (double k=0;k<2*Math.PI;k+=0.1)
 {
      sSin.Points.AddXY(k, Math.Sin(k));
 }
}


결과 화면은 다음과 같다.



한 화면에 다수의 그래프를 그릴 수도 있는데 Series 객체만 추가시켜주면 된다.


private void Form1_Load(object sender, EventArgs e)
{
   chart1.Series.Clear(); //default series를 삭제한다.
   Series sSin = chart1.Series.Add("sin"); //새로운 series 생성
   sSin.ChartType = SeriesChartType.Line; //그래프를 '선'으로 지정
   //데이터 포인트 저장
   for (double k=0;k<2*Math.PI;k+=0.1)
   {
       sSin.Points.AddXY(k, Math.Sin(k));
   }
           
   // 같은 화면에 그래프 추가
   Series sCos = chart1.Series.Add("cos"); //새로운 series 생성
   sCos.ChartType = SeriesChartType.Line;
   for (double k = 0; k < 2 * Math.PI; k += 0.1)
   {
       sCos.Points.AddXY(k, Math.Cos(k));
   }
}


그러면 다음과 같이 두개의 그래프가 그려진다.



chart콘트롤은 Series객체가 갱신될 때마다(즉, 데이터 포인트가 추가될때마다) 자동으로 그래프 영역을 갱신시켜 준다.




Posted by 살레시오
,

 C# 6.0은 이전 버전의 메이져 업그레이드가 아니라 사용자 편의성을 높일 자잘한 기능들이 추가되었는데 문자열 보간도 그 중 하나이다. 예를 들어서 문자열의 중간에 변수의 값을 넣고 싶다면 String.Format()함수를 이용하였다.


str = String.Format(“da is {0}.\r\n”, da);


또는 Console.Writeln함수에서도 이런 형식을 입력할 수 있다.


Console.Writeln(“da is {0}.\r\n”, da);


C# 6.0에서는 이것보다 더 간단한 표현식을 제공한다.


str = $“da is {da}.\r\n”;
Console.Writeln($“da is {da}.\r\n”);


위와 같이 문자열 앞에 $를 붙이면 문자열 내부의 {...}안에 변수가 바로 올 수 있다. 이것을 문자열 보간(string interpolation)이라고 하고 컴파일 시에 내부적으로 String.Format() 함수를 이용한 코드로 적절하게 해석이 된다. 이 새로운 문법이 보기에 훨씬 더 간결하다.


 이 방법으로 정렬과 표시 방법도 옵션으로 지정할 수 있다. 예를 들어서 이전에는 다음과 같이 코딩했던 것을

 

for (int ctr = 0; ctr < names.Length; ctr++)
{
 Console.WriteLine("{0,-20} {1,5:N1}", names[ctr], hours[ctr]);
}

유사하게 문자열 앞에 ‘$’를 붙이고 {...} 안에서는 번호(인덱스) 대신 변수명으로 대신하여 사용할 수 있다.


for (int ctr = 0; ctr < names.Length; ctr++)
{
  Console.WriteLine($"{names[ctr],-20} {hours[ctr],5:N1}");
}

여기에서 첫 번째 변수는 20칸 좌정렬이 되고 두 번째 변수는 5칸 우정렬에  N1형식으로 표시된다.



Posted by 살레시오
,

wxMaxima에서는 그래프를 그리는 명령으로 wxplot2d 함수와 wxplot3d 함수가 있는데 각각 2차원 그래프와 3차원 그래프를 그려준다. 이번 절에서는 2차원 그래프를 그리는 함수의 사용법에 대해서 알아보자. 일단 메뉴창에서 이 함수를 선택하면 (Plot > Plot 2d...) 아래와 같은 대화창이 화면에 나타난다.

[그림 1] wxMaxima에서 plot>Plot 2d 메뉴 선택


[그림 2] Plot 2d 메뉴의 정보 입력 창

위에서 부터 차례대로


①도시할 함수(expression)

② x축의 범위

③ y축의 범위

④ 그래프의 정밀도

⑤ 표시형식(format)

⑥ 선택사항

⑦ 그래프를 저장할 화일명 (eps)


들을 입력하게 되어 있다. 일단 처음이니까 [그림 2]와 같이 첫 번째 칸만 채우고 [OK]를 클릭(엔터키를 쳐도 된다)하면 다음과 같은 그래프가 입력창에 나타나게 된다. 결과를 보면 알겠지만 대화창은 단순히 wxplot2d 함수의 파라메터를 결정해서 함수를 호출하는 역할을 한다. 따라서 사용자가 직접 이 함수를 입력해도 동일한 결과가 나타나므로 앞으로는 wxplot2d함수를 직접 입력해 보겠다.



Posted by 살레시오
,

 맥시마에서 수학 함수는 := 기호를 써서 정의한다. 변수에 어떤 값을 대입하는 연산자는 콜론(:)이고 함수를 정의하는 기호는 (:=) 이라는 것에 유의해야 한다.



다음 예제를 고려하자.


.


이것을 맥시마로 풀면 다음과 같다.



 조건명령 if를 이용하여 함수를 정의할 때 구간 별로 다른 규칙을 정의할 수 있다. 예를 들어 다음과 같은 불연속 함수를 고려하자.

이 함수는 다음과 같이 입력할 수 있다.



다음 함수도 유사하게 입력할 수 있다.


이와 같이 맥시마에서 함수를 정의할 경우에는 := 연산자를 사용하며 if 조건문을 이용하여 불연속 함수도 자유롭게 생성할 수 있다.






Posted by 살레시오
,

 맥시마에서 조건 검사를 하는데 if 명령어가 사용된다. 문법은 다음과 같다.


if <조건식> then <expr1> else <expr2>


만약 조건식이 참이면 <expr1>이 실행되고 거짓이면 <expr2>가 실행된다. 조건식을 구성하는데 사용되는 조건 연산자는 다음과 같다.


[표 1] 조건식에 사용되는 연산자들

연산자

의미

비고

a = b, equal(a,b)

같다

관계 연산자

a # b, notequal(a,b)

다르다(≠)

a < b

크다

a > b

작다

a <= b

크거나 같다

a >= b

작거나 같다

and

and

논리 연산자

or

or

not

not


예를 들면 다음과 같다.

변수 a에 %pi 값이 들어있으니 조건은 거짓이 되므로 b:0 이 실행된다. 위의 예제는 다음과 같이 조금 더 간단하게 바꿀 수 있다.


위에서 (if a<%e else 0)가 단일 표현식이며 그 값은 조건에 따라서 1이거나 0이 된다. 따라서 조건에 따라 그 값을 변수 b에 저장시키는 것이다. and연산자를 이용한 예를 들어보면 다음과 같다.


또한 elseif 명령을 이용하여 if문을 중첩하여 쓸 수 있다.


if <조건식1> then <expr1>
elseif <조건식2> then <expr2>
elseif <조건식3> then <expr3>
...
else <exprN>


이 문법에서 만약 <조건식1> 이 참이라면 <expr1>을 수행하고 빠져나간다. <조건식1>이 거짓이고 <조건식2>가 참이라면 <expr2>를 수행한다. <exprN>은 모든 조건이 거짓일 때 수행된다. 다음 예를 보자.

이 예제에서 변수 b에는 2가 대입된다.



Posted by 살레시오
,