python의 내장함수를 사용할때 매우 유용하다.

 

def plus_on(arr):
    return arr+1

a=[1,2,3]

#정의한 함수 사용
print(list(map(plus_on,a)))
출력 : [2,3,4]

#함수 없이 람다 사용
print(list(map(lambda x: x + 2, a)))
출력 : [3,4,5]

#간단한 람다 표현식
plus_two = lamnda x: x+2
print(plus_two(1))
출력 : 3

'Program > Python' 카테고리의 다른 글

Sinc 함수 구현  (0) 2021.05.06
K번째 큰 수  (0) 2021.05.06
2차원 리스트 다루기  (0) 2021.04.13
List 다루기(2/2)  (0) 2021.03.22
List 다루기 (1/2)  (0) 2021.03.21
#1x3 행렬 만들기
a=[0] * 3
print(a)
#출력 : [0,0,0]

#3x3 행렬 만들기
b = [[0] * 3 for  _ in range(3)]]
print(b)
#출력 : [[0,0,0],[0,0,0],[0,0,0]]

#3x3 행렬 특정 위치 값 수정 하기
b[1][0] = 2
print(b)
#출력 : [[0,0,0],[2,0,0],[0,0,0]]

#3x3 행렬 출력하기
for x in b:
	print(x)
#출력
[0,0,0]
[2,0,0]
[0,0,0]

for x in b:
	for value in x:
    	print(value, end=' ')
    print()
#출력
0 0 0
2 0 0
0 0 0 


 

그래프 알고리즘 다룰때 자주 사용한다.

2차원 배열 데이터 처리는 알아두면 매우 유용!

'Program > Python' 카테고리의 다른 글

K번째 큰 수  (0) 2021.05.06
람다 표현식  (0) 2021.04.24
List 다루기(2/2)  (0) 2021.03.22
List 다루기 (1/2)  (0) 2021.03.21
문자열 내장함수  (0) 2021.03.15

1. 원하는 인덱스 범위 출력하기

a = list(range(0,10)) # list생성 [0,1,2,3,4,5,6,7,8,9]
print(a[:3])	      # list 0 ~ 2 인덱스 출력
print(a[1:3])         # list 1 ~ 2 인덱스 출력

2. 반복문 활용 방법

a = list(range(0,10)) # list생성 [0,1,2,3,4,5,6,7,8,9]

for i in range(len(a)):# i는 0~9까지 순환
	print(a[i])
    
for i in a:            # i에게 값 타입 반환 value
	print(i)
    
for i in enumerate(a): # i에게 튜플 타입 반환 (index, value)
    print(i)
    
for index, value in enumerate(a): # index에게 a의 index 반환, value에게 a의 value값 반환
    print(index, value)
    
isOver = all(11>x for x in a)    # list a의 값이 모두 11을 넘기지 못하므로 True 반환
isUnder = all(11<x for x in a)    # list a의 값이 모두 11을 넘기지 못하므로 False 반환

3. 값 변경

a = list(range(0,10)) # list생성 [0,1,2,3,4,5,6,7,8,9]

a[0] = 2              # list변경 [2,1,2,3,4,5,6,7,8,9]

1. 선언

a = list()				# list 생성
b = []					# list 생성
c = [1,2,3]				# 1~10까지의 list 생성
d = list(range(1,11)) 			# 1~10까지의 list 생성

2. 인덱스 접근

a = [1,2]	#list 1~2 생성
print(a[1]) # 2 출력

3. list 끼리 더하기

a = [1,3]	#list 1,3 생성
b = [3,5]   #list 3,5 생성
c = a + b   #list 1,3,3,5 생성

4. list 값 추가 및 제거

a = []	#list 생성

a.append(6) 	# list에 추가 6 저장, list 상태 : 6
a.append(7) 	# list에 추가 7 저장, list 상태 : 6, 7
a.append(8) 	# list에 추가 8 저장, list 상태 : 6, 7, 8
a.append(9) 	# list에 추가 9 저장, list 상태 : 6, 7, 8, 9

a.insert(1,2)	# list 1번 인덱스에 2추가 저장, list 상태 : 6, 2, 7, 8, 9

a.pop()			# list 가장 마지막 인덱스 삭제, list 상태 : 6, 2, 7, 8
a.pop(2)		# list 가장 2번째 인덱스 삭제, list 상태 : 6, 2, 8

a.remove(6)		# list에서 데이터 6 삭제, list 상태 : 2, 8

locateValue = a.index(8) # list에서 데이터가 8인 인덱스 출력, locateValue에 1 저장

