Tkinter - 레이아웃에 Weight 적용하기

|

Tkinter - 레이아웃 Row, Column에 Weight 적용하기

root = tk.Tk()
root.title("SnowDeer's Tkinter Example")
root.resizable(False, False)
root.geometry("640x480")

for col in range(0, 4):
    root.grid_columnconfigure(col, weight=1)

Network Interface 우선 순위 변경하기

|

Network Interface 우선 순위 변경하기

Ubuntu에서 랜카드를 여러 개 꽂아서 네트워크 인터페이스(Network Interface)가 여러 개 존재할 경우 우선 순위를 바꾸는 방법입니다.

먼저 ifmetric를 설치합니다.

sudo apt install ifmetric

이후 다음 명령어를 이용해 Routing Table을 확인합니다.

$ route -n

Kernel IP routing table
Destination     Gateway         Genmask     Flags   Metric  Ref     Use     Iface
0.0.0.0         10.51.0.1       0.0.0.0     UG      100     0       0       eth0
0.0.0.0         192.168.0.1     0.0.0.0     UG      600     0       0       wlan0

맨 뒤의 Iface 항목이 각 네트워크 인터페이스 이름이며 Metric 항목이 우선 순위라고 생각하면 됩니다. Metric 값이 낮을 수록 우선 순위가 높습니다.

ifmetric 명령어를 이용해서 다음과 같이 우선 순위를 변경할 수 있습니다.

sudo ifmetric wlan0 50

다시 route -n 명령어로 Routing Table을 확인해봅니다.

$ route -n

Kernel IP routing table
Destination     Gateway         Genmask     Flags   Metric  Ref     Use     Iface
0.0.0.0         192.168.0.1     0.0.0.0     UG      50      0       0       wlan0
0.0.0.0         10.51.0.1       0.0.0.0     UG      100     0       0       eth0

우선 순위가 바뀐 것을 확인할 수 있습니다.

문자열(std_msg)을 수신(Subscribe)하고 전송(Publish)하는 예제 코드(C++)

|

문자열(std_msg)을 수신(Subscribe)하고 전송(Publish)하는 예제 코드(C++)

하나의 프로그램내에서 ROS 2.0 문자열 메시지를 수신하고, 바로 그 내용을 다른 토픽(Topic)으로 전송하는 예제 코드입니다. 메시지 수신부는 람다 함수로 되어 있습니다.

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

#include <iostream>

using namespace std;
using std::placeholders::_1;

const string NODE_NAME = "snowdeer_msg_echo_example";

int main(int argc, char *argv[]) {
  cout << "Hello, ROS2 ECHO Example" << std::endl;

  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared(NODE_NAME);
  auto publisher = node->create_publisher<std_msgs::msg::String>("snowdeer_output");

  auto subscription = node->create_subscription<std_msgs::msg::String>
      ("snowdeer_input", [publisher](std_msgs::msg::String::SharedPtr inMessage) {
        auto outMessage = std::make_shared<std_msgs::msg::String>();
        outMessage->data = inMessage->data;
        publisher->publish(outMessage);
      });

  auto message = std::make_shared<std_msgs::msg::String>();

  rclcpp::spin(node);
  rclcpp::shutdown();

  return 0;
}

Intent를 이용해서 전화 및 화상 통화 호출하는 방법

|

Intent를 이용해서 전화 및 화상 통화 호출하는 방법

제조사마다 방식이나 특정 Flag 값이 다를 수 있습니다.

import android.Manifest.permission;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

  EditText etPhoneNumber;
  static final int PERMISSION_REQUEST_CODE = 100;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    etPhoneNumber = findViewById(R.id.et_phone_number);

    findViewById(R.id.btn_call).setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        Intent i = new Intent(Intent.ACTION_CALL);
        i.setData(Uri.parse("tel:" + getPhoneNumber()));
        i.putExtra("android.phone.extra.calltype", 0);
        startActivity(i);
      }
    });

    findViewById(R.id.btn_video_call).setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        Intent i = new Intent(Intent.ACTION_CALL);
        i.setData(Uri.parse("tel:" + getPhoneNumber()));
        i.putExtra("videocall", true);
        startActivity(i);
      }
    });

    if (checkSelfPermission(permission.CALL_PHONE)
        != PackageManager.PERMISSION_GRANTED) {
      String[] permissions = new String[]{permission.CALL_PHONE};
      requestPermissions(permissions, PERMISSION_REQUEST_CODE);
    }
  }

  String getPhoneNumber() {
    return etPhoneNumber.getText().toString();
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {
      case PERMISSION_REQUEST_CODE:
        if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
          Toast.makeText(getApplicationContext(), "Permission 완료", Toast.LENGTH_SHORT).show();
        } else {
          Toast.makeText(getApplicationContext(), "Permission 실패", Toast.LENGTH_SHORT).show();
        }
        break;
    }
  }

}

ZSH Plug-in 사용 방법

|

ZSH Plug-in 사용 방법

ZSH에는 수 많은 플러그인(Plug-in) 들이 있습니다. 그런데, 그 중에서 쓸만한 것들이 아주 많은 것 같지는 않습니다. 다음은 개인적으로 쓰고 있는, 범용적으로 쓰일 수 있는 플러그인들입니다.

ZSH 플러그인 설치는 ~/.oh-my-zsh/custom/plugins 디렉토리에 하면 되며, 사용 유무는 ~/.zshrc 파일에서 설정 할 수 있습니다.


플러그인 설치 예시

cd ${ZSH_CUSTOM1:-$ZSH/custom}/plugins

git clone https://github.com/djui/alias-tips.git
git clone https://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

그 이후 ~/.zshrc 파일에 다음과 같이 설정합니다.

plugins=(
  git
  alias-tips
  zsh-autosuggestions
  zsh-syntax-highlighting
)

그 외에도 저는 wd 같은 플러그인도 사용하고 있습니다.