1. 강남 학군은 10년 후에도 강세를 보일것이다 - 반대의견 : 학생수는 줄고있어서 자녀가 없는 가정이 늘고 학원이 줄기 시작하면, 비싼지역도 줄어들 수 있다.
2. 사람이 몰리는 지역에 돈과 인프라가 몰린다. - 반대의견 : 서울에 건축한지 오래되어가는 곳들 슬럼화되었고 안전상의 문제가 생기는데 비싸기만 하다면 상가가 옮겨간다. 가로숲길,샤로숲길 무슨무슨 길에서 성수 힙지로 문래동 등의 지역으로 사람이 몰리는 곳이 바뀌어서 기존 인기지역은 고정되지 않을 확률이 높다( 인스타 사진 감성이나, 음식의 트렌드와도 상관관계있어보임)
3. 대부분의 대기업을 비롯한 주요 기업은 서울 또는 서울근교에 위치해있어 결국 사람들도 서울 주요도심 (강남, 영등포, 을지로등등) 지역에서 대중교통 및 자차로 30분 이내의 지역을 선호할 것이다 - 반대의견 : 지금은 기업들이 인력난에 시달리고 있으며, 점차 재택과 출근의 공존문화로써 가는 회사가 많아지는 추세이며, 출근을 선호하는 회사들은 재택혹은 재택출근 하이브리드 기업들에 비해 직장 선택의 기준경쟁에서 밀릴 것이다.
4. 대규모단지 아파트들은 점진 지속적인 상승세일것이고 사람들의 우선선호 대상이 계속될것이다. - 반대의견 : 아파트의 장점은 대부분 사는 환경이 크게 다르지가 않아서 환금이 쉽다는 장점이 있으나, 우리나라도 점차 개인 공간및 침해되지 않을 사적인 공간에 대한 욕구가 커지기 때문에, 당장 모든 아파트 거주민들이 주택으로 가지는 않겠지만, 지금처럼 아파트일변도보다는 주택선호하는 사람은 점차 많아질 것이다. (법의 규제에 따라 달렸다)
결론 : 인프라와 시설이 서울과 경기 대도시에 대부분 몰려있기 때문에 당분간은 수요는 계속 될것이다. 다만 지금 20~25살의 청년들이 35~40살 실수요자가 되었을때, 자녀를 낳지 않으려 하는 성향이 계속될것이고, 학군으로 인한 집값 상승 지역이 가장 먼저 빠지고 ( 대략 10년~15년이내) 병원 및 교통이 편한지역을 제외하면 슬럼화가 가속될것이다. 서울에서 좀더 싼집을 찾는 사람들은 경기도나 서울 인근 대도시로 갈것이고, 비싸서 개발이 쉽지 않은 지역은 사람이 점점 빠지는 지역도 생길것이라 생각한다. 부동산도 양극화가 더 심화될것이라 예상한다.
22.06.07 삼프로 글로벌 시황에서 들은바로는 러시아 주식은 다 회복했다고 하며, 쌓아둔 외환은 충분하다고 하는데 SWIFT망을 이용하지 못해 발생한듯 하다.
최근에 브릭스(BRICS) 모임에서 SWIFT에 대응되는 결재망을 그들끼리 구성한다는 이야기가 나오는거보면, 미국과 유럽연합및 그 우방대 BRICS 의 대결구도로 가는 모양새이다.
아이러니 하게도, 러시아가 쌓아놓은 달러유보금은 유럽소재한 은행들에 있는데, 결재망을 이용하지 못해 국채 이자를 지급하지 못해 발생한 상태이며, 대상은 달러,유로화와 같은 외채로 발행된 채권이라고 한다.
유럽에 관한 상황을 기사 및 글로벌 시황같은 매체물로 들었을 때 지금은 여름이라서 난방 수요가 높지 않지만, 추위가 오기시작하면 유럽지도자들은 지지율을 잃고 난방에 이용할 가스가 부족하지 않게 해결하지 못하면, 친러성향 혹은 중도성향의 정치인으로 교체될 수도 있다고 생각한다.
그래서 지지율이 떨어진 마크롱이 지금 본인이 중재하겠다고 나서면서 유럽에서의 큰형님 역할을 하고싶어 하는것 같은데, 메르켈 전총리의 역할을 대신할 수 있을 것 같지는 않다. 심지어 우크라이나에 양보를 종용하고 있는 상황이라서 여러모로 혼란하다.
브릭스에게 약한것이 지금 반도체분야인데, 러시아와 우크라이나가 전쟁을 끝내지 못한 채 올 겨울이 오면 최악의 경우, 중국이 대만을 위협할 수 있는 상황도 올것같다. 내가 러시아나 중국 전술가라면, 유럽으로 가는 가스관과 가스선박을 차단하고, 중국이 대만을 침공하는 양동작전이 가장 최적의 판단이라고 생각한다. 그래서 그런 최악의 상황에 도달하지 않도록 미국과 사우디의 관계개선이 중요한데, 바이든과 민주당의 성향상 쉽지 않을 것이라고 생각한다.
국제정치에서는 역시 적을 만들지 않는것이 중요하다. 나의 성향과는 관계없이. 제발 전쟁도 멈추고, 돌도끼와 활로 싸우게 되는 일은 없기를 바란다.
본격 장마가 시작이라는데, 23일은 잠깐 내리다 그치고 24일은 오는둥 마는둥 가뭄이 심각하다는데, 비가 많이 내렸으면 좋겠다. 다치는 사람 없이,
한국주식은 이제 저점이라는 사람이 많다는거보니 더 내려갈것 같다. 잠깐 반등할것도 같아보이지만, 유통원자재대란 + 고유가(약간 내렸지만 아직 멀었다) 에 인플레대응하는 금리인상까지 악재투성이이다.
한국주식은 코스피 52포인트상승 코스닥 35포인트 상승
LG디스플레이 - 다음분기 매출이 오를것 같은데 지금 재무재표는 좋지않다. 15200
-> 3프로에서 기술과 생산설비에 지속투자 비용이 높아서 장기로 들고 있기는 적합치 않다고 했는데, OLED 관련한 계약은 공시에서 몇개좀 나왔는데 더 분발 해줬으면...
미국주식장은 다소 반등
리얼티인컴을 계속 매수하려하니, 몇일사이에 올라버려 매수할수가 없다. 68.66
어펌도 16불을 찍을때 물타려하니 다시 조금 올라왔다 22.85
ASML은 EUV 매출은 몇년간 지속될것이기 때문에(공장에 불났다는 기사를 봤었지만) 꾸준매수할 계획이다. 512.3
루시드는 당분간 관망이다. 물은 언젠가는 타야하지만, 재무재표나 매출에 관한 시그널이 좋아져서 회복세에 돌입하면 사도 늦지 않을것 같다. 19.05
엔비디아는 월급타면 한두개씩 주워도 될것같다. 4천번대 시리즈와 인공지능에서 이용하는 GPU를 이용한 학습모델 개발은 앞으로 계속 많아질것이기 때문이다. 168.65
테슬라는 반등하는 모양세지만, 사이버트럭이나 다음세대 인공지능(자율주행)이 나오지 않는이상 사고율을 확 줄이기는 힘들것 같아서 역시 관망이다. 734.0
벨로다인은 반등하는 모양세고, 돈이 생길때마다 조금씩 사고 있는데, 23일과 24일 GM자동차 자율주행관련한 스파이샷에서 벨로다인 라이다를 장착하고 있는모습을 봐서, 거의 모든 자동차 회사들이 필수가 아닌가 싶다(개인적 생각) 역시 돈생길때마다 적금처럼 사고있다. 1.275
이전 블로깅에서 클래스파일을 추가하고, 솔루션내의 파일들을 정리 하였는데, 이번에는 파일입출력을 간단히 다뤄보겠다.
처음했던 기능적기와(기능명세) 마찬가지로 구현할 기능을 세세하게 말로 풀어서 써보겠다. 이 기능에 대한 설명이 명확하지 않으면, 프로그램을 작성하는데에 있어 수정을 많이 하거나 생각지 못한 부분에서 버그가 생길 수 있으며, 정해지지 않은 기능을 프로그램 작성중에 발견하여 대대적인 수정이 필요한 경우가 생긴다.
파일입출력하기
- 파일을 읽기기능 - 지정된 경로를 읽을 것인가? 경로를 입력받아 읽을것인가를 정해야한다.
- 파일을 쓰기기능 - 지정된 경로에 파일을 쓸것인가? 파일이 없다면 새로 생성할 것인가? 어떤 형태로 파일을 쓸것인가?
위와같이, 파일 입출력시 예상되는 오류부분을 적는데 로또번호를 텍스트로 읽고, ( 기존번호 ) 텍스트파일 형태로 출력할 것이기 때문에 기능을 적는것이 필요하다. 여기에서는 정해진 경로에 지정하도록 해보겠다.
지난번 클래스파일 추가하기를 이용하여 FileController.cs 라는 class 를 추가해주자.
파일을 추가했다면, 위에서 적었던 기능명세를 주석을 이용하여 클래스내에 적어주자. 이 기능명세는 곧 함수가 된다고 생각하면 된다.
짧은 팁으로, 영역 전체를 주석처리 하는 기능은 Ctrl + K + C 이다. 해제기능은 Ctrl + K + U 다 프로그래밍을 하다보면 굉장히 자주 사용하게 되므로, 10번 정도 주석하고 풀기를 해서 자연스럽게 사용할 수 있도록 숙달해두자.
기능명세를 주석처리해둔 모습 기능은 곧 함수가 된다. (단축키는 Ctrl+k+c)
위처럼 기능명세를 주석으로 추가 했다면, 기능에 맞는 이름을 함수로 만들어보자.
파일읽기는 ReadFile() 파일쓰기는 WriteFile()
보면서 느꼈겠지만, 암묵적으로 클래스의 첫자와 함수의 첫자는 대문자로 쓰는것이 관습이다. 대다수의 변수는 소문자로 시작을 한다.
기능명세 밑에 함수를 작성하였다.
함수를 추가했으면 함수에 어떤기능이 있는지 세부적으로 보자. 여기서는 정해진 경로를 읽을 것이기 때문에
readPath, writePath 라는 이름의 string 타입의 변수를 클래스 아래에 두개 만들어두자.
여기까지 했으면, 솔루션 탐색기에서 프로젝트 우클릭을 통해 프로젝트 폴더로 가보자.
여기서 파일탐색기에서 폴더열기를 누르면, 프로젝트의 폴더가 열리게 된다.
폴더가 열리면 datas 라는 폴더를 만들어보자. 우클릭을 해서 새폴더를 만들고 이름을 datas로 바꾸어도 되지만,
컴퓨터를 잘 아는척을 위해 새폴더만들기 단축키인 Ctrl + Shift + N 을 눌러 새폴더를 만들고, F2를 누르면 이름을 변경할수 있게 되는데 datas로 이름을 바꿔주자.
이제 폴더를 만들었으면, 코드 작성하던 곳으로 돌아가서 readPath 와 writePath 의 경로에 다음과 같이 변경해주자.
문자열을 처리할때 경로의 역슬래쉬를 쓸경우는 문자열 앞에 골뱅이 또는 at (엣) sign 이라고 하는 특수문자를 추가해준다.
경로를 다 적었으면, 보통의 프로그램이라면 관행적으로 가지고 있는 InitPath 라는 함수와 workingDirectory 라는 string 타입의 문자열 변수를 만들어준다. ( 참고로, 클래스내의 함수 밖 변수의 정식 명칭은 멤버변수라고 한다. 함수내의 변수는 로컬변수 라고 한다.)
로컬변수와 멤버변수 예시
위처럼 함수와 멤버변수를 작성했으면, 프로젝트내의 경로에 접근해보자.
그전에 라이브러리 선언 부분을 System.IO 를 쓰고 나머지는 다 지우겠다. 그리고 InitPath 함수 내부에 다음처럼 작성해보자.
경로를 절대경로로(드라이브부터 프로젝트까지) 특정해버리면, 시스템이 달라질때마다, 프로그램을 새로 컴파일 ( 사람이 작성한 부분을 컴퓨터가 읽을 수 있도록 바꿔주는 기능 ) 해야 하므로 컴퓨터가 달라지더라도 이 프로그램이 실행되도록 상대경로로 지정할 필요가 있다. ( 잘 모르면 구글에서 검색해보자 )
왼쪽은 mylist.txt 라는 파일이 경로에 있으면 존재라는 글자와 경로가 출력되게 해두었고, 없으면 없음 이라고 출력되게 하였다.
우측은 FileControll 클래스의 인스턴스 ( 객체라고도 한다) 를 만들고 InitPath 함수를 호출시켜주었다. 위의 로또출력부분은 원활한 테스트를 위해 잠시 주석처리를 해두자. ( 주석은 영역설정하고 Ctrl + K + C ) 추가로 콘솔창이 바로 꺼지는것을 방지하기 위해 아래 한줄도 추가해주자.
아직 없어서 없음이 떴다. 그렇다면 콘솔창을 종료하고, 없으면 파일을 만들어 주도록 해보자.
먼저 MakeFile 이라는 함수를 추가하고 파라미터는 string path 로 추가해주자.
위처럼 파라미터가 있는 함수를 만들고, 파일을 만드는 부분을 추가해보자.
파일이 없으면 만들도록 하고 저장한후 실행 (F5) 해보자.
실행하면 에러가 없다면 아무것도 뜨지 않는 콘솔창이 뜰텐데 끄고, 솔루션탐색기에서 솔루션 폴더로 가보자.
아무내용이 없는 파일이 생긴것을 확인할 수 있다. 위에서 폴더를 직접 만들었는데, 이를 응용하면 폴더도 생성할 수 있다.
이제 내가 만든 로또번호를 파일에 저장을 해보자. 그전에 읽거나 저장하는 경로가 두개이기 때문에 ( 지금은 같지만 이후에바뀐다.) 경로를 가져오는 간단한 부분을 작성해보자.
위의것은 나열자라고 하며, 그냥 나열하는 기능이 있는데 데이터타입을 특정하거나, 값을 부여할 수 있다. 자세한것은
C# 나열자 라고 구글에서 검색하면 된다. 아래의 GetFullPath 는 나열자를 파라미터로 사용하여 경로를 가져온다.
이 함수를 읽어보면, 파라미터가 READ 면 workingDirectory + readPath 를 가져오고 READ가 아니면 orkingDirectory + writePath 를 가져온다는 의미이다.
이제 출력할 필요가 없으므로 위에서 만든 함수를 이용하여, InitPath 함수를 정리해보았다.
여기서 var path 에서 var는 최신언어들에서 제공되는 특성인데, 타입을 특정하지 않고 컴파일타임에 결정된다. ( 이를 암시적 형식 지역변수 라고한다)
즉 위의 코드에서 path 는 GetFullPath 의 return 타입이 string 이므로 암시적으로 string이 된다.
읽고 쓰고 경로를 조금 바꿔주자.
그리고 만들어진 로또번호를 FileController 객체에 전달하기 위해 Numbers 클래스를 조금 변경해주겠다.
List 를 멤버변수로 바꿔주고, 저장하기전 보기좋게 바꿔주기위해 GetStringFormatValue 라는 함수를 만들고 작성해준다.
내용은 다음처럼 작성해준다. 이부분은 뽑아진 번호를 쉼표로 구분하게 한다.
위처럼 바꿔줬으면 FileController 로 돌아와서 WriteFile 의 파라미터를 다음과 같이 바꿔주고 내용을 작성해준다.
Number 클래스에서 만든 로또번호를 파라미터로 전달하고, 로또번호를 파일로 저장한다.
마지막으로 main 함수로 가서 다음처럼 바꿔준다.
기본적인 파일 출력은 끝났다 저장하고 F5를 눌러 잘 실행되는지 확인해보자.
실행하면 파일이 만들어 지느라 한번 오류가 날수 있는데, 이부분은 다음에 다루기로 하고 다시 실행해주면 위와같이 이번주 로또번호가 파일에 잘 출력된것을 볼 수가 있다.
여기까지 따라왔다면 프로젝트 폴더의 bin\Debug 폴더로 가면 아래처럼 파일들이 생성되어있는것을 볼 수가 있는데
#1 번에서 만들었던 추출기는 번호 정렬이 안되어있다. 정렬 방법은 많지만, 이곳에선 숫자 6개만 정렬하면 되기 때문에 제공되는 함수를 쓰겠다.
기본은 오름차순 정렬( ascending order ) 이며 내림차순 정렬 ( descending order ) 을 위해서는 내림차순을 비교대상데이터 비교를 어떻게 할것인지에 대한 인터페이스와 인터페이스를 Realize (구현화) 한 클래스를 파라미터로 작성하면 된다. 여기까지 따라오는데 아직 필요 없는 내용이지만 궁금한 분들은 문서를 참고 바라고 댓글을 남겨주시기 바란다.
프레임워크 버전도 같을 필요는 없다. 로또번호 추출기에서 사용할 라이브러리는 대부분 기본적인 라이브러리만 제공되면 만들 수 있는 수준이다.
프로젝트를 만들고 나면 다음과 같은 화면이 보일 것이다.
프로그램을 작성할 기본적인 준비는 끝났다.
이제 로또번호를 추출한다는 기능을 아주 세세하게 분리해보자
1. 로또번호는 1부터 45까지 이다.
2. 로또는 중복되지 않는 6개의 숫자를 뽑는다.
이렇게 기능을 적는것을 기능명세라고 한다.
본격적으로 작성을 시작해보자.
위와같이 먼저 Program 이라는 class 아래에 이름이 Numbers 라는 class 를 만들어두자.
public 과 class 를 왜 치는지 궁금할텐데 나중에 설명할테니 먼저 따라하는데 중점을 두자.
위와같이 이름이 Numbers인 Class 밑에 CreateNumbers() 라는 함수를 만들었다. 이제 기능명세를 주석으로(설명-컴파일되지 않음) 달아보자 주석은 슬러쉬 // 두개로 달 수 있다.
위와같이 프로그램을 본격적으로 작성하기 전에 기능을 기록해두면 로직을 작성에 도움이 된다.
다음은 변수라는 것을 작성해 볼것이다.
위와같이, 기능명세를 해둔부분의 기능을 구현하기 위해 먼저 정해진 수를 타입이 정수인(int) 변수로 만들어보았다.
이제 임의적으로 6개를 뽑는다는 부분인데, 임의적으로 사용한다는 말인 랜덤은
System.Random 이라는 클래스를 사용해보겠다.
위와같이 Type이 Random 이고 이름이 ran 인 랜덤변수를 함수내에 만들었다.
이제 뽑기 즉 추출을 하고 담을 바구니 같은 역할을 하는 LIST 를 하나 만들어 보겠다.
타입 ( type ) 이 정수형 ( int ) 만 담을 수 있는 List 를 위와같이 이름을 list 로 하여 만들었다.
이제 정해진 조건을 만족할때까지 계속 반복 실행하는 반복문 while을 사용하여 번호 6개를 뽑아보도록 하자.
List 가 바구니 역할을 한다고 했는데 List 안에 담긴 갯수는 Count 라는 읽을수만 있는 프로퍼티(약간 다른 개념이지만 지금은 변수라고 이해하면 된다) 를 제공하니 Count를 사용하겠다. 어떤 기능을 제공하는지는 타입에 F12 를 누르면 제공하는 기능들을 볼수 있다.
다음과 같이 List 타입을 클릭 혹은 더블클릭하고 F12를 누르면,
이처럼 List 가 제공하는 많은 기능들을 볼 수가 있다. 지금은 이기능들중에 Count 만 써볼것이다.
먼저, 반복문인 while를 계속 실행시키는 조건을 만들려면 처음에 적어둔 기능중에 임의로 6개를 추출한다. 를 풀어서 쓰면
1부터 45까지의 숫자중 임의로 6번을 뽑는다 -> 숫자를 6번을 반복하여 뽑는다 이말은 결국 List에 6개가 담기지 않으면 실행한다. 라고 조건을 쓸수 있다.
위와같이 반복문 while 의 괄호 ( ) 안에 list.count 리스트의 갯수가 6개보다 작으면 실행이라는 조건을 써 넣었다.
정말로 6번을 실행하는지 테스트를 해보자.
List 에 숫자를 넣는 방법은 List.Add 를 사용하면 되는데 다음과 같다.
List.Add() 함수를 사용하여 숫자 0을 넣어보았다. 이것이 6번 들어가는지 확인 할수 있는 방법은 여러가지가 있는데,
가장 기초적인 방법인 출력을 해보겠다.
출력은 Console.WriteLine() 을 사용한다.
그리고 콘솔창이 실행을 완료하고 바로 꺼지는 것을 방지하기 위해 잠시 입력을 받도록
Console.ReadKey() 로 써주겠다.
위와같이 작성을 하고, 어디에선가 이 함수를 호출을 해야한다.
이 함수는 이름이 Numbers 인 Class 아래에 있었는데, 처음 작성할때 자동으로 만들어져 있던 Main 부분에 다음과 같이 작성한다.
모든 프로그램은 Main(string[] args) 가 실행되게 되는데 위의 작성된 부분을 설명하자면,
Numbers num = new Numbers(); -> 타입이 Numbers 인 클래스 이름은 num 인 인스턴스 변수를(객체라고도한다) 만들었다.
num.CreateNumbers(); -> num 변수의 함수 CreateNumbers 를 호출한다 이다.
기능명세 부분 int min = 1; 과 int max = 45; 부분에 주석처리를 한다. 주석처리를 하는 이유는 사용하지 않는 내부변수는 컴파일 에러를 일으킬수 있기 때문이다.
위와같이 작성을 해주고 저장을 한후 ( 컨트롤+S키) F5키를 눌러본다.
위와 같이 검은색 창 (콘솔창이라고 한다)이 뜨며 hello world! 가 6번 뜨는것을 보아 반복문 while은 6번을 실행함을 확인 할 수 있었다.