a.clear()	#모든 데이터 삭제

5. list 값 통계

a = list(range(1,11))	#list 생성, 1~10 저장

sumvalue = sum(a) #list a에 저장되어있는 1~10까지의 합 저장
maxvalue = max(a)  #list a에 저장되어있는 1~10까지의 최대값 저장
minvalue = min(a)  #list a에 저장되어있는 1~10까지의 최소값 저장

6. list  셔플, 정렬

import random as r #랜덤함수 필요

a = list(range(1,11))	# list 생성, 1~10 저장

r.shuffle(a)		# list a 셔플
a.sort()		# list a 오름차순 정렬
a.sort(reverse=True)	# list a 내림차순 정렬

 

1. 대문자 변환

msg = "Hello"

#문자열 모두 대문자 출력
print(msg.upper())

2. 소문자 변환

msg = "Hello"

#문자열 모두 소문자 출력
print(msg.lower())

3. 특정 문자 또는 문자열 찾기

msg = "Hello"

#문자의 인덱스 출력
print(msg.find('e'))

#문자열의 시작 인덱스 출력
print(msg.find("el"))

4. 특정 문자 갯수 찾기

msg = "Hello"

#문자열에 문자가 포함한 갯수 출력
print(msg.count('e'))

#문자열에 문자열이 포함한 갯수 출력
print(msg.count("el"))

5. 문자열 자르기

msg = "Hello"

#문자열 자르기 0번 인덱스에서 시작하는 2번 인덱스 이전까지 문자열 출력
print(msg[:2]) 

#문자열 자르기 1번 인덱스에서 시작하는 2번 인덱스 이전까지 문자열 출력
print(msg[1:2])

6. 문자열 길이

msg = "Hello"

#문자열 길이 출력
print(len(msg)) 

7. 문자열 순회 하기

msg = "Hello"

for i in msg:
	print(i) # "Hello 출력"
    
for i in range(len(msg)):
	print(msg[i]) # "Hello 출력"

8. 대문자 또는 소문자 인지 확인하기

msg = "Hello"

for x in msg:
	#대문자 체크
	if x.isupper():
    	print(x)
        
    #소문자 체크
    if x.islower():
        print(x)

9. 알파뱃인 경우 확인하기 (한글도 알파뱃으로 취급함)

msg = "H1e2l3lo123"

for i in msg:
	if i.isalpha():
    	print(i) #Hello 출력                         

10. 해당 문자의 아스키 코드 출력

msg = "Hello"

print(ord(msg[0]))                    

11. 아스키 코드를 문자열로 출력

msg = 65

print(chr(msg))                    

12. 문자열 왼쪽, 가운데, 오른쪽 정렬

s = 'abc'#문자열
n = 7 #문자열 총 길이

print(s.ljust(n)) # >>abc
print(s.center(n))# >>  abc   
print(s.rjust(n)) # >>    abc
"""
반복문을 이용한 문제풀이
 1) 1부터 N까지 홀수출력하기
 2) 1부터 N까지 합 구하기
 3) N의 약수출력하기
"""
n = int(input("-->"))
listofn = []
sum = 0

//1번, 2번문제 동시에 수행
for i in range(1,n+1):
    sum += i
    if i%2!=0:
        print(i)

print("합계 -> " + str(sum))

decreaseN = n
devider = 2

//3번 문제 수행
//감소하는 decreaseN이 1이 아닐때까지 수행 또는 devider가 입력 변수 n의 1/2값 보다 크면 종료
//devider를 1씩 증가하면서 입력 변수 n과 나누고 몪이 0이면 소인수 추가
//devider를 1씩 증가하면서 입력 변수 n과 나누고 몪이 0이 아니면 devider 1 증가
while decreaseN!=1:
    if devider > n/2:
        break
        
    if decreaseN % devider == 0:
        decreaseN /= devider
        listofn.append(devider)
    else:
        devider+=1

print(listofn)           

 

'Program > Python' 카테고리의 다른 글

List 다루기(2/2)  (0) 2021.03.22
List 다루기 (1/2)  (0) 2021.03.21
문자열 내장함수  (0) 2021.03.15
for, break, else  (0) 2021.03.07
map 함수 - 다중 형변환  (0) 2021.03.07

코드

//1. 0~9까지 데이터를 포함한 list 생성
//2. i에 0값 대입 후 for문 print 수행
//3. 수행 후 i에 2 증가
//4. i가 9를 초과하면 else문 수행
for i in range(0,10,2):
    print(i)
else:
    print("모든 데이터 출력")

출력

0
2
4
6
8
모든 데이터 출력

 

코드

//1. 0~9까지 데이터를 포함한 list 생성
//2. i에 0값 대입 후 for문 print 수행
//3. 수행 후 i에 2 증가
//4. i가 9를 초과하거나 i가 3보다 크면 for문 탈출
//5. break로 수행되었기 때문에 else문 무시
for i in range(0,10,2):
    print(i)
    if i >= 3:
        break
else:
    print("모든 데이터 출력")

출력

0
2
4

 

간단한 for문 및 for문을 모두 완료시 수행하는 else문을 설명했다.

지금까지 했던 다른언어 C++, C#, Java에서도 이런 코드가 있던가?

아무튼 for~else문은 현재 for문을 모두 돌았는지 확인하는? 그런 용도로 쓰일것 같다.

//1. 사용자 입력을 받는다.
//2. 문자열 입력 데이터를 ',' 기준으로 자른후 문자열 리스트를 반환한다.
//3. 문자열 리스트를 float으로 모두 변환 시킨다.
//4. float으로 변환된 float 리스트를 a, b에 저장한다.
//5. 저장된 a, b를 출력한다.
a, b = map(float, input("-->").split(','))
print(a, b)

 

입력

--> 1,2

출력

1 2

 

알고리즘 문제 풀다보면 사용자 입력을 받아야 하는 문제가 존재한다.

이전 C++로 풀었다면 생각보다 귀찮은 코드가 추가되어야 하지만 python은 이처럼 간단하게 처리가 가능하다.

 

입력!!, 자르기!!, 변환!!

상수는 불변의 값이다.

C#의 경우 기본 타입을 상수로 정의할 수 있다.

기본 타입은

Bool, Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, String 등이 있다.

 

상수의 특성

1. 컴파일 타임에서 정의가 된다.

2. 컴파일러는 해당 어셈블리의  메타데이터 안에 정의된 상수 기호를 검색하여 상수의 실제 값을 추출한 후 IL코드에 직접 첨부한다.

   (외부 dll에서 정의된 상수 값도 컴파일러가 해당 응용프로그램을 컴파일 시 외부 dll의 어셈블리의 메타데이터의 상수 기호를 검색하여 응용프로그램의 IL 코드 직접 첨부한다.)

3. 상수값에 대해서 따로 메모리 추가, 삭제를 하지 않는다.

 

 

주의해야 하는 코드를 보겠다.

 

외부에서 생성한 DLL 코드

ExportDLLClass 코드

DLL을 사용하는 응용프로그램

 

응용프로그램 코드

 

위의 응용프로그램을 컴파일 해보겠다. 

 

ExportDLLClass의 const 값 출력
실제 TestDLL 과 같은 폴더에 있는 응용프로그램 DLLTestConsole

이처럼 dll을 참조하여 사용시 응용프로그램은 참조할 dll을 응용프로그램의 경로에 복사시킨다.

그럼 저 경로의 TestDll.dll만 바꿔보겠다.

TestDLL의 ExportDLLClass의 Const값 변경
dll 코드 빌드 후 변경된 DLL만 덮어쓰기

위의 작업 후 DLLTestConsole을 실행하면 어떤 값이 나올까?? 우리 예상은 15이다 참조할 dll의 const 값이 15이기 때문이다.

dll을 변경해도 const값이 그대로 인 결과

위의 결과가 나온다. 이는 2번에서 설명한 응용프로그램에서의 IL코드가 재갱신되지 않았기 때문이다.

자 그럼 응용프로그램을 컴파일 후 실행해보겠다.

우리가 원하던 값 15 출력

이처럼 외부 dll에서 제공하는 const값은 참조하는 응용프로그램과의 혼동을 유발시킬 수 있다.

그래서 dll 개발 시 가능하면 const는 절대 불변의 값(Ex. PI = 3.141592...)만을 사용하는 것을 추천한다.

추 후 런타임에서 정의되는 상수 readonly도 포스팅하겠다.

 

결론

1. 상수는 컴파일 타임에서 해당 응용프로그램의 IL 코드로 생성된다.

2. 상수는 컴파일 타임에서 메모리를 이미 잡고 있기 때문에 런타임에서 사용하는 메모리와는 무관하다.

3. DLL을 배포하는 코드를 작업 시 가능하면 const는 사용하지 않는다. 정말 필요할 때 (PI = 3.141592, ushort max = 65535 등..)만 사용 하자.

'Program > C#' 카테고리의 다른 글

값타입의 박싱과 언박싱  (1) 2020.12.14
값 타입, 참조 타입  (0) 2020.12.13
네임스페이스와 어셈블리  (1) 2020.12.05
타입에 대하여2  (0) 2020.12.02
타입에 대하여1  (1) 2020.11.29

환경 :

Window10, Visual Studio 2019, WPF, MVVMLight, OpencvSharp

 

솔루션 구조

usercontrol 폴더

ImageViewer.xaml 

<UserControl x:Class="WpfApp1.usercontrol.ImageViewer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp1.usercontrol"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Image x:Name="image"/>
    </Grid>
</UserControl>

 

ImageViewer.xaml.cs

using OpenCvSharp;
using System.Windows;
using System.Windows.Controls;
using WpfApp1.utility;

namespace WpfApp1.usercontrol
{
    /// <summary>
    /// ImageViewer.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class ImageViewer : UserControl
    {
        public ImageViewer()
        {
            InitializeComponent();
        }

        public Mat MatImage
        {
            get { return (Mat)GetValue(MyProperty); }
            set { SetValue(MyProperty, value); }
        }

        public static readonly DependencyProperty MyProperty =
            DependencyProperty.Register(
                "MatImage",
                typeof(Mat),
                typeof(ImageViewer),
                new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyPropertyChanged)));


        private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ImageViewer viewer = d as ImageViewer;
            viewer.image.Source = ImageHandler.IplImageToInteropBitmap((e.NewValue as Mat));
        }
    }
}

 

주요코드 

1. MatImage의 GetValue,SetValue

 

2. MyProperty의 등록 과정

DependecyProperty.Register(

"MatImage",                      // 실제 xaml에 노출 시킬 변수 명 추 후 Binding 시킨다.

typeof(Mat),                      // 위의 MatImage의 타입을 정의한다.

typeof(ImageViewer),          //  MatImage 변수를 가지고 있는 객체 타입을 정의한다.

new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyPropertyChanged)));

//OnMyPropertyChanged 함수로 콜백을 등록한다.

 

3. OnMyPropertyChanged 함수

   DependecyObject - MatImage 인스턴스를 가지고 있는 오너 인스턴스 타입으로 사용.

   DependencyPropertyChangedEventArgs - 외부 Binding을 통해 전달된 Mat Type의 인스턴스.

  

private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ImageViewer viewer = d as ImageViewer; // 오너 인스턴스로 변환
    
    //e.NewValue as Mat으로 외부에서 바인딩한 데이터 변환
    viewer.image.Source = ImageHandler.IplImageToInteropBitmap((e.NewValue as Mat)); 
    
}

   

 

ViewModel 폴더 

MainViewModel.cs

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using OpenCvSharp;
using WpfApp1.utility;

namespace WpfApp1.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        Mat _matImage;
        public Mat matImage
        {
            get
            {
                return _matImage;
            }
            set
            {
                _matImage = value;
                RaisePropertyChanged(() => matImage);
            }
        }

        public RelayCommand OpenImage { get; set; }
        public MainViewModel()
        {
            OpenImage = new RelayCommand(OpenImageAction);
        }

        void OpenImageAction()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.RestoreDirectory = true;
            openFileDialog.DefaultExt = "jpg";
            openFileDialog.Filter = "Images Files(*.jpg; *.bmp; *.png)|*.jpg;*.bmp;*.png";

            if (openFileDialog.ShowDialog() == true)
            {
                //Get the path of specified file
                string strImagePath = openFileDialog.FileName;
                matImage = ImageHandler.OpenImage(strImagePath);
            }
        }
    }
}

주요 코드

1. matImage 프로퍼티를 이용한 바인딩 코드

Mat _matImage;
public Mat matImage
{
    get
    {
        return _matImage;
    }
    set
    {
        _matImage = value;
        RaisePropertyChanged(() => matImage);
    }
}

 

MainWindow.xaml

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        xmlns:uc="clr-namespace:WpfApp1.usercontrol"
        mc:Ignorable="d"
        DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <uc:ImageViewer MatImage="{Binding matImage}" Grid.Column="0"/>
        <Button Command="{Binding OpenImage}" Grid.Column="1"/>
    </Grid>
</Window>

주요코드

ImageViewer에서 등록한 MatImage를 MainViewModel의 matImage 프로퍼티에 바인딩.

<uc:ImageViewer MatImage="{Binding matImage}" Grid.Column="0"/>

 

결과

이미지 로드 전
이미지 로드 다이얼로그 생성
이미지 로드 완료!

+ Recent posts