1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
        void OldDeleteLog()
        {
            // 경로 + 형식을 통하여 폴더 내 해당 파일들을 추출하기 위한 변수
            string path = savePath + "*.log";
            // 핸들을 통하여 path에 해당하는지 검사
            _finddata_t fd;
            intptr_t handle = _findfirst(path.c_str(), &fd);
            // 파일이 없다.
            if (-1 == handle) return;
            int result = 0;
            // 경로를 통해 파일 이름을 가져온다.
            do
            {
                int year = 0, month = 0, day = 0;
                char *pt1 = nullptr, *pt2 = nullptr, temp[16= { 0 };
                char yearCopy[4= { 0 }, monthCopy[2= { 0 }, dayCopy[2= { 0 };
                // 파일이름에서 20으로 시작하는 부분(연도)을 가르킨다.
                pt1 = strstr(fd.name, "20");
                pt2 = strstr(fd.name, ".log");
                // 파일 포맷에서 날짜 추출 X_X_yyyy-mm-dd.log에서 "yyyy-mm-dd"를 추출한다.
                // 20으로 시작하는 부분을 copy하고 .log로 시작하는 부분을 자른다.
                // 현재 "yyyy-mm-dd" 상태
                memcpy(temp, pt1, 10);
                memcpy(yearCopy, &temp, 4);
                memcpy(monthCopy, &temp[5], 2);
                memcpy(dayCopy, &temp[8], 2);
                // 날짜를 문자열 -> 정수로 변환
                year = atoi(yearCopy);
                month = atoi(monthCopy);
                day = atoi(dayCopy);
                // tm_st = 뺄 기준이 되는 날짜 변수 ( 현재 날짜 )
                // tm_nd = 뺄 날짜 ( 파일 날짜 )
                time_t tm_st, tm_nd;
                struct tm fileDay;
                memset(&fileDay, 0sizeof(tm));
                // 년도는 1900년부터 시작, 월은 0부터 시작이기에 
                // 년도 - 1900 / 월 - 1
                fileDay.tm_year = year - 1900;
                fileDay.tm_mon = month - 1 ;
                fileDay.tm_mday = day;
                
                tm_st = mktime(&fileDay);
                time(&tm_nd);
                // 날짜 차이를 구하고 tm_day에 일수를 set
                double d_diff = difftime(tm_nd, tm_st);
                int tm_day = static_cast<int>(d_diff / (60 * 60 * 24));
                
                // 날짜의 차이가 save_day와 같거나 크면 
                // 해당 경로의 Log 파일을 삭제
                if (tm_day >= save_day)
                {
                    // 경로 + 파일 이름 지우기
                    char deleteFilePath[100];
                    ZeroMemory(deleteFilePath, sizeof(deleteFilePath));
                    strcat_s(deleteFilePath, sizeof(deleteFilePath), savePath.c_str() );
                    strcat_s(deleteFilePath, sizeof(deleteFilePath), fd.name );
                    // 해당 경로의 파일 지우기
                    remove( deleteFilePath );
                }
                // 해당 날짜 - saveDay가 크면 해당 파일 삭제.
                result = _findnext(handle, &fd);
            } while (-1 != result);
            _findclose(handle);
        }
cs




예를들어 보겠습니다.


SVN 서버상에서의 버전은 rev #116, 나의 로컬 버전은 #119라고 가정하였을때.

Commit 명령을 실행하면, 오류가 납니다. SVN 내부에서는 #117, #118을 찾으려고 하기 때문입니다.


이 문제를 해결하기 위해서는 SVN 서버상의 #116을 Check Out하고, 로컬 버전인 #119를 Export 명령을 통해 Check Out받은 #116에

덮어 씌웁니다. 그 상태로 Commit을 하게되면, 변동사항이 반영되어 #117로 로드됩니다.







1. 문자열


파이썬에서는 문자를 " 혹은 '로 묶어서 표현 합니다. 서로 쌍이 맞아야 합니다.


' string ', " string " 처럼!


만약 print 함수를 통하여 인용을 나타내고 싶을때는 """ 혹은 '''을 사용하면 표현 가능합니다.


예를들어 print(""" 영원에 살고 순간에 살아라 영원히 살 것처럼 일하고 금방 죽을 것 처럼 사람들을 대하라. - 리히텐베르크""")와 같이 말이죠!!!


또는 \' \"의 에스케이프 문자를 이용하여 표현이 가능합니다.


문자열을 더하거나 같은 문자열을 반복 하고싶을때는 +, *의 연산자를 사용하면 됩니다.

"hello" + "world" = "hello world"

"re" * 3 = "rerere"


문자열의 각 문자는 인덱스를 통하여 접근 가능합니다.


c = "hello"

c[0] = h 출력

c[1] = e 출력


** 문자열 슬라이싱 **


변수명 [시작위치:끝위치]를 이용하여 문자열을 꺼낼수 있습니다.

c = "hello"

c[0:3] = 'hel'과 같이 말이죠!

시작이나 끝을 생략 할 경우는 시작 혹은 끝으로 간주 됩니다. 또한 -를 통하여 문자열 끝부터 문자열 시작 까지도 가능!

c[-1] = "hello


2. 리스트


값의 나열을 담는 자료형. 순서가 존재하며 여러 종류의 값을 담을 수 있을뿐 아니라 인덱싱을 통한 접근, 슬라이싱을 통한 접근이 가능합니다.

리스트를 만드는 방법은 다음과 같습니다.

animal = ['dog', 'bird', 'cow']


 멤버함수명

설명 

 append()

 리스트의 뒤에 값을 추가.

 insert()

 원하는 위치에 값을 추가. 

 extend()

 튜플 혹은 리스트 등의 여러 값을 한 번에 삽입 

 index()

 어떤 값이 어디에 존재하는지 반환 

 count()

 현재 값의 개수를 반환 

 pop()

뒤에서 부터 값을 뽑아낸다.  

  remove()

 해당 값을 삭제 

  sort()

 순방향으로 정렬

  reverse()

 역방향으로 정렬


+연산자를 통하여 삽입이 가능하다. 그러나 튜플이나 리스트가 아닌 문자열을 'abc'와 같이 넣을 경우 'a' 'b' 'c'의 형태로 쪼개어 들어갑니다.


3. 세트 


수학의 집합과 같다.


union

매개변수로 들어가는 세트와의 합집합을 반환 

intersection() 

매개변수로 들어가는 세트와의 교집합을 반환 

- 연산자 

 차집합을 반환

| 연산자

 합집합을 반환

& 연산자

 교집합을 반환





4. 튜플


()로 묶어서 표현하며 읽기 전용이다. 속도는 리스트에 비해 빠르다.


 count()

 현재 값의 개수를 반환 

 index()

 어떤 값이 어디에 존재하는지 반환 



5. 딕셔너리


key와 value로 구성되어 있으며 가장 많이 사용하는 자료구조

예) a = dict(a=0, b=1, c=2)

   >>>a

   {'a':0, 'b':1, 'c':2} 

없는 키를 사용 할 경우 오류가 발생.

 item()

 딕셔너리의 모든 키와 값을 튜플로 묶어 반환

 key()

 키를 반환

 value()

 값을 반환


6. 얕은복사와 깊은 복사


파이썬에서의 모든 변수는 해당 객체의 주소를 갖고 있다. 그러므로 주의 해야 할 점이 있는데

아래의 예제와 같은 경우와 같이 복사 생성을 할 때에는 주솟값이 복사가 된다.

a = [1, 2, 3]

b = a 

a[0] = 4

>> b

b [ 4, 2, 3] 의 결과와 같이 b는 a의 주소값을 복사 한 것이다.

고유한 값인 아이디를 반환하는 함수를 사용하면 다음과 같다.

id(a), id(b)

(180000, 1800000 )


이를 해결하는 방법은 copy 모듈을 import하고 deepcopy()함수를 사용하면 해결 할 수 있다.





'프로그래밍 > Python' 카테고리의 다른 글

[파이썬 기초 문법 - 3] 제어관련  (0) 2019.02.20
[파이썬 기초 문법 - 2] 함수  (0) 2019.02.20

섀도잉

int num = 10; (전역변수) void A(){ int num = 20; Console.WriteLine( num );}

위와 같이 코딩을 하였을 때, 콘솔 창에 출력되는 것은 함수 A에서 생성된 num의 값인 20이다.

이와 같이 특정 영역에서 이름이 겹쳐져 다른 변수를 가리는 것을 섀도잉 이라고 한다!


하이딩

class Program { class Parent { public int variable = 273; } class Child : Parent { public string variable = "shadowing"; } static void Main(string[] args) { Child child = new Child(); Console.WriteLine(child.variable); } }

하이딩과는 달리 부모 클래스와 자식클래스 간에 동일한 이름으로 변수를 생성하여 사용하는 상황이다.

Main문을 보았을때 과연 무엇이 출력 될 것이라고 생각하는가?

정답은 ? " Shadowing "이 출력 된다. 섀도잉과 비슷하게 가장 가까운 클래스 내부의 문자열 변수를 사용한다고 생각하면 된다.

하이딩을 사용하는 것은 정상적인 상속을 막으므로 되도록이면 변수명을 다르게하여 하이딩 상황이 일어나지 않도록 하는 것이 좋겠다.






//< 함수 >

public static IEnumerable<T> FindLogicalChildren<T>(DependencyObject obj) where T : DependencyObject
{
if (obj != null)
{
if (obj is T)
yield return obj as T;
foreach (DependencyObject child in LogicalTreeHelper.GetChildren(obj).OfType<DependencyObject>())
foreach (T c in FindLogicalChildren<T>(child))
yield return c;
}
}
//< 호출 부분 >
foreach (var a in FindLogicalChildren<ContentControl>(this))
{
if (dic.ContainsKey(a.Name))
{
if (a is GroupBox)
{
GroupBox grb = (GroupBox)a;
grb.Header = dic[a.Name];
}
else if (a is TabItem)
{
TabItem cvs = (TabItem)a;
cvs.Header = dic[a.Name];
}
else if (a.Content is String)
{
a.Content = dic[a.Name];
}
}
}

자식 컨트롤을 재귀적으로 탐색하여 리턴하여주는 함수를 통하여 모든 버튼을 반환한다.
그러나 Canvas와 TabItem의 Text는 Content가 아닌 Header를 쓰기 때문에 따로 검사를 해주어야 한다.
이 방식을 이용하여 이미 개발되어 있는 프로젝트의 각 컨트롤 추출 및 입력으로 다국어 지원을 쉽게 해결 할 수있었다.






+ Recent posts