import java.util.Arrays;
import java.util.List;

public class Test {
	public void copyByArray(int[] source) {
		int[] target = new int[source.length];
		// arraycopy(원본 배열, 복사 시작 위치, 대상 배열, 대상 배열의 시작 위치, 복사 길이);
		System.arraycopy(source, 0, target, 0, source.length);
	}

	public List copyByList(Integer[] args) {
		List list = (List) Arrays.asList(args);
		return list;
	}

}
package report1;

import java.io.UnsupportedEncodingException;

public class CharacterIncoding {

	public static void main(String[] args) {

		String word = "무궁화 꽃이 피었습니다.";
		try {
			System.out.println("utf-8 -> euc-kr        : "
					+ new String(word.getBytes("utf-8"), "euc-kr"));
			System.out.println("utf-8 -> ksc5601       : "
					+ new String(word.getBytes("utf-8"), "ksc5601"));
			System.out.println("utf-8 -> x-windows-949 : "
					+ new String(word.getBytes("utf-8"), "x-windows-949"));
			System.out.println("utf-8 -> iso-8859-1    : "
					+ new String(word.getBytes("utf-8"), "iso-8859-1"));
			System.out.println("iso-8859-1 -> euc-kr        : "
					+ new String(word.getBytes("iso-8859-1"), "euc-kr"));
			System.out.println("iso-8859-1 -> ksc5601       : "
					+ new String(word.getBytes("iso-8859-1"), "ksc5601"));
			System.out.println("iso-8859-1 -> x-windows-949 : "
					+ new String(word.getBytes("iso-8859-1"), "x-windows-949"));
			System.out.println("iso-8859-1 -> utf-8         : "
					+ new String(word.getBytes("iso-8859-1"), "utf-8"));
			System.out.println("euc-kr -> utf-8         : "
					+ new String(word.getBytes("euc-kr"), "utf-8"));
			System.out.println("euc-kr -> ksc5601       : "
					+ new String(word.getBytes("euc-kr"), "ksc5601"));
			System.out.println("euc-kr -> x-windows-949 : "
					+ new String(word.getBytes("euc-kr"), "x-windows-949"));
			System.out.println("euc-kr -> iso-8859-1    : "
					+ new String(word.getBytes("euc-kr"), "iso-8859-1"));
			System.out.println("ksc5601 -> euc-kr        : "
					+ new String(word.getBytes("ksc5601"), "euc-kr"));
			System.out.println("ksc5601 -> utf-8         : "
					+ new String(word.getBytes("ksc5601"), "utf-8"));
			System.out.println("ksc5601 -> x-windows-949 : "
					+ new String(word.getBytes("ksc5601"), "x-windows-949"));
			System.out.println("ksc5601 -> iso-8859-1    : "
					+ new String(word.getBytes("ksc5601"), "iso-8859-1"));
			System.out.println("x-windows-949 -> euc-kr     : "
					+ new String(word.getBytes("x-windows-949"), "euc-kr"));
			System.out.println("x-windows-949 -> utf-8      : "
					+ new String(word.getBytes("x-windows-949"), "utf-8"));
			System.out.println("x-windows-949 -> ksc5601    : "
					+ new String(word.getBytes("x-windows-949"), "ksc5601"));
			System.out.println("x-windows-949 -> iso-8859-1 : "
					+ new String(word.getBytes("x-windows-949"), "iso-8859-1"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}



소프트웨어 공학 실무적 접근

저자
Pressman 지음
출판사
McGRAW HILL | 2015-01-02 출간
카테고리
컴퓨터/IT
책소개
▶ 이 책은 소프트웨어 공학 이론서입니다. 소프트웨어 공학의 기...
가격비교

 

1.   소프트웨어의 본질

 

 소프트웨어(software 이하 SW)는 프로덕트이며, 동시에 프로덕트를 전달하는 수단이다. ① 프로덕트로써, 소프트웨어는 하드웨어나 네트워크에 의해 구체적인 컴퓨팅 잠재력을 전달한다. ② 프로덕트를 전달하는 수단으로써, 소프트웨어는 컴퓨터를 제어(운영체제)., 정보의 전달(네트워크), 다른 프로그램을 생성하고 제어(소프트웨어 도구와 환경)하는 역할을 한다.

  소프트웨어는 가장 중요한 프로덕트인 정보(한 개의 비트에서부터 많은 데이터로 만든 멀티미디어 데이터)를 생산, 관리, 획득, 수정, 표시, 전파시킨다. 개인적인 관점에서 더욱 유용하게 사용할 수 있도록 개인적인 데이터를 변환하거나, 경쟁력을 향상시키기 위해 사업관련 정보를 관리하거나, 전 세계적인 정보 네트워크로의 게이트웨이를 제공하거나, 다양한 형태의 정보를 획득할 수 있는 수단을 제공한다.

  지난 50년간 하드웨어 성능 개선, 컴퓨터 구조 변화, 저장용량 증가, 다양한 입출력 장치 등으로 인해 컴퓨터 소프트웨어는 더욱 정교해지고 복잡하게 변화하였다. 그러나 개발자의 입장에서는 큰 어려움이 되기도 하였다. 소프트웨어의 규모가 커짐에 따라 개인이 시스템을 개발하는 것이 아닌 여러 개의 팀으로 대체되었다. 하지만 여전히 같은 질문을 하고 있다.

Ÿ   시간 : 소프트웨어가 완성되기 위해 왜 그렇게 많은 시간이 필요한가?

Ÿ   비용 : 소프트웨어 개발 비용이 왜 그렇게 많이 드는가?

Ÿ   소프트웨어를 고객에게 전달하기 전에 왜 모든 에러를 찾지 못하는가?

Ÿ   개발된 프로그램을 유지 보수하는 데 왜 그렇게 많은 시간과 노력을 들여야 하나?

Ÿ   소프트웨어를 개발하고 유지 보수할 때 진척 정도를 측정하기가 왜 어려운가?

  이와 같은 질문들은 소프트웨어의 개발 방식에 대한 질문으로, 이런 질문으로 소프트웨어공학 기술의 필요함을 알려준다.

 

1.1   소프트웨어 정의

  먼저 프로그램은 특정 문제를 해결하기 위한 명령어들의 정렬된 집합을 말한다. 소프트웨어란 컴퓨터 프로그램과 함께 관련된 문서(요구서, 설계서, 분석서, 에러리포트, 설명서, 테스트 리포트, 테스트 케이스등 유지 보수하는데 사용되고, 개발하면서 필요한 모든 문서들)를 포함한 것을 말한다. 곧 프로그램은 하나의 소프트웨어의 진부분집합이다.

 

"소프트웨어는 실행되면서 원하는 기능이나 함수, 성능을 제공해 주는 명령어들, ② 프로그램이 데이터를 적절하게 처리할 수 있게 해주는 자료구조, ③ 프로그램의 사용이나 운영을 나타내는 하드카피나 가상 형태의 문서이다.

- 교재 p5

 


[그림 1] 하드웨어 고장률 곡선

 

  그림 1은 하드웨어 고장률을 나타낸다. 욕조 커브(bathtub curve)로 불리는 그래프로, 하드웨어의 생명주기 초기에는 설계나 제조과정의 결점으로 인해 고장률이 높다. 그리고 결점의 수정을 통해 안정적인 수준으로 떨어진다. 하지만 시간의 지남에 환경적 요인(먼지, 진동, 오용, 극단적인 온도 등)을 겪으며 마모되고 고장률은 다시 올라가게 된다

 

.

[그림 2] 소프트웨어 고장률 곡선

 

  소프트웨어는 하드웨어와 달리 환경적 요인에 의해서 마모되지 않는다. , 하드웨어는 부품이 마모되면 새것으로 교체하면 되지만 소프트웨어는 오류가 발생하면 코드를 변경해야 한다. 이론상으로는 소프트웨어는 마모되지 않으므로 그림 2와 같이 초기에는 높은 고장률을 보이다가 수정을 통해 낮은 고장률인 곡선의 형태를 보여야 한다. 하지만 소프트웨어는 마모되는 것이 아니라 악화되는 것이다.

그림 2의 실제 곡선(Actual curve)과 같이 뾰족한 고장률 곡선이 나타난다. 생명주기에는 발견되지 않은 결함으로 인해 높은 고장률을 나타낸다. 결함들이 수정되어지면 다시 일정하게 낮아진다. 하지만 새로운 요구사항으로 인해 소프트웨어에 변경이 이루어지면 급격하게 고장률은 높아진다. 수정을 통해 곡선은 낮아지다가 안정적인 고장률로 돌아가기 전에 다른 요구사항으로 인해서 곡선은 뾰족하게 된다. , 변경과정에서 많은 에러를 동반한다. 이러한 반복으로 인해 전체적으로 고장률 수준이 올라가기 시작하면서 소프트웨어는 저하된다. 따라서 변경을 요하는 소프트웨어 유지보수 작업은 하드웨어 유지보수보다 상당히 복잡하다.

  소프트웨어공학 방법론에서는 소프트웨어 고장률 그래프에 변경으로 인해 고장률이 높아진 정도를 줄이기 위해 노력하고 있다.

 

1.2   소프트웨어 애플리케이션 도메인

  컴퓨터 소프트웨어는 넓게 7가지 범주로 나눌 수 있다.

Ÿ   시스템 소프트웨어(System software) : 컴파일러나 파일 관리 유틸리티와 같은 시스템 소프트웨어는 결정적(소프트웨어의 입력, 처리, 출력의 시간과 순서가 예측 가능)인 정보구조를 처리하고, 운영체제 컴포넌트, 드라이버, 원거리 통신 처리기와 같은 시스템 소프트웨어는 비결정적인 데이터를 처리한다.

Ÿ   애플리케이션 소프트웨어(Application software) : 특수한 업무상의 요구를 해결해 주는 독자적인 프로그램이다.

Ÿ   공학/과학용 소프트웨어(Engineering/scientific software) : '수 처리' 알고리즘으로 사용되는 것들로, 천문학부터 화산학, 자동차 스트레스 분석부터 우주 왕복선 궤도 역학 등 다양하게 응용된다.

Ÿ   임베디드 소프트웨어(Embedded software) : 제품이나 시스템에 내정되어 있으면서 시스템 자체를 위한 특징적인 기능만 구현하고 제어하는 데 사용된다. 예를 들어 전자레인지나 밥솥에 내장된 소프트웨어를 말한다.

Ÿ   프로덕트라인 소프트웨어(Product-line software) : 많은 고객들이 사용할 수 있는 특수한 기능을 제공하기 위하여 설계되어지며, 제한적이고 개인적인 프로덕트나 또는 대규모 고객을 위한 프로덕트에 주안점을 두고 개발할 수 있다.

Ÿ   /모바일 애플리케이션(Web/mobile applications) : 네트워크 중심 소프트웨어의 범주에는 다양한 응용 분야가 있을 수 있으며, 브라우저 기반의 앱들과 모바일 기기들에서 동작하는 소프트웨어들을 모두 포함한다.

Ÿ   인공지능 소프트웨어(Artificial intelligence software) : 계산이나 직접적인 방법으로는 분석할 수 없는 복잡한 문제를 해결하기 위해 비수치적 알고리즘을 사용한다. 로보틱스, 패턴인식, 인공신경망 등을 분야로 들 수 있다.

  일부 새로운 시스템이 만들어지고 있지만, 대부분, 기존 애플리케이션이 수정되고, 적용되며, 개선되고 있다. 이처럼 지난 세대의 소프트웨어 종사자들이 각 범주 별로 유산을 남겨두었다. , 재사용성이 가능하도록 하여 새로운 시스템을 개발하는데 있어서 부담을 덜 수 있게 되었다.

 

1.3   레거시 소프트웨어

  레거시 소프트웨어란 과거에 개발되어 현재에도 사용 중인 낡은 소프트웨어를 말한다. 이는 현대까지도 남아 쓰이는 기술일 수도 있고, 쓰이지 않더라도 현대의 기술에 영향을 주는 경우도 있다. 보통 레거시 소프트웨어는 오래 전에 개발되어서 품질이 낮은 경우가 많다. , 확장 불가능한 설계, 매우 복잡한 코드, 문서화가 되어있지 않은 경우, 변경에 대한 기록이 없는 경우이다. 이 시스템이 "사업의 핵심 기능을 지원하며 사업상 꼭 필요한 것이다."라고 하면 어떻게 할 것인가?

  이 질문에 대해서 한 가지 적합한 해결책은 아무것도 하지 않는 것이다. 만약 레거시 시스템이 사용자의 요구를 만족시키고 믿을 수 있게 작동한다면 이 시스템은 고장 난 것이 아니며, 고칠 필요가 없다. 하지만 레거시 시스템은 다음과 같은 이유로 계속 진화한다.

Ÿ   새로운 컴퓨팅 환경이나 기술이 필요한 경우 소프트웨어가 이를 만족시키기 위해 적응 되어야만 한다.

Ÿ   사업상 새로운 요구를 만족시키기 위해 기능이 향상되어야 한다.

Ÿ   새로운 시스템이나 데이터베이스와 상호 운용될 수 있도록 소프트웨어가 확장되어야 한다.

Ÿ   진화하는 컴퓨팅 환경에서 실행 가능하도록 하기 위해 소프트웨어는 재설계되어야 한다.

  이런 식으로 점진적인 진화가 이루어지면 레거시 시스템은 새로운 환경에 맞게 재공학되어야 한다. 현대의 소프트웨어공학의 목표는 "진화 기초를 둔 방법론은 고안하는 것"이다. 진화 개념이란 소프트웨어는 계속적으로 변화한다는 것으로, 예전 소프트웨어와 새로운 소프트웨어 모두 서로 상호운용되어야 하고 서로 협력해야 한다는 것이다.

 

2.   소프트웨어 본질의 변화


  산업계를 지배하며 진화하고 있는 소프트웨어에는 네 가지 범주가 있고, 10여 년 전까지 초기 단계에 머물러 있었다. 하지만 오늘날 급격하게 변화하였으며 각각의 범주는 다음과 같다.

 

1.1           웹앱

  월드 와이드 웹은 하이퍼텍스트라는 기능에 의해 인터넷상에 분산되어 존재하는 온갖 종류의 정보를 통일된 방법으로 찾아볼 수 있게 하는 광역 정보 서비스 및 소프트웨어이다. 초기 단계에는 텍스트와 한정된 그래픽만을 사용하여 구성되어 있었다. 시간이 흘러, HTML(HyperText Markup Language)은 개발도구에 의해 확대되어 졌고, 정보 컨텐츠와 함께 계산 기능을 제공하는 것을 가능하게 하였다. 그로 인해 웹 기반 시스템과 응용프로그램(웹앱)들이 생겨났다.

  지난 10여 년 동안, 씨맨틱 웹(Semantic Web) 기술들(종종 Web 3.0으로 표현됨)은 계속 진화해왔다. 그로 인한 정교하고 복잡한 관계형 자료 구조는 이전에는 불가능했던 상이한 정보들에 대한 접근을 가능하게 함으로써, 완전히 새로운 웹앱을 만들 수 있는 길을 열어주었다.

 

  시맨틱 웹(Semantic Web) '의미론적인 웹'이라는 뜻으로, 현재의 인터넷과 같은 분산환경에서 리소스(웹 문서, 각종 화일, 서비스 등)에 대한 정보와 자원 사이의 관계-의미 정보(Semanteme)를 기계(컴퓨터)가 처리할 수 있는 온톨로지형태로 표현하고, 이를 자동화된 기계(컴퓨터)가 처리하도록 하는 프레임워크이자 기술이다. 웹의 창시자인 팀 버너스 리가 1998년 제안했고 현재 W3C에 의해 표준화 작업이 진행 중이다.

- '시맨틱 웹', 위키백과

 

1.2           모바일 앱

  (app)이란 모바일 플랫폼에서 동작하도록 제작된 소프트웨어를 뜻한다. 모바일 앱과 모바일 웹 응용프로그램 사이의 차이점을 인식하는 것은 중요하다. 모바일 웹 응용프로그램(WebApp)은 모바일 디바이스로 하여금 모바일 플랫폼의 장단점을 포함하도록 디자인된 브라우저를 통해 웹 기반의 컨텐츠에 대한 접근을 가능하게 해준다. , 모바일 브라우저를 통해서 실행되는 응용프로그램을 말한다. 반면에 모바일 앱은 특정 모바일OS에서 구동되는 것으로 하드웨어 특징들에 대한  직접적인 접근이 가능한 것을 말한다. 하지만 오늘날, 기술의 발전으로 브라우저들이 디바이스를 컨트롤 가능하게 되었기 때문에 모바일 앱과 모바일 웹 응용프로그램 간의 차이는 점점 흐려지고 있다.

 

1.3           클라우딩 컴퓨팅

  클라우딩 컴퓨팅은 모든 사용자들이 장소에 구애 받지 않고 광범위한 범위에서 컴퓨팅 장치를 사용하여 컴퓨팅 자원들을 공유하게 하는 인프라스트럭처 또는 "생태계"를 포함한다.

  클라우드 컴퓨팅의 구현은 프론트앤드와 백앤드 서비스들을 포함하는 구조의 개발이 필요하다. 프론트앤드는 클라이언트 디바이스와 백앤드 서비스에 대한 접근을 가능하게 해주는 응용 소프트웨어를 말한다. 백앤드는 서버와 관련 컴퓨팅 자원들, 데이터 저장 시스템, 서버에 상주하는 응용프로그램, 그리고 관리 서버들을 포함한다.

  클라우드 컴퓨팅은 소프트웨어가 전달되는 방식과 존재하는 환경을 바꿀 것이다.

 

1.4           프로덕트 라인 소프트웨어

  카네기 멜론 대학의 소프트웨어공학 연구소는 소프트웨어 프로덕트 라인을 "특정 시장 분야 또는 임무에 필요하며, 공통으로 관리되는 특징들을 공유하고, 규정된 방식에 따라 핵심 자산들로부터 개발된 일련의 소프트웨어 집약 시스템"으로 정의했다. , 프로덕트 라인 내의 모든 프로덕트들 사이에서 공통적인 컴포넌트, 아키텍처, 모델 등을 활용하여 재사용하고 개발 기간을 단축시켜 생산성을 높이고 품질이 좋은 소프트웨어를 개발할 수 있게 됨을 의미한다.


 

온도계 만들기

온도계 센서도 사용하고 세그먼트도 사용해보았다. 이제 두개를 이용하여 온도계를 만들어보고자 했다. 간단하게 생각하고 있었는데 문제는 브레드보드와 연결하는 중에 생각났다. 아두이노에 두개의 세그먼트를 연결할 핀이 부족했다.

7-세그먼트 2개를 이용해 2자리 숫자 출력하기

먼저 생각한 것은 논리회로 시간에 하던 것 처럼 진리표를 그려서 간략화 시켜서 해야겠다는 생각을 하였다. 하지만 기본키트에는 AND, OR게이트를 도와줄 칩이 없어서 할 수 없었고, 인터넷을 찾아보던중 한 동영상을 찾았다.

아두이노 강좌 - 8강-2 7 세그먼트 컨트롤하기(2자리 컨트롤 하기)

여기서는 두개의 세그먼트 가지고 반복적으로 출력함으로써 눈속임을 이용하였다. 이 코드를 이용해 조금 더 바꾸어서 다음과 같이 작성하였다.

byte seven_seg_digits[10][7] = { 
  { 0,0,0,0,0,0,1 },  // = 0
  { 1,0,0,1,1,1,1 },  // = 1
  { 0,0,1,0,0,1,0 },  // = 2
  { 0,0,0,0,1,1,0 },  // = 3
  { 1,0,0,1,1,0,0 },  // = 4
  { 0,1,0,0,1,0,0 },  // = 5
  { 0,1,0,0,0,0,0 },  // = 6
  { 0,0,0,1,1,1,1 },  // = 7
  { 0,0,0,0,0,0,0 },  // = 8
  { 0,0,0,1,1,0,0 }   // = 9
 };

void setup() {
  int pinNum = 2;
  // segment init
  for (pinNum = 2; pinNum < 10; pinNum++) {
    pinMode(pinNum, OUTPUT);
  }

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);

  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
}

// 세그먼트에 한개의 숫자를 출력하는 함수
void sevenSegWrite(byte digit) {
  byte pin = 2;
  for (byte segCount = 0; segCount < 7; ++
    segCount) {
    digitalWrite(pin, seven_seg_digits[digit][segCount]);
    ++pin;
  }
}

// show number
// 0부터 99까지 출력하는 함수.
// 1번 세그먼트와 2번세그먼트를 반복적으로 
// 보여줌으로써 눈속임을 이용해 2자리 숫자를 나타낸다.
void showDigite(byte pNum) {
  int num1 = pNum / 10;
  int num2 = pNum % 10;
  int cnt = 100;

  if (num1 == 0) {
    while(0 < cnt--) {
      digitalWrite(0, HIGH);
      digitalWrite(1, LOW);
      sevenSegWrite(num2);
    }
  } else {
    while(0 < cnt--) {
      digitalWrite(0, LOW);
      digitalWrite(1, HIGH);
      sevenSegWrite(num1);
      delay(10);
      digitalWrite(0, HIGH);
      digitalWrite(1, LOW);
      sevenSegWrite(num2);
      delay(10);
    }
  }
}
void loop() {
  showDigite(80);
}

showDigite() 함수가 2자리 수를 출력하는 함수이다. 원리는 간단하다. 두개의 세그먼트가 같은 숫자를 보여주지만 한번은 왼쪽 세그먼트를 끄고, 또 한번은 오른쪽 세그먼트를 끄고 출력하여 그것을 반복하여 눈속임을 하는 것이다. 그것을 함수로 작성하려고하니 눈속임을 할 수 있을 정도 한번 보여줄때 100번 반복을 통해 두자리인것 마냥 보여준다.

디지털 온도계 만들기


위 사진은 회로도이다. (Fritzing 라는 프로그램으로 편하게 작성할수 있다. 링크)두 개의 세그먼트를  5V에 주지 않고 0번과 1번 핀에 주어진 것을 볼 수있다. 다음으로 온도값을 가져오면 된다. 이것은 센서를 이용하여 간단하게 알 수 있기때문에 어려움은 없었다. 센서를 연결하고 loop()에 다음과 같은 코드만 추가시켰다.

아두이노 온도 센서사용하기


int val = 0;

void loop() {
  int reading = analogRead(0);
  
  val = (reading * 500.0) / 1024.0;
  showDigite(val);
  
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  delay(1000);
}

결과 영상

마지막으로

보완해야할 점이 매우 많았다. 선을 너무 많이 사용해서 복잡한것도 있었고, 눈속임을 통해 보여주는 것이라 반복문을 돌고있는 중에는 다른 작업을 할수 없는것도 문제점이었다. 나중에 제대로 디지털온도계를 만들 때는 세그먼트 두개에 간략화를 해서 사용하던지, 그냥 2digit segment 를 사용해야겠다. 회로 연결하는 것은 어렵지 않았으나 코드를 작성할때 생각처럼 간단하지 않았던 실험이었다.


전체코드

Temperature.c


"본 제품은 아이씨뱅큐 무상체험단 21기 활동의 일환으로 체험 제품을 제공받아 작성되었습니다."

for문 사용

function getRandomArray(idxSize, range) {
	/* 랜덤 수를 가진 배열을 반환하는 메서드.
	 * idxSize : 반환받을 배열 사이즈, 
	 * range : 랜덤 수의 범위
	 */
	var indexs = new Array(); // 랜덤 인덱스 배열
	var hasValue = false; //같은 값이 있는지 확인하기 위한 변수
	
	if(idxSize > range) {
		console.error('index size > range');
		return indexs;
	}
	
	while(indexs.length < idxSize) {
		hasValue = false;
		var temp = parseInt(Math.random() * range);
		for(c = 0; c < indexs.length; c++) {
			if(temp == indexs[c]) {
				hasValue = true;
				break;
			}
		}
		if(hasValue == false) {
			indexs.push(temp);
		} 
	}
	return indexs;
}

// 사용방법
var indexs = new Array();
indexs = console.log(getRandomArray(5, 10));
indexs.forEach(function(value) {
	console.log(value);
});


Set 사용

set으로 좀 더 짧은 코드를 작성할 수 있지만 크롬과 오페라, 파이어폭스에서만 지원되며 익스플로러에서는 Set을 지원하지 않는다.

var indexs = new Set();
while(1) {
	indexs.add(parseInt(Math.random() * 10));
	if(indexs.size == 5) {
		console.log(indexs.size);
		break;
	}
}

indexs.forEach(function(value) {
	console.log(value);
});

CSS로 말줄임표 만들기

.ellipsis{width:200px;text-overflow:ellipsis;-o-text-overflow:ellipsis;overflow:hidden;white-space:nowrap; word-wrap:normal !important;}


참고 사이트 링크, 링크(JQuery 플러그인)


'Web > HTML,CSS' 카테고리의 다른 글

[CSS] div 둥근 테두리 만들기  (0) 2013.08.30
[HTML] html RFC 한글 번역  (0) 2013.08.20
[HTML] 한글 번역문 HTML 4.01  (0) 2013.08.20
[CSS] Opacity 투명도 조절하기  (0) 2013.08.09

하나의 액티비티에 적용

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

전체 적용

<uses-permission android:name="android.permission.WAKE_LOCK"/>



제품ID가져오기.bat


2015.03.04

학교 컴퓨터실 포맷을 하면서 고정IP에 마지막 숫자만 변경해야 하는데, 하나하나 변경하지않고 마지막 숫자만 입력받아서 빠르게 네트워크 설정하기 위해 작성. (원본은 참고사이트에 올라와있는 배치파일이다.)


네트워크설정(그래픽스).bat

네트워크설정(원본).bat


참고사이트 링크

7-세그먼트(SR-1056A) 사용하기

세그먼트 사용법을 알아보고자 한다. 먼저 사용되는 세그먼트는 SR-1056A로 다른 세그먼트와 핀이 다를 수도 있다. 세그먼트에 관한 정보는 링크를 통해서 확인하기 바란다.


출처 링크


회로 구성



프로그램 코드

byte seven_seg_digits[10][7] = { 
  { 0,0,0,0,0,0,1 },  // = 0
  { 1,0,0,1,1,1,1 },  // = 1
  { 0,0,1,0,0,1,0 },  // = 2
  { 0,0,0,0,1,1,0 },  // = 3
  { 1,0,0,1,1,0,0 },  // = 4
  { 0,1,0,0,1,0,0 },  // = 5
  { 0,1,0,0,0,0,0 },  // = 6
  { 0,0,0,1,1,1,1 },  // = 7
  { 0,0,0,0,0,0,0 },  // = 8
  { 0,0,0,1,1,0,0 }   // = 9
 };

void setup() {
  int pinNum = 2;
  // segment init
  for(pinNum = 2; pinNum < 10; pinNum++) {
    pinMode(pinNum, OUTPUT);
  }
  writeDot(0); // start with the "dot" off
}

void writeDot(byte dot) {
  digitalWrite(9, dot);
}

void sevenSegWrite(byte digit) {
  byte pin = 2;
  for (byte segCount = 0; segCount < 7; ++segCount) {
    digitalWrite(pin, seven_seg_digits[digit][segCount]);
    ++pin;
  }
}

void loop() {
  for (byte count = 10; count > 0; --count) {
    delay(1000);
    sevenSegWrite(count - 1);
  }
  delay(4000);
}


실험결과

0부터 1까지 카운트하는 코드로, 아주 잘 출력되었다. 2자리 숫자를 표현하려고했는데 핀에 꼽을 선이 너무많아 다른 방법을 찾아보아야겠다.


"본 제품은 아이씨뱅큐 무상체험단 21기 활동의 일환으로 체험 제품을 제공받아 작성되었습니다."

main page

Javascript를 이용해서 다음 페이지에 파라미터 넘기기 위한 방법이다.

<html>
 <head>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
  <script>
   function setChildValue(index) {
    window.location.href = "subPage.html?index=" + index;
   }
  </script>
 </head>
 <body>
  <button onclick="setChildValue(123)">Click me</button>
 </body>
</html>

sub page

방법 1

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
	<script type="text/javascript">
		$(document).ready(function () {
			var val = location.href.substr(
				location.href.lastIndexOf('=') + 1
			);
			console.log('val : ' + val);
		});
	</script>
</head>
<body>

</body>
</html>

방법 2

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
	<script type="text/javascript">
		function getURLParameter(name) {
			return decodeURI(
			 (RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
			);
		}

		function getURLParameter2(name) {
			 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null
		}
		$(document).ready(function () {
			console.log('val : ' + getURLParameter('index'));
			console.log('val : ' + getURLParameter2('index'));
		}
	</script>
</head>
<body>
</body>
</html>

방법 3

<!DOCTYPE html>
<html>
<head>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
	<script type="text/javascript">
		var getParameter = function (param) {
			var returnValue;
			var url = location.href;
			var parameters = (url.slice(url.indexOf('?') + 1, url.length)).split('&');
			for (var i = 0; i < parameters.length; i++) {
				var varName = parameters[i].split('=')[0];
				if (varName.toUpperCase() == param.toUpperCase()) {
					returnValue = parameters[i].split('=')[1];
					return decodeURIComponent(returnValue);
				}
			}
		};
		$(document).ready(function () {
			console.log('val : ' + getParameter('index'));
		}
	</script>
</head>
<body>
</body>
</html>

iptime 외부접속하기

1. 관리자화면(192.168.0.1) 로 접속하고, 다음과 같이 설정을 변경한다.


2. '네트워크 관리 - 내부 네트워크 설정'을 통해 해당 PC의 IP가 바뀌지 않도록 고정IP로 변경한다.


3. '특수기능 - DDNS 설정'를 통해 외부에서 접속하기 위한 호스트를 설정한다. iptime에서 제공해주기 때문에 따로 도메인을 구입할 필요가 없다.


4. '특수기능 - WOL 기능'을 통해 원격 PC를 실행시킬수 있도록 해당 PC를 추가한다.


5. 'NAT/라우터 관리 - 포트포워드 설정'에서 원격에서 접속하기위한 포트를 추가해준다.


패키지 업데이트 및 업그레이드

$ sudo apt-get update
( 혹은 $ sudo apt-get upgrade )
$ sudo shutdown -r now

라즈베리 파이 설정

$ sudo raspi-config
1. Expand Filesystem : 메모리 공간 확장
2. Change User Password : 암호 변경
3. Enable Boot to Deaktop : 부팅시 X-윈도우 바로실행
4. Internationalisation Options : 지역 설정 - 'ko_KR.UTF-8 UTF-8', 기본 설정 추천
  4-1. Change Timezone : 시간 설정 - 'Seoul'
  4-2. Change Keyboard Layout : 키보드 레이아웃 변경, 기본 설정
5. Enable Camera : 카메라 활성화
6. Add to Rastrack : 라즈베리 파이 사용자 분포 체크
7. Overclock
8. Advanced Options
  8-1. Overscan : 디스플레이 맞도록 설정
  8-2. Hostname : 호스트네임 변경
  8-3. Memory Split : 메모리 할당 관련 설정
  8-4. SSH : SSH 사용 여부 설정
  8-5. Update : raspi-config 툴 업데이트
9. About raspi-config : raspi-config 툴 설명
$ sudo reboot

유/무선랜 설정

유선 정적/동적 IP 지정하기 링크

무선 설정 링크

(iptime 공유기에서 외부접속 링크)

SSH 접속하기

링크

XRDP 접속

설치(라즈베리 파이)
$ sudo apt-get install xrdp
접속(윈도우)
실행(wind + R) > 'mstsc' 입력(원격 데스크톱 연결) > ip 입력후 접속

삼바 접속

1. 설치
$ sudo apt-get install samba samba-common-bin
2. 유저 추가 및 패스워드 설정
$ sudo smbpasswd -a pi
3. 설정
$ sudo vi /etc/samba/smb.conf
  [pi]
  comment  = rpi samba server
  # 공유할 폴더 지정
  path = /home/pi
  # 사용 가능한 유저 지정
  valid user = pi
  # 쓰기 가능 여부
  writable = yes
  # 공유 폴더 목록 보여주기 여부
  browseable = yes
4. 재실행
$ sudo service samba restart


문제점

다음과 같이 ajax로 다른 페이지에 접급하려할 때 에러가 발생하였다.

source

$.ajax(
 {
  type: "GET",
  contentType: 'text/xml',
  dataType: "xml",
  url: 'url address',
  timeout: 4000,
  async: false,
  success: parseXml,
 });

error message

XMLHttpRequest cannot load http://xx.xx.xx.xx/xxx. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 

원인은 ajax로 외부 서버에 접속하려 할 경우에 보안상의 문제 때문이라고 한다. 해결방법에는 여러가지가 있다.


해결방안

이것저것 며칠을 찾아보면서 찾은 각종 해결방법은 아래와 같다.

  1. PHP
    header("Access-Control-Allow-Origin: *");
  2. JSP
    <% response.addHeader("Access-Control-Allow-Origin", "*"); %>
  3. ajax
    dataType의 값을 jsonp로 변경한다.
    $.ajax(
     {
      type: "GET",
      contentType: 'text/xml',
      dataType: "jsonp",
      url: 'url address',
      //timeout: 4000,
      async: false,
      success: parseXml,
     });
  4. open source
    homepagegithub
  5. With jQuery and the Google AJAX Feed API
    $.ajax({
      url      : document.location.protocol + '//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent(FEED_URL),
      dataType : 'json',
      success  : function (data) {
        if (data.responseData.feed && data.responseData.feed.entries) {
          $.each(data.responseData.feed.entries, function (i, e) {
            console.log("------------------------");
            console.log("title      : " + e.title);
            console.log("author     : " + e.author);
            console.log("description: " + e.description);
          });
        }
      }
    });


아두이노에서 날짜, 시간 출력하기.

먼저 아두이노에서 링크를 통해 Time 라이브러리는 받는다. 압축을 해제하고 각 폴더들을 아두이노 라이브러리폴더안에 넣는다. (그냥 압축 풀고 통째로 넣으면 헤더파일을 읽어오지 못한다.)



다운로드 주소
http://playground.arduino.cc/Code/Time
아두이노 라이브러리 경로
C:\Program Files (x86)\Arduino\libraries 혹은
C:\Users\사용자명\Documents\Arduino\libraries

라이브러리를 사용하는 2가지 방법이 있다. 먼저 아두이노 설치경로안에 libraries 폴더 안에 넣거나, Documents 폴더내의 아두이노 폴더에 넣는 방법이다. 다른 점은 크게 없고, 어떻게 화면에 나누어지는가의 차이인 것 같다. 아래 사진은 Documents 폴더 내의 아두이노 라이브러리에 넣은 화면이다.(초록색)


실행하기

코드는 라이브러리 설치 후에 '파일 > 예제'에 있는 TimeRTC 코드를 조금 수정한 것으로, RTC(Real Time Clock)칩에 저장된 값을 불러와서 출력한다.

#include <Time.h>  
#include <Wire.h>  
#include <DS1307RTC.h> 

void setup()  {
  Serial.begin(9600);
  setSyncProvider(RTC.get);  
  setTime(17,39,0,24,2,15);
  if(timeStatus()!= timeSet) 
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");      
}

void loop()
{
   digitalClockDisplay();  
   delay(1000);
}

void digitalClockDisplay(){
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}
시간 설정
setTime(hr, min, sec, day, month, year);
예 : setTime(17,39,0,24,2,15); // 2015.2.24 17:39:00

업로드하고 난 뒤에, 시리얼 모니터를 확인하면 다음과 같은 화면을 보여준다.



관련 문제점

에러 : 'BYTE' was not declared in this scope

에러 : must be const in order to be put into read-only section by means of '__attribute__((progmem))'


결론

먼저 실행하기 전에 컴파일단계에서 에러때문에 꽤나 답답하였다. 위 코드에서 문제점은 현재시각을 출력하지 않는다는 점이다. 앞으로 컴퓨터나 핸드폰의 시간을 받아와서 출력하도록 해봐야겠다. 혹은 인터넷의 시간을 가져오는 방법도 찾아봐야겠다.


참고사이트 링크링크, 링크


문제점

Time.h 을 사용하려는데 발생하는 에러.


해결방안

Time 라이브러리가 있는 디렉토리에서 DateStrings.cpp 파일에서 PROGMEM을 모두 지우고 실행하였더니 에러가 발생하지않았다. 아래 파일은 PROGMEM을 지운 파일이다.

DateStrings.cpp


문제점

아래 코드에서 발생하는 에러

  int  value = 1;
  Serial.print(value, BYTE);
'BYTE' was not declared in this scope

해결방안

  int  value = 1;
  Serial.write(value);

참고사이트 링크

아두이노 온도 센서 사용하기

온도 센서에는 여러 종류가 있다. LM34, LM35, LM36 등이 있으며 각각 온도를 구하는 공식이 약간 다르다. 

LM35 = (5.0 * reading * 100.0) / 1024.0;
TMP36 = (((reading * 5.0) / 1024.0) - 0.5) * 100

이번 실험에는 LM35 를 사용한다. 생김새는 아래 그림과 같이 뒷부분에 LM35라고 적혀있으며 반대쪽은 둥근형태이다. Output은 Analog In에 연결한다.


사진 출처

사진 출처


실험결과

따로 저항도 필요없고 쉽게 연결할 수 있어서 매우 편리하다. 코드는 아래와 같이 간단하며, 두번째 사진은 실행결과이다. 이 점에서 값을 구하는 식이 다르다는 점을 반드시 확인하여야한다. 아무것도 모르고 있을 땐, 센서가 고장난 줄 알고 한참을 헤매였다.




"본 제품은 아이씨뱅큐 무상체험단 21기 활동의 일환으로 체험 제품을 제공받아 작성되었습니다."


참고 사이트 링크, 링크, 링크

아두이노 편집기(IDE) 폰트 변경하기

먼저 '파일 > 환경설정'을 선택하면, 아래 추가적인 환경 설정은 직접 편집할수 있다고 알려준다. 그 경로를 선택한다.


font 부분에 자신의 원하는 폰트를 입력한다.

나눔고딕일 경우 > NanumGothic


블루스택 화면 사이즈, 메모리 변경하기


화면 사이즈 변경
실행(윈도우키 + R) → regedit 실행 → 
HKEY_LOCAL_MACHINE → SOFTWARE → BlueStacks → Guests → Android → FrameBuffer → 0
WindowHeight, WindowWidth 값 변경

메모리 변경
실행(윈도우키 + R) → regedit 실행 →
"HKEY_LOCAL_MACHINE → SOFTWARE → BlueStacks → Guests → Android"
Memory 값 변경

변경 후 재부팅


'대학 생활 > Develop' 카테고리의 다른 글

HTTP 프로토콜의 상태 코드  (0) 2015.01.21
언론사/포탈 뉴스 RSS 목록  (0) 2014.11.18
주요 RSS 목록  (0) 2014.11.18
[Sublime Text 2] Gits에 코드 발행하고 가져오기  (0) 2014.09.10

안녕하세요. DFRduino UNO R3 Beginner Kit 개봉기를 올려보려고합니다.

ICBanQ 21기 체험단을 지원했을 때 그냥 '아두이노 비기너 킷'이라고만 생각하고 지원하였습니다.

그런데 검은색으로 평소 생각했던 파랑색의 아두이노와 달라서 긴가민가했습니다.

찾아보니 이 제품은 아두이노의 호환보드로 DFTobot에서 만든 DFRduino라고 합니다.

(하지만 기존의 아두이노와 100% 호환되며, 성능과 사용법이 모두 같다고 하네요. 참고)

 

먼저 박스를 개봉하고 제품의 모습입니다.


받기전에 사진을 보았을 땐 아주 컸던것 같은데, 직접보니 손바닥 크기로 생각보다 작았습니다.


박스를 열고 난 모습입니다. 첫 느낌은 정리가 아주 잘되어있다고 느꼈습니다.

오른쪽에는 들어있는 제품들의 목록이 적혀있고, 왼쪽엔 각각의 부품, 센서들을 사용하는 방법들이 그려져있는 카드가 들어있습니다. (회로에 대해서는 많이 부족한 저에게 정말 필요한 것이라서 아주 마음에 들었습니다.)


사용설명서와 리스트를 걷어내면 아주 잘 정리된 부품들을 볼 수 있었습니다.


하나하나 빼면서 나열하는데 정말 차곡차곡 잘 정리되어있었고, 처음 시작하기에 알맞은 많은 부품들이 있었습니다.


DFRduino UNO R3의 모습입니다. 라즈베리파이보다 조금 더 작은 크기같고, 기존 아두이노랑 거의 똑같이 생겼습니다.


쉴드 장착후 컴퓨터에 연결하고 테스트 해보았습니다. LED 불 들어오는 것만으로도 엄청난 성취감을 느꼈습니다..

그리고 기존의 아두이노는 ON LED가 파랑색인데 디에프알두이노는 빨간색인 것 같습니다. 처음엔 에러가 난건지 계속 고민했는데 그냥 빨간색 인것 같습니다..(제것만 그런건가요..?)

(그리고 노랑색 LED가 불량이라서 좀 아쉬웠습니다..하나는 브레드보드에 꼽았을 때 치칙!하면서 아예 타버려서 놀랐습니다..)

 

비기너 킷을 개봉하면서 많은 구성물(스위치, 모터, 리모콘, 센서, 알람, 세그먼트, 팬 등)과 잘 정돈되고 각 하나하나 스티커가 부탁되어있음으로 처음하는 사람들에게 아주 괜찮은 것 같습니다. 또한 많은 응용을 할 수 있을것 같습니다.

결과적으로 아주 아주 만족스러운 제품인 것 같습니다.

 

"본 제품은 아이씨뱅큐 무상체험단 21기 활동의 일환으로 체험 제품을 제공받아 작성되었습니다."

equals() 와 hashCode() 는 함께 오버라이드 할 것.

자료형

해시 값 계산 방법

boolean

(value ? 1 : 0)

byte, char short, int

(int) value

float

Float.floatToIneBits(value)

double

Double.doubleToLongBits(value)

 String 및 기타 객체

"test".hashCode() 

package Test;

public class Test {
	int intVal;
	String strVal;

	public Test(int intVal, String strVal) {
		this.intVal = intVal;
		this.strVal = strVal;
	}

	public int getIntVal() {
		return intVal;
	}

	public void setIntVal(int intVal) {
		this.intVal = intVal;
	}

	public String getStrVal() {
		return strVal;
	}

	public void setStrVal(String strVal) {
		this.strVal = strVal;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + intVal;
		result = prime * result + ((strVal == null) ? 0 : strVal.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Test other = (Test) obj;
		if (intVal != other.intVal)
			return false;
		if (strVal == null) {
			if (other.strVal != null)
				return false;
		} else if (!strVal.equals(other.strVal))
			return false;
		return true;
	}

}

이클립스에서는 만드는 방법

단축키 Shift + Alt + S 

Generate hashCode() and equals()... 선택




문제점

Dialog를 화면에 띄우려고할 때, 발생하는 에러.

BadTokenException: Unable to add window -- token null is not for an application

해결방안

대화상자 객체 생성시 파라미터를 확인할 것.

getApplicationContext()를 사용하지 말고, 액티비티명.this를 사용할 것

AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);

int(정수)를 String(문자열)로 바꾸는 여러가지 방법

평소에 정수타입의 변수를 문자열로 바꿀 때 +"" 를 자주 사용하였다. 편리하기도하고 습관이 되었기 때문이다. 그러다가 갑자기 궁금해져서 바꾸는 방법에 대해서 페이스북 생활코딩 그룹에 도움을 청했다. 댓글을 통해서 2012년도에 작성된 String.valueOf(int) vs ""+int라는 글을 보았고, 몇가지 더 추가해서 실험해보았다. 실험에 사용된 코드는 아래와 같다.

코드

package Test1;

import java.io.IOException;

public class TestClass {
	public static void main(String... args) throws IOException {
		for (int i = 0; i < 10; i++) {
			long svo = perfStringValueOf();
			long qqp = perfQuoteQuotePlus();
			long its = perfIntegerToString();
			long sf = perfStringFormat();
			System.out.printf("String.valueOf() : %.3f\t", svo / 1e3);
			System.out.printf("Integer.toString() : %.3f\t", its / 1e3);
			System.out.printf("\"\"+ : %.3f\t", qqp / 1e3);
			System.out.printf("String.Format() : %.3f\n", sf / 1e3);
		}
	}

	private static long perfStringValueOf() {
		long start = System.nanoTime();
		final int runs = 100000;
		String s;
		for (int i = 0; i < runs; i++) {
			s = String.valueOf(i * i);
			if (s.length() < 1)
				throw new AssertionError();
		}
		long time = System.nanoTime() - start;
		return time / runs;
	}

	private static long perfQuoteQuotePlus() {
		long start = System.nanoTime();
		final int runs = 100000;
		String s;
		for (int i = 0; i < runs; i++) {
			s = "" + i * i;
			if (s.length() < 1)
				throw new AssertionError();
		}
		long time = System.nanoTime() - start;
		return time / runs;
	}

	private static long perfIntegerToString() {
		long start = System.nanoTime();
		final int runs = 100000;
		String s;
		for (int i = 0; i < runs; i++) {
			s = Integer.toString(i * i);
			if (s.length() < 1)
				throw new AssertionError();
		}
		long time = System.nanoTime() - start;
		return time / runs;
	}

	private static long perfStringFormat() {
		long start = System.nanoTime();
		final int runs = 100000;
		String s;
		for (int i = 0; i < runs; i++) {
			s = String.format("%d", i * i);
			if (s.length() < 1)
				throw new AssertionError();
		}
		long time = System.nanoTime() - start;
		return time / runs;
	}
}

결과


첫 실행 속도로 보았을 땐 Integer.toString() < String.valueOf() < ""+ < String.Format()  이다. 하지만 여러번 반복하고 평균적으로 보았을 땐 ""+ < Integer.toString() < String.valueOf() < String.Format() 이었다.

속도와 간단함으로 보았을 땐 ""+ 이었지만 추후에 좀더 성능을 고려해서 다시 실험해보아야겠다.

Mysql 설정.pdf



+ Recent posts