Skip to content

Latest commit

ย 

History

20 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 

Repository files navigation

๐Ÿ Python

Coding Style

๐Ÿ“ Python Sytle Guide
๐Ÿ“ Documentation
# Module

"""A one-line summary

Detailed descriptions for the module or program.
You may include 'how to run this' or 'usage of functions/classes'

"""

# Function
def function_name(args):
    """Function Description shortly

    More details for this class...
    More details for this class...

    Args:
        arg_name: description

    Returns:
        what to return
    
    Raises:
        error_type: why we get this error
    """

# Class
class ClassName:
    """A one-line summary

    More details for this class...
    More details for this class...

    Attributes:
        attrib_name: description
    """

๐Ÿ“ Indentations and Spaces
# Examples: Parentheses --------------------------------
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

meal = (spam,
        beans)

foo = long_function_name(
    var_one, var_two, var_three,
    var_four)

foo = long_function_name(
    var_one, var_two, var_three,
    var_four
)

# String ------------------------------------------------
# One Tab (= 4 spaces)
long_string = """This is fine if your use case can accept
    extraneous leading spaces."""

# Use parentheses
long_string = ("And this is fine if you cannot accept\n" +
               "extraneous leading spaces.")
long_string = ("And this too is fine if you cannot accept\n"
               "extraneous leading spaces.")

# textwarp
import textwrap
long_string = textwrap.dedent("""\
    This is also fine, because textwrap.dedent()
    will collapse common leading spaces in each line.""")

๐Ÿ“ Function signature
def my_method(
    self,
    first_var: int,
    second_var: Foo,
    third_var: Bar | None,
) -> int:

# spaces around `=` if the argument have type annotation & default value
def func(a: int = 0) -> int:

๐Ÿ“ Type Annotation
  • var: type = value format
  • typing module can be used
# Variables
path: str = '/home/winterbloooom/foo.txt'
paths: list = [path1, path2, path3]

# Functions
def show_paths(paths: list, max_num: int = 3) -> str:
    return 'done'

# With `typing` module
from typing import List, Dict
food: List[str] = ['banana', 'apple']
students: Dict[str, int] = {'eungi': 100, 'winterbloooom': 99}

๐Ÿ“ Naming Convention
  • Package / module - package_name , module_name
    • DO NOT use dashes(-)
  • Function - function_name
  • Variable
    • Global Constant - GLOBAL_CONSTANT_NAME
    • others - var_name
  • Class - ClassName
  • Exception - ExceptionName

Here's a guideline from Gudio

Type Public Internal
Packages lower_with_under
Modules lower_with_under _lower_with_under
Classes CapWords _CapWords
Exceptions CapWords
Functions lower_with_under() _lower_with_under()
Global/Class Constants CAPS_WITH_UNDER _CAPS_WITH_UNDER
Global/Class Variables lower_with_under _lower_with_under
Instance Variables lower_with_under _lower_with_under (protected)
Method Names lower_with_under() _lower_with_under() (protected)
Function/Method Parameters lower_with_under
Local Variables lower_with_under

๐Ÿ“ Black & isort formatting

[ Formatting with Black and isort ]

  • Black for Python code formatting
  • isort for Python import sorting

[ Method 1. VSCode extensions ]

  1. command + shift + p
  2. Preferences: Open User Settings (JSON)
  3. Insert code blow
"[python]": {
    "diffEditor.ignoreTrimWhitespace": false,
    "editor.defaultFormatter": "ms-python.black-formatter",
    "editor.formatOnSave": true,
},
"isort.args":["--profile", "black"],

[ Method 2. Commandline ]

  • Installation**
    pip install black
    pip install isort
  • Usage 1: command
    black <file or path>
    isort <file or path>
  • Usage 2: with pyproject.toml configuration file
    • Make this file in the directory where the .gitignore exists.
      [tool.black]
      line-length = 100
      target-version = ['py39']
      exclude = '''
        \.git
        \DIR_OR_FILE_NAME
      '''
      
      [tool.isort]
      profile = "black"
      multi_line_output = 3
      use_parentheses = true
      line_length = 100
      skip = [".gitignore"]
      
    • then run commands below.
      black --config pyproject.toml <PATH>
      isort --settings-path pyproject.toml <PATH>

[ Use with Pre-commit ]

  • Installation
    pip install pre-commit
  • pre-commit configuration file
    • Make a file named .pre-commit-config.yaml in the directory where the .gitignore exist.
      repos:
        - repo: https://github.com/PyCQA/isort
          rev: 5.10.1
          hooks:
            - id: isort
      
        - repo: https://github.com/ambv/black
          rev: 22.6.0
          hooks:
            - id: black
  • Make pre-commit hook
    pre-commit install
  • Commit
    git commit -am "pre-commit test"

๐Ÿ“ String Formatting
# ์ฒœ ๋‹จ์œ„ ์ฝค๋งˆ ํ‘œ์‹œ
print(f"{value:,}")
# ์ฒœ ๋‹จ์œ„ ์ฝค๋งˆ ํ‘œ์‹œ + ์†Œ์ˆซ์  (์†Œ์ˆซ์  ์•ž 5์ž๋ฆฌ, ๋’ค 2์ž๋ฆฌ)
print(f"{value:5,.2f}")

# Scientific Notation (์ง€์ˆ˜ ํ‘œํ˜„)
print("{value:.2e}") # 1234567.89 -> 1.23e+06
print("{value:.2e}") # 0.0000001234 -> 1.23e-07

For your smart codes

๐Ÿ“Œ Check the type or value of the function arguments
if not isinstance(argument, (type1, type2, ...)):
    # Preprocess the argument

assert isinstance(argument, type1), f"Error message"
		# If fasle, Python occurs an AssertionError

# Example
def function_name(arg1, arg2):
    print(isinstance(arg1, str))
    assert isinstance(arg2, bool), f"""The type of 'arg2' is not matched. It should be {bool.__name__}, not {type(arg2).__name__}."""

๐Ÿ“Œ Configuration - OmegaConf

๐Ÿ‘‰ Basic Usage

from omegaconf import DictConfig

# yaml -> DictConfig
conf = OmegaConf.load('source/example.yaml')
# DictConfig -> yaml
print(OmegaConf.to_yaml(conf))

# Access
conf.dataset.name
conf['dataset']['name']

# Default Values
conf.get('missing_key', 'default_value')

# Merge configs
conf = OmegaConf.merge(base_cfg, model_cfg, optimizer_cfg, dataset_cfg) # each params are DictConfig types

# Convert to primitive container (dict)
primitive = OmegaConf.to_container(conf) # to_container(conf, resolve=True)

๐Ÿ‘‰ Resolvers

  • oc.env: environment variables
  • oc.create: make new DictConfig
user: ${oc.env:USER}

๐Ÿ“Œ Set the root directory

ํ”„๋กœ์ ํŠธ ํด๋” ๋‚ด์—์„œ from, import ๋ฌธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•  ๋•Œ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ค์ •ํ•˜๋ฉด from ํด๋”1_์ด๋ฆ„.ํด๋”2_์ด๋ฆ„ import ํŒŒ์ผ_์ด๋ฆ„ ์‹์œผ๋กœ ์‚ฌ์šฉ์ด ์‰ฝ๋‹ค.

  • Choice 1: pyrootutils.setup_root()
    # .git ์ด ์žˆ๋Š” ๊ณณ์„ root๋กœ ์ง€์ •
    import pyrootutils
    root = pyrootutils.setup_root(
        search_from=__file__,
        indicator=[".git"],
        pythonpath=True,
        dotenv=True,
    )
  • Choice 2: sys.path.insert()
    # os.path.dirname(__file__) : ํ˜„ ํŒŒ์ผ์ด ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ ๊ฒฝ๋กœ
    # sys.path.insert(0, [PATH]): [PATH]๋ฅผ ํ™˜๊ฒฝ๋ณ€์ˆ˜์— ๋“ฑ๋ก
    import sys, os
    sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '.')))

๐Ÿ“Œ Skip warning messages
import warnings
warnings.simplefilter("ignore", UserWarning)

๐Ÿ“Œ Progress bar
from tqdm import tqdm

for item in tqdm(my_list, desc="description")
for idx, item in enumerate(tqdm(my_list, desc='description'))

๐Ÿ“Œ Parsing the arguments
import argparse

parser = argparse.ArgumentParser(description="Description of this project")
parser.add_argument("--arg_name", type=int, default=None, help="description of this argument")
args = parser.parse_args()
  • Description & default value of the argument
    parser.add_argument("--arg_name", default=None, help="description of this argument")
  • Define the names of the argument
    parser.add_argument("--arg_name", "-n")
  • Specify the type (e.g., string)
    parser.add_argument("--arg_name", type=str)
  • Specify the options
    parser.add_argument("--arg_name", choices=[1, 2, 3])
    parser.add_argument("--arg_name", choices=range(0, 100))
  • Actions
    • (1) store (default): store the value to the argument
    • (2) append: when you want to store multiple values as an list
      • e.g., --arg_name 1 --arg_name "12", --arg_name False -> [1, "12", False]
    • (3) store_true: store true
    parser.add_argument('--arg_name', action='store_true')
    # [Wrong] parser.add_argument('--test', type=bool) -> if `--test False`, it also save True!
    # just `python main.py --arg_name`. If this argument not mentioned, False is stored.
  • Specify the number of values
    • N: read N values (e.g., --arg_name "spring" "winter")
    • *: read multiple values (e.g., --arg_name 1 2 3 4)
    • +: read at least one value
    • etc...
    parser.add_argument('--arg_name', nargs='2') 
  • Change the variable name to store the value
    parser.add_argument("--arg_name", dest="arg_new_name")
  • Positional (you must pass the value)
    • There isn't - before the name of the argument
    • You can just pass the value without the name (e.g., python example.py "happy"), just keep the sequence of positional arguments
    • If you want to change optional to positional, `parser.add_argument("--arg_name", required=True)``
    parser.add_argument("arg_name")
  • the number of arguments: len(sys.argv)
  • Print the help: parser.print_help()

Useful modules & functions

๐ŸŒฑ Running arguments

Python running arguements
  • -m: run python module directly
    project/
    โ”‚โ”€โ”€ mypackage/
    โ”‚   โ”‚โ”€โ”€ __init__.py
    โ”‚   โ”‚โ”€โ”€ myscript.py
    โ”‚โ”€โ”€ main.py
    
    • You can run the myscript.py with python -m mypackage.myscript rather than python mypackage/myscript (it may occur import error)
  • -u

๐ŸŒฑ Get information about current status

Date & Time in text
import datetime
datetime.datetime.now().strftime("%y_%m_%d-%H_%M_%S")
# e.g., 24_02_16-17_26_20

Current running file/directory
import os
# file name
f_name = os.path.abspath(__file__) # absolute path
f_name = os.path.realpath(__file__) # relateive path
# directory name
os.path.dirname(f_name)

Name of function
import sys
sys._getframe(1).f_code.co_name # ํ˜„์žฌ ํ•จ์ˆ˜
sys._getframe(2).f_code.co_name # ์ด๋ฅผ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜

Print the file name, line number, and function name
import inspect
cf = inspect.currentframe()
print(f'\nFile "{cf.f_code.co_filename}", line {cf.f_lineno}, in {cf.f_code.co_name}')
# e.g., File "/home/eungi/4D-Humans/hmr2/datasets/__init__.py", line 68, in __init__

Attributes of Object
hasattr(obj, 'age') # obj๋ผ๋Š” ๊ฐœ์ฒด์— 'age'๋ผ๋Š” ์†์„ฑ์ด ์žˆ์œผ๋ฉด True
getattr(obj, 'age', 'No age attribute') # obj๋ผ๋Š” ๊ฐœ์ฒด์— 'age'๋ผ๋Š” ์†์„ฑ์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ , ์—†์œผ๋ฉด ์„ธ ๋ฒˆ์งธ ํ…์ŠคํŠธ ์ถœ๋ ฅ
setattr(obj, 'age', 25) # obj๋ผ๋Š” ๊ฐœ์ฒด์— 'age'๋ผ๋Š” ์†์„ฑ์„ 25๋กœ ์ถ”๊ฐ€/๋ณ€๊ฒฝ


๐ŸŒฑ File/Directory Paths

Existance of File/Directory
import os
os.path.exist(PATH)

Compose file paths
import os
path = '/home/data/my_dataset'
file_name = 'image_list.txt'
os.path.join(path, file_name)

Files in the directory
import os
# file names
list_of_files = os.listdir('PATH_OF_DIR') # list
# file paths
list_of_paths = [os.path.join('DIR_PATH', fname) for fname in list_of_files]

List of files with condition
import glob
file_list = glob.glob("*.jpg")


๐ŸŒฑ Control

Turn off the program here
import sys; sys.exit()

pdb debugger

๐ŸŒฑ File Handling

text ํŒŒ์ผ ์ฝ/์“ฐ๊ธฐ
with open("foo.txt", "r") as f:
    lines = f.readlines()

with open("foo.txt", "w") as f:
    f.write("Life is too short, you need python")

pickle (.pkl) ํŒŒ์ผ ์ฝ/์“ฐ๊ธฐ
import pickle

# save
SOMETHING = [1, 2, 3] # example
with open("FILE_NAME.pickle", "wb") as f:
    pickle.dump(SOMETHING, f)

# load
with open("FILE_NAME.pickle", "rb") as f:
    data = pickle.load(f)

๐Ÿช„ NumPy

import numpy as np

๐Ÿ“ฆ Load npy, npz file
# npz: ํ‚ค ๋ชฉ๋ก ๋ณด๊ธฐ
data = np.load(PATH)
keys = [k for k in data.keys()] # print(data.keys())๋Š” ์•ˆ ๋ณด์ž„

# ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋”•์…”๋„ˆ๋ฆฌ๋ผ๋ฉด
data = (np.load(PATH, allow_pickle=True)).item()
data[KEY] # ํ‚ค ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ ์ ‘๊ทผ

๐Ÿ”ฅ PyTorch

Process Image/Video

Image at PIL / OpenCV / PyTorch
PIL OpenCV PyTorch
load Image.open() cv2.imread()
size func. img.size img.shape tensor.shape or tensor.size()
size (w, h) (h, w, c) (c, h, w)
dtype 8 (img.bits) uint8 (img.dtype) torch.float32 (0~1) (tensor.dtype)
range 0 ~ 255 0 ~ 255 0 ~ 1
format RGB (img.mode) BGR RGB
  • PIL

    from PIL import Image
    img = Image.open('path_of_image')
    
    # PIL -> Numpy
    import numpy as np
    img = np.asarray(img) # or np.array(img)
    # Numpy -> PIL
    img = Image.fromarray(img)
  • OpenCV

    import cv2
    img = cv2.imread('path_of_image')
  • PyTorch

    # PIL -> tensor
    import torchvision.transforms.functional as F
    img = Image.open('path_of_image')
    img = F.to_tensor(img)
    # Numpy -> tensor
    from torchvision.transforms import ToTensor
    toTensor = ToTensor()
    img = toTensor(img)
    # cv -> tensor (1)
    img = cv2.imread(path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # RGB -> BGR
    img = img.transpose((2, 0, 1)) # H,W,C -> C,H,W
    img = img.float().div(255.0) # normalize
    # cv -> tensor (2)
    img = cv2.imread(path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # RGB -> BGR
    img = img.Tensor(img) # normalize
    img = img.permute(2, 0, 1) # H,W,C -> C,H,W
    
    # tensor -> PIL, NumPy
    from torchvision.transforms import ToPILImage
    toPILImage = ToPILImage()
    img = toPILImage(img)
    # tensor -> cv
    img = img.detach().cpu().numpy() # tensor -> numpy
    img = np.transpose(img, (1, 2, 0)) # C,H,W -> H,W,C
    img = img*255 # denormalize
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR -> RGB
    img = img.astype(np.uint8).copy() # np.float32 -> np.uint8
  • cv to torch in lambda func.

    load_images = lambda path, h, w: cv2.resize(cv2.cvtColor(cv2.imread(path, cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), ((w, h)))
    tensorify = lambda x: torch.Tensor(x.transpose((2, 0, 1))).unsqueeze(0).float().div(255.0)
    
    img_tensor = tensorify(load_images("img.png", 400, 300))
    print(img_tensor.shape) # torch.Size([1, 3, 400, 300])

Save the image
  • Tensor type

    # (1) torchvision
    # Option: nrow (ํ•œ ์ค„์— ๋ช‡ ๊ฐœ์˜ ์ด๋ฏธ์ง€), padding (์ด๋ฏธ์ง€ ๊ฐ„ ๋ช‡ ํ”ฝ์…€ ๊ฐ„๊ฒฉ), etc
    from torchvision.utils import save_image
    save_iamge(img, 'path_of_image') # (B, C, H, W) -> (W, H, C)
    
    # (2) plt
    import matplotlib.pyplot as plt
    img = img.permute(1, 2, 0) # [C, H, W] -> [H, W, C]
  • Numpy, PIL type

    import numpy as np
    from PIL import Image
    img = Image.fromarray(img) # numpy -> PIL
    img.save('path_of_image', 'jpg')
Save the video
import torchvision
# video: np.ndarray, [Time, Hight, Width, Channel], 0~255, np.uint8
torchvision.io.write_video(save_fname, video, fps=fps, audio_codec='aac')

Use CUDA (GPU)

Check CUDA
import torch; print(torch.cuda.is_available()) # True of False

Setting GPU Devices
# Method 1)
import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = <gpu_numbers> 
    # e.g., "1, 2" - assign GPU number 0 and 1 for each GPU 1, GPU 2

# Method 2)
import torch; torch.cuda.set_device(1)

# Method 3) Commandline
CUDA_VISIBLE_DEVICES=2,3 python script_fname.py

Checkpoint and Pre-trained model

Load model
  • PATH: checkpoint file
  • DEVICE: running device (type: torch.device)
  • MODEL: model to load parameters
checkpoint = torch.load(PATH, map_location=DEVICE)

# if you save only model_state_dict
MODEL.load_state_dict(checkpoint)
# if you save all parameters of model, optimizer, etc.
MODEL.load_state_dict(checkpoint["model_state_dict"])

Tensors

Merge lists to tensors
# list[tesor, tensor, ...] -> tensor[tensor, tensor, ...]
torch.stack(list_name, dim=0)

Dataset & Dataloader

Sampler

๐Ÿš€ Other Python Tools

wandb

import wandb

initiate
# init
wandb.login()
wandb.init(
    project="PROJECT_NAME",
    entity="USER_NAME",
    name="EXPERIMENT_NAME",
    config = {
        "CONFIG1": config1,
    },
    notes="NOTES",
)

Logging
# logging - number
wandb.log({
    "train/loss1": loss.item(), 
    "val/metric1": metric,
})
# logging - image
# e.g., wandb.log({"result_img": wandb.Image(output_img, mode="RGB", caption="step_2 result")})
wandb.log({'<NAME>': wandb.Image(<IMAGE>, mode="<MODE>", caption="<CAPTION>")})

# logging - video
# e.g., wandb.log({"video": wandb.Video("/home/eungi/video.mp4", fps=30, format="mp4")})
wandb.log({"<NAME>": wandb.Video(<VIDEO_PATH>, fps=<FPS>, format="<FORMAT>")})

Tensorboard

Show tensorboard
tensorboard --logdir=<log_directory_path> --port=<port_number>
Port forwarding
ssh -NfL localhost:<server_port>:localhost:<local_port> <server_name>

# example
ssh -NfL localhost:6007:localhost:6007 eungi@gpu01

dotenv

dotenv๋กœ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ด€๋ฆฌ
  • .env ํŒŒ์ผ์— ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ •์˜
    • ์ฝ”๋“œ ๋‚ด ๋ฏผ๊ฐ ์ •๋ณด๋ฅผ ์ ์ง€ ์•Š๊ณ ๋„ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ด€๋ฆฌ ์šฉ์ด
API_KEY=your_api_key
  • ์„ค์น˜: pip install python-dotenv
  • ์‚ฌ์šฉ: from dotenv import load_dotenv; load_dotenv()
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ: os.getenv('API_KEY') ํ˜น์€ os.environ['API-KEY]

๐Ÿ”ฆ Dev Tools

tmux

Usage
  • seesion list: tmux ls

  • make session: tmux new -s <session-name>

  • session attach: tmux a -t <session-name>

  • session detach: Ctrl + b โ†’ d

  • Split vertically: Ctrl + b โ†’ %

  • Split horizontally: Ctrl + b โ†’ >

  • Change focus: Ctrl + b โ†’ direction_key or space

  • Scroll: Control + b โ†’ [ / q to quit

Installation
### Install

# ubuntu
sudo apt install tmux

# mac
brew install tmux

### Check installation
tmux -V
tmux configuration

Create/Edit ~/.tmux.conf file:

vi ~/.tmux.conf

the, run:

tmux source-file ~/.tmux.conf

Configs:

  • ๋งˆ์šฐ์Šค ์‚ฌ์šฉ ํ—ˆ์šฉ: set -g mouse on
  • Other options

Anaconda

Usage
  • environment list: conda env list
  • create environment: conda create --name <env_name> [python=<py_version>]
  • remove environment: conda env remove --name <env_name>
  • clone environment: conda create --name <AFTER> --clone <ORIGINAL>
  • change environment name: (์ด๋ฆ„ ๋ณ€๊ฒฝ์€ ์ง€์› ์•ˆ ํ•จ) ์›ํ•˜๋Š” ์ด๋ฆ„์œผ๋กœ ๊ทธ ํ™˜๊ฒฝ์„ __๋ณต์‚ฌ__ํ•ด๋‘๊ณ  ์›๋ž˜ ์ด๋ฆ„์˜ ํ™˜๊ฒฝ์€ ์ง€์šฐ๊ธฐ
  • activate environment: conda activate <env_name>
  • deactivate environment: conda deactivate
  • Package List: conda list
  • Clean: conda clean --all
  • pip clean: pip cache purge

Git and GitHub

Remote Repository
# Check registered remotes
# You can use `git remote get-url origin` instead
git remote -v

# After making an empty repository in GitHub,
# add remote repository in local repository.
git remote add origin <URL-OF-REMOTE-REPOSITORY>

# Push
git branch -M main
git push -u origin master

# GitHub์—์„œ mergeํ•˜๊ณ  local์— ๋™๊ธฐํ™”
git fetch -p # ์›๊ฒฉ ๋ธŒ๋žœ์น˜ ์‚ญ์ œ ๋‚ด์—ญ ๋ฐ˜์˜
git pull
git branch -d <branch_name> # ๋กœ์ปฌ ๋ธŒ๋žœ์น˜ ์‚ญ์ œ
Branch naming convention
Clone specific vertion of commit
  1. Clone repo: git clone <repo_address>
  2. Go to that commit: git reset --hard <commitID>

VSCode

Debugging Configurations
  • ํ•ญ์ƒ ํŠน์ • ํŒŒ์ผ์—์„œ ๋””๋ฒ„๊น…ํ•˜๊ธฐ: "program": "ํŒŒ์ผ๋ช…". ${file}์€ ๋””๋ฒ„๊น… ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ํ•ด๋‹น ํŒŒ์ผ์„ ์˜๋ฏธ
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •ํ•˜๊ธฐ: env ๋”•์…”๋„ˆ๋ฆฌ์— ์ž…๋ ฅ
  • ๋ฃจํŠธ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹Œ, ํŠน์ • ๊ฒฝ๋กœ์—์„œ ๋””๋ฒ„๊น… ์‹œ์ž‘ (change directory): cwd์— ์ž…๋ ฅ. ํ˜„์žฌ ์—ด๋ ค์žˆ๋Š” ํŒŒ์ผ์˜ ๋””๋ ‰ํ† ๋ฆฌ ์ด๋ฆ„์€ ${fileDirname}
"env": {
	"CUDA_VISIBLE_DEVICES": "6"
},
"cwd": "src" 
  • python -m์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์‹คํ–‰
"module": "dir/.../file" # program  ๋Œ€์‹ 
Kill VSCode server process
# check process list
ps -ef | grep <UserName> | grep vscode
# Kill all processes
#kill -9 $(ps -eL | grep <UserName> | grep vscode)

https://bakyeono.net/post/2015-05-05-linux-kill-process-by-name.html

Change all upper/lowercases
  • (Windows) Ctrl + Shift + U
  • ๋ณ€๊ฒฝํ•  ๋ถ€๋ถ„ ์„ ํƒ -> Cmd + Shift + P -> transform to ...
Extensions
  • indent-rainbow: Colorize indentations
  • Comment Anchors: Comment with anchor tags
  • Black Formatter: Python code formatter
  • isort: Python import part formatter
Rulers (์—๋””ํ„ฐ ์„ธ๋กœ์„ )

cmd + shift + P โ†’ Open settings (JSON)

"editor.rulers": [
    {
    	"column": 88,
    },
],

ffmpeg/ffprobe

Video <-> image frames

Options:

  • -ss/-to/-t: ์ถ”์ถœ ์‹œ์ž‘/์ข…๋ฃŒ์‹œ์ /์ข…๋ฃŒ๊ธธ์ด ์„ค์ •. hh:mm:ss, hh:mm:ss.sss, s ํ˜•์‹
  • -framerate: '์ž…๋ ฅ' ๋น„๋””์˜ค/์ด๋ฏธ์ง€ ์ŠคํŠธ๋ฆผ์˜ FPS. ์ฃผ๋กœ ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ๋น„๋””์˜ค๋กœ ๋ณ€ํ™˜ ์‹œ ์‚ฌ์šฉ
  • -r: '์ถœ๋ ฅ' ํŒŒ์ผ์˜ ์ดˆ๋‹น ํ”„๋ ˆ์ž„ ๋ ˆ์ดํŠธ๋ฅผ ์„ค์ •. ์ž…๋ ฅ ๋น„๋””์˜ค์˜ ํ”„๋ ˆ์ž„ ๋ ˆ์ดํŠธ ์กฐ์ • ํ˜น์€ ๋น„๋””์˜ค ์ธ์ฝ”๋”ฉ ์‹œ ์‚ฌ์šฉ.
  • -f: ์ถœ๋ ฅ ํŒŒ์ผ์˜ ํฌ๋งท ์ง€์ •. image2์ด๋ฉด ์ž…๋ ฅ ํŒŒ์ผ์„ ๋น„๋””์˜ค๊ฐ€ ์•„๋‹ˆ๋ผ ์ด๋ฏธ์ง€๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์ง€์‹œ.
  • ์ถœ๋ ฅ ํŒŒ์ผ ์ด๋ฆ„ ํฌ๋งท: %d์ด๋ฉด ์ˆœ์ฐจ์ ์œผ๋กœ 1, 2, 3, ...์ด๊ณ , %06d์ด๋ฉด ์—ฌ์„ฏ ์ž๋ฆฌ๋ฅผ ๋งž์ถ”๋˜ ์•ž ๋ถ€๋ถ„์„ 0์œผ๋กœ ์ฑ„์šฐ๋Š” ์‹.
  • -qscale:v ๋˜๋Š” -q:v: ๋น„๋””์˜ค ํ’ˆ์งˆ ๋น„์œจ. ๋‚ฎ์„์ˆ˜๋ก ํ’ˆ์งˆ ์ข‹๊ณ  ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ ํผ. ๊ธฐ๋ณธ 2
  • -c:v: ๋น„๋””์˜ค ์ฝ”๋ฑ ์ง€์ •
    • libx264: H.264 ์ฝ”๋ฑ
    • mpeg4: MPEG-4 Part 2 ์ฝ”๋ฑ. ์˜ค๋ž˜๋œ ์žฅ์น˜๋‚˜ SW์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ
    • copy: ์žฌ์ธ์ฝ”๋”ฉ ์—†์ด ์›๋ณธํŒŒ์ผ์—์„œ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ(์†๋„ ๋น ๋ฆ„, ํ’ˆ์งˆ ์†์‹ค ์—†์Œ)
  • pix_fmt: ๋น„๋””์˜ค์˜ ํ”ฝ์…€ ํฌ๋งท ์„ค์ •. yuv420p์ด๋ฉด H.264์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ํฌ๋งท.
# Extract frames from a video
ffmpeg -i <VideoPath> -f image2 <ImgPath%d.png>
# ffmpeg -ss 00:01:00 -to 00:21:00 -i input.mp4 -r 25 -f image2 image_%06d.png
# PNG๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉด ํ™”์งˆ์ด ๊นจ์งˆ ๋•Œ๊ฐ€ ์ข…์ข… ์žˆ์Œ

# Merge frames into single video
ffmpeg -framerate <FPS> -i <PathPattern> -c:v <Value> -pix_fmt <Value> <OutVideoPath.mp4>
# ffmpeg -framerate 25 -i iamge_%03d.png -c:v libx264 -pix_fmt yuv420p <OutVideoPath.mp4>
Merge multiple images in one frames
# 4 images to one (upper left, upper right, lower left, lower right)
ffmpeg \
-i [ul_path] -i [ur_path] -i [ll_path] -i [lr_path] \
-filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[out]" \
-map", "[out]" \
[save_path]
import subprocess
cmd = [
    'ffmpeg', '-y', '-loglevel', "error",
    '-i', ul, '-i', ur, '-i', ll, '-i', lr,
    "-filter_complex",
    "[0:v][1:v]hstack=inputs=2[top];"
    "[2:v][3:v]hstack=inputs=2[bottom];"
    "[top][bottom]vstack=inputs=2[out]",
    "-map", "[out]",
    save_path
]
return_code = subprocess.call(cmd)
Extract audio from video

Options:

  • -ac: ์˜ค๋””์˜ค ์ฑ„๋„ ์„ค์ •. 1์€ ๋ชจ๋…ธ(1์ฑ„๋„), 2๋Š” ์Šคํ…Œ๋ ˆ์˜ค(2์ฑ„๋„)
  • -vn: ๋น„๋””์˜ค ์ŠคํŠธ๋ฆผ ์ œ์™ธ
  • -ar: ์˜ค๋””์˜ค ์ƒ˜ํ”Œ๋ง ๋ ˆ์ดํŠธ ์„ค์ •
  • -acodec ํ˜น์€ -c:a: ์˜ค๋””์˜ค ์ฝ”๋ฑ ์„ค์ •
    • pcm_s16le๋Š” ๋น„์••์ถ• ์˜ค๋””์˜ค(๊ณ ํ’ˆ์งˆ, ๊ณ ์šฉ๋Ÿ‰)์ด๋ฉฐ, ํ™•์žฅ์ž๋Š” wav๋กœ ์ €์žฅํ•˜๋Š” ๊ฒŒ ์ผ๋ฐ˜์ .
    • aac๋Š” mp3 ๋Œ€์ฒด ์œ„ํ•œ ๊ณ ํšจ์œจ ์˜ค๋””์˜ค ์ฝ”๋ฑ
    • copy์ด๋ฉด ๋ณ„๋„์˜ ์ธ์ฝ”๋”ฉ ์—†์ด ์›๋ณธํŒŒ์ผ์—์„œ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ(์†๋„ ๋น ๋ฆ„, ํ’ˆ์งˆ ์†์‹ค ์—†์Œ)
ffmpeg -i <VideoPath> -ac 1 -c:a <Value> -ar <SampleRate> -vn <OutPath.[wav/mp4/m4a/aac]>
Merge audio and video

Options:

  • -c:v: ๋น„๋””์˜ค ์ฝ”๋ฑ ์ง€์ •
    • libx264: H.264 ์ฝ”๋ฑ
    • mpeg4: MPEG-4 Part 2 ์ฝ”๋ฑ. ์˜ค๋ž˜๋œ ์žฅ์น˜๋‚˜ SW์˜ ํ˜ธํ™˜์„ ์œ„ํ•ด ์‚ฌ์šฉ
    • copy: ์žฌ์ธ์ฝ”๋”ฉ ์—†์ด ์›๋ณธํŒŒ์ผ์—์„œ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ(์†๋„ ๋น ๋ฆ„, ํ’ˆ์งˆ ์†์‹ค ์—†์Œ)
  • -acodec ํ˜น์€ -c:a: ์˜ค๋””์˜ค ์ฝ”๋ฑ ์„ค์ •
    • pcm_s16le: ๋น„์••์ถ• ์˜ค๋””์˜ค(๊ณ ํ’ˆ์งˆ, ๊ณ ์šฉ๋Ÿ‰)์ด๋ฉฐ, ํ™•์žฅ์ž๋Š” wav๋กœ ์ €์žฅํ•˜๋Š” ๊ฒŒ ์ผ๋ฐ˜์ .
    • aac: mp3 ๋Œ€์ฒด ์œ„ํ•œ ๊ณ ํšจ์œจ ์˜ค๋””์˜ค ์ฝ”๋ฑ
    • copy: ์žฌ์ธ์ฝ”๋”ฉ ์—†์ด ์›๋ณธํŒŒ์ผ์—์„œ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ(์†๋„ ๋น ๋ฆ„, ํ’ˆ์งˆ ์†์‹ค ์—†์Œ)
ffmpeg -i <VideoPaht> -i <AudioPath> -c copy -c:v <Value> -c:a <Value> <OutputPath.mp4>
Cut the audio
ffmpeg -i <AudioPath> -ss <StartTime> -to <EndTime> <OutAudioPath.wav>
Give offset (delay) to audio and video
ffmpeg -i <VideoPaht> -itsoffset <Offset(sec)> -i <VideoPaht> -map 0:v -map 1:a <OutputPath.mp4>
# map -0:v : ์ฒซ ๋ฒˆ์งธ ์ž…๋ ฅ ํŒŒ์ผ์„ video ์ž…๋ ฅ์œผ๋กœ ์‚ผ์Œ
# map -1:a : ๋‘ ๋ฒˆ์งธ ์ž…๋ ฅ ํŒŒ์ผ์„ audio ์ž…๋ ฅ์œผ๋กœ ์‚ผ์Œ
# ์˜ค๋””์˜ค๋ฅผ ๋’ค๋กœ ๋ฐ€๊ธฐ
subprocess.run(
    f"ffmpeg -loglevel {loglevel} -y "
    + f"-i {video_path} "
    + f"-itsoffset {delay_time} "
    + f"-i {video_path} "
    + "-map 0:v -map 1:a "  # -c:v copy -c:a copy "
    + str(save_path),
    shell=True,
)

# ๋น„๋””์˜ค๋ฅผ ๋’ค๋กœ ๋ฐ€๊ธฐ
subprocess.run(
    f"ffmpeg -loglevel {loglevel} -y "
    + f"-i {video_path} "
    + f"-itsoffset {delay_time} "
    + f"-i {video_path} "
    + "-map 0:a -map 1:v "  # -c:v copy -c:a copy "
    + str(save_path),
    shell=True,
)
ffmpeg: Other Options
  • -loglevel: ์ถœ๋ ฅ ๋ ˆ๋ฒจ ์„ค์ •. /error/์ด๋ฉด ์ถœ๋ ฅ ์•ˆ ๋‚˜์˜ด
    • quiet: ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์™ธ ์ถœ๋ ฅ ์•ˆ ํ•จ
    • panic, fatal: ์น˜๋ช…์  ์˜ค๋ฅ˜๋งŒ ์ถœ๋ ฅ
    • error: ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋งŒ ์ถœ๋ ฅ
  • -y: ์ด๋ฏธ ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ๋ฎ์–ด์“ฐ๊ธฐ
  • threads: ์‚ฌ์šฉํ•  ์“ฐ๋ ˆ๋“œ ์ˆ˜ ์„ค์ •. ๋ณ„๋„ ์ง€์ •์ด ์—†์œผ๋ฉด ์ž๋™์œผ๋กœ ์ตœ์ ํ™”.
Information of Video/Audio

Options:

  • -v: error์ด๋ฉด ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋งŒ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•ด ๊น”๋”ํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณต
  • -show_entries: ์ถœ๋ ฅํ•  ๋ถ€๋ถ„ ์ง€์ •
    • FPS: stream=r_frame_rate
    • Duration: format=duration
    • Codecs: stream=codec_type
  • -of: ์ถœ๋ ฅ ํฌ๋งท ์ง€์ •. json์œผ๋กœ JSON ํ˜•ํƒœ๋กœ ์ถœ๋ ฅ ๊ฐ€๋Šฅ.
# one query. just single line
ffprobe -v error -show_entries format=duration -of default=nk=1:nw=1 input.mp4

# multiple query. one line, one output
ffprobe -v error -show_entries format=duration,stream=codec_type -of default=noprint_wrappers=1 input.mp4
# If you want to get as scalar value in python pipeline
def get_duration(video_path):
    command = [
        "ffprobe",
        "-v",
        "error",
        "-show_entries",
        "format=duration",
        "-of",
        "json",
        video_path,
    ]
    result = subprocess.run(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
    )
    ffprobe_output = json.loads(result.stdout)
    duration = float(ffprobe_output["format"]["duration"])
    return duration
How to run in python
  • subprocess.call(command): ๋ช…๋ น์–ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ  ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜

    • args command: ๋ฆฌ์ŠคํŠธ/ํŠœํ”Œ ํ˜น์€ ๋ฌธ์ž์—ด๋กœ ์ „๋‹ฌ(shell=True์ผ ๋•Œ๋งŒ)
    • args shell: True์ผ ๊ฒฝ์šฐ ๋ช…๋ ์–ด๋ฅผ ์…ธ์„ ํ†ตํ•ด ์‹คํ–‰ํ•˜๊ณ (command๊ฐ€ ๋ฌธ์ž์˜๋ฆฌ์–ด์•ผ ํ•˜๋ฉฐ, ํŒŒ์ดํ”„๋‚˜ ๋ฆฌ๋””๋ ‰์…˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ), False(default)์ผ ๊ฒฝ์šฐ ์ง์  ์ˆ˜ํ–‰ํ•จ
    • ๋ช…๋ น์–ด ์ˆ˜ํ–‰์˜ ์ถœ๋ ฅ์„ ๋ฐ›์œผ๋ ค๋ฉด subprocess.run() ์‚ฌ์šฉ
    • return์ด 0์ด๋ฉด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ์Œ์„ ๋œปํ•จ
      result = subprocess.call(
          [
              "ffmpeg", "-y", "-framerate", "60",
              "-i", "frame_%04d.png",
              "-c:v", "libx264",
              "-pix_fmt", "yuv420p",
              "output.mp4"
          ]
      )
  • subprocess.run(command): ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ์™„๋ฃŒ ์‹œ๊นŒ์ง€ ๋Œ€๊ธฐ

    • args command: ๋ฆฌ์ŠคํŠธ๋กœ ์ „๋‹ฌ
    • capture_output: True ์‹œ stdout, stderr๋ฅผ ์บก์ณํ•จ
    • text: True์‹œ ์ถœ๋ ฅ์„ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•จ
    run(
          f"ffmpeg -loglevel {loglevel} -y "
          + f"-i {video_path} "
          + f"-itsoffset {delay_time} "
          + f"-i {video_path} "
          + "-map 0:a -map 1:v "
          + str(save_path),
          shell=True
    )
  • ๋งŒ์•ฝ ํ„ฐ๋ฏธ๋„์—์„œ ์ž˜ ์ž‘๋™ํ•˜๋Š” ๋ช…๋ น์–ด๊ฐ€ subprocess๋ฅผ ํ–ˆ์„ ๋•Œ ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด? (์—๋Ÿฌ, ์ผ๋ถ€ ๊ธฐ๋Šฅ ์ž‘๋™ ์•ˆ ํ•จ)

    • ffmpeg์˜ ํ”„๋กœ๊ทธ๋žจ ๊ฒฝ๋กœ๋ฅผ ffmpeg ๋Œ€์‹  ์ ์–ด์ฃผ๊ธฐ
    • where ffmpeg โ†’ subprocess.call(["/usr/bin/ffmpeg", ...])

Terminal Customize

iTerm2 + oh-my-zsh

OS ํ™˜๊ฒฝ๋ณ€์ˆ˜

Setting environment variables when you train a deep learning model
  • python: os.environ์œผ๋กœ ์„ค์ • (์ˆซ์ž๋Š” str์ฒ˜๋ฆฌ)
  • ๋˜๋Š” bash ํŒŒ์ผ์— export๋กœ ์„ค์ •
OMP_NUM_THREADS
MKL_NUM_THREADS
NUMEXPR_NUM_THREADS

OPENBLAS_NUM_THREADS
VECLIP_MAXIMUM_THREADS

๐Ÿง Linux

Move & Copy Files
  • move file: mv <from> <to>
  • copy file: cp <from> <to>
Count the number of files/directories
# All types
ls | wc -l

# Files
ls -l | grep ^- | wc -l

# Directories
ls -l | grep ^d | wc -l
Copy file server โ†”๏ธ local
  • scp
# if you want to copy directory, add `-r` option
scp -P <PORT_NUM> [OPTIONS] <source> <destination>

# example (server -> local) (run in local)
scp -P PORT_NUM USER@ADDRESS:SERVER_FILE LOCAL_PATH

# example (local -> server) (run in local)
scp -P PORT_NUM LOCAL_FILE USER@ADDRESS:SERVER_PATH
  • rsync
    • -e 'ssh -p <Port>': ํฌํŠธ ๋ณ€๊ฒฝ
    • -a: ์•„์นด์ด๋ธŒ ๋ชจ๋“œ. ํŒŒ์ผ ์†์„ฑ, ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ๋“ฑ ์œ ์ง€
    • -v: ์ƒ์„ธ ์ถœ๋ ฅ
    • -z: ์ „์†ก ์ค‘ ๋ฐ์ดํ„ฐ ์••์ถ•
    • -h: ํŒŒ์ผ ํฌ๊ธฐ๋ฅผ ์‚ฌ๋žŒ์ด ์ฝ๊ธฐ ์‰ฌ์šด ํ˜•์‹์œผ๋กœ ํ‘œ์‹œ
    • --progress: ์ „์†ก ์ง„ํ–‰์ƒํ™ฉ ํ‘œ์‹œ
# ํฌํŠธ ๋ณ€๊ฒฝ
rsync -avz -e 'ssh -p <Port>' <Src> <Dst>

# ํด๋” ์ „์ฒด์˜ ์ง„ํ–‰์ƒํ™ฉ ํ‘œ์‹œ
rsync -avz --info=progress2 <Src> <Dst>
Monitor GPU status
  • nvidia-smi
    • Keep watching: watch nvidia-smi
  • gpustat [OPTIONS]
    • Install: pip install gpustat
    • With -pi option, the command runs iteratively
Symbolic Link
ln -s [SOURCE] [DEST]

# e.g., you can access 'original.txt' with 'linked.txt'
ln -s /home/eungi/original.txt /home/eungi/yeah/linked.txt

# e.g., you can access 'origin_dir' with 'linked_dir'
# Don't need to make 'linked_dir' first, just type the command blow
# Do not add `/` behind the name of directories
ln -s /home/eungi/origin_dir /home/eungi/linked_dir

# e.g., change link
ln -Tfs [SOURCE] [DEST]
Disk usage, File size
# `-h` option: print the sizes in human readable format (e.g., 12M)
df -h [PATH] # Disk usage
du -h [--max-depth=0] [PATH] # Size of file/directory
ls -lh [PATH] # just for file
CPU/Memory status
htop
Process
# kill
kill -9 PID1 PID2 ...

# process list
ps -e
ps -eL | grep <Query>
Find file
  • find
     find {where-to-find} -name {name} # e.g., find / -name test*
     find {where-to-find} -name {name} -type {type} # e.g., {type} - `d` for directory, `f` for file
  • which: ์‹คํ–‰ํŒŒ์ผ/๋ช…๋ น์–ด ์œ„์น˜
  • whereis: ์‹คํ–‰ํŒŒ์ผ, ์†Œ์Šค, ๋งค๋‰ด์–ผ ํŒŒ์ผ ์œ„์น˜ (๋ชจ๋“  ๋‚ด์šฉ ์ถœ๋ ฅ)
zsh + ohmyzsh + tmux
apt-get update
apt install tmux -y

apt install -y zsh
chsh -s `which zsh` # VSCode Terminal - select default profile ๋„ ๋ณ€๊ฒฝ

# ohmyzsh ์„ค์น˜
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
conda init zsh

# ํ…Œ๋งˆ ๋ณ€๊ฒฝ
# https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
vi ~/.zshrc -> ๋ณ€๊ฒฝ(crunch) -> source ~/.zshrc

# ์ค„ ๋ฐ”๊ฟˆ
vi ~/.oh-my-zsh/themes/{THEME}.zsh-theme
# ์•„๋ž˜ ๋‚ด์šฉ ์ถ”๊ฐ€
NEWLINE=$'\n'
COND='%(?.%F{green}โฏ%f.%F{red}โฏ%f) '
# PROMPT ๋์— ${NEWLINE}${COND} ์ถ”๊ฐ€

# auto suggestion, highlighting
cd ~/.oh-my-zsh/plugins

git clone https://github.com/zsh-users/zsh-autosuggestions.git
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git

echo "source ${(q-)PWD}/zsh-autosuggestions/zsh-autosuggestions.zsh" >> ${ZDOTDIR:-$HOME}/.zshrc
echo "source ${(q-)PWD}/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ${ZDOTDIR:-$HOME}/.zshrc
 
vi ~/.zshrc
plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
source ~/.zshrc

๐ŸŽ Mac

์œ ์šฉํ•œ ์ดˆ๊ธฐ ์„ค์ •
  1. Install programs
    • Snipaste: capture, pin images
    • Keka: zip
    • CopyClip: Clipboard
    • Rectangle: window control
    • MS Edge or Chrome
    • Notion or Obsidian
  2. Trackpad
    • Drag with three figures
  3. Settings
    1. Settings > Function Keys > enable 'Use F1, F2, ...'
    2. 'Finder' app > View > 'Show Path Bar', 'Show Status Bar'
    3. 'Finder' app > Tool bar right click > Customize... > insert/delete icons
iTerm2 + zsh + ohmyzsh
  • Install
    # Install homebrew
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    echo 'export PATH=/opt/homebrew/bin:$PATH' >> ~/.zshrc
    source ~/.zshrc
    
    # Install iTerm2
    brew install iterm2
    
    # Install ohmyzsh
    sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
  • Theme: vi ~/.zshrc -> Find ZSH_THEME and change to what you want (e.g., agnoster)
  • Color
    1. Browse colors here -> https://iterm2colorschemes.com/
    2. Download the code of the picked color: curl -L0 [URL_OF_COLOR]
    3. iTerm2 > Settings > Profiles > Colors > Color presets > Import > select the downloaded file
  • Font: iTerm2 > Settings > Profiles > Font (e.g., 'D2Coding')
  • Other custom terminal settings
     ### Newline
     vi ~/.oh-my-zsh/themes/[YOUR_THEME].zsh-theme # or zshrc?
     # Find `build_prompt()` function, insert line below between `prompt_hg` and `prompt_end`
     prompt_newline
     # Insert function below
     prompt_newline() {
       if [[ -n $CURRENT_BG ]]; then
     	echo -n "%{%k%F{$CURRENT_BG}%}$SEGMENT_SEPARATOR
     %{%k%F{blue}%}$SEGMENT_SEPARATOR"
       else
     	echo -n "%{%k%}"
       fi
     
       echo -n "%{%f%}"
       CURRENT_BG=''
     }
     source ~/.zshrc
    
     ### Delete computer name: insert codes below
     vi ~/.zshrc
     prompt_context() {
       if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
     	prompt_segment black default "%(!.%{%F{yellow}%}.)$USER"
       fi
     }
     source ~/.zshrc
    
     ### Syntax highlighting (commands for M series users)
     brew install zsh-syntax-highlighting
     source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
     
     ### Auto suggestion
     brew install zsh-autosuggestions
     source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
  • Tmux install: brew install tmux
Python & virtual env. in Mac

๐ŸชŸ Windows

ํŒŒ์ผ๋ช… ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ

์œˆ๋„์šฐ์—์„œ๋Š” ํŒŒ์ผ๋ช…์ด ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š์Œ(abc.txt๋‚˜ ABC.txt๋‚˜ ๊ฐ™๋‹ค๊ณ  ์ทจ๊ธ‰). ์ด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•.

  1. ๋นˆ ํด๋” ๋งŒ๋“ค๊ธฐ
  2. ๋ช…๋ น ํ”„๋กฌํ”„ํŠธ๋ฅผ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์—ด๊ธฐ
  3. fsutil file setCaseSensitiveInfo enable
    1. "๋Œ€/์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ ํŠน์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."๋ผ๊ณ  ์ถœ๋ ฅ๋˜๋ฉด ์„ค์ • ์™„๋ฃŒ
    2. ๋น„ํ™œ์„ฑํ™”ํ•˜๋ ค๋ฉด disable๋กœ ์ธ์ž ์ฃผ๊ธฐ
  4. ์–ด๋–ป๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ๋‚˜ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด queryCaseSensitiveInfo
ํ„ฐ๋ฏธ๋„ ๊พธ๋ฏธ๊ธฐ: oh my posh

1๏ธโƒฃ ์œˆ๋„์šฐ ๋ณด์•ˆ์„ค์ • ๋ณ€๊ฒฝ - ์ฐธ๊ณ  ๋งํฌ

  • ํŒŒ์›Œ์‰˜ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์—ด๊ธฐ
  • Set-ExecutionPolicy RemoteSigned ์ž…๋ ฅ

2๏ธโƒฃ oh my posh ์„ค์น˜

  • ํŒŒ์›Œ์‰˜ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์—ด๊ธฐ
  • ์„ค์น˜: winget install oh-my-posh
  • ์ผ๋ฐ˜ ๊ถŒํ•œ์œผ๋กœ ๋‹ค์‹œ ์—ด๊ธฐ
  • oh-my-posh get shell: ์‹คํ–‰ ์‹œ pwsh์ด ๋‚˜์˜ค๋ฉด ๋จ

3๏ธโƒฃ Theme ์„ ํƒ - ํ…Œ๋งˆ ๋ชฉ๋ก

  • New-Item -Path $PROFILE -Type File -Force: ์„ค์ • ํŒŒ์ผ ๋ฉ”๋ชจ์žฅ ์—ด๊ธฐ ์ „, ์—๋Ÿฌ ๋ฐฉ์ง€
  • notepad $PROFILE: ์„ค์ • ํŒŒ์ผ์ด ๋ฉ”๋ชจ์žฅ ์—ด๋ฆผ (๋นˆ ํŒŒ์ผ)
  • ์•„๋ž˜ ๋‚ด์šฉ ์ž…๋ ฅ ํ›„ ์ €์žฅ
oh-my-posh init pwsh --config 'https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/<ํ…Œ๋งˆ_json_ํŒŒ์ผ>' | Invoke-Expression

4๏ธโƒฃ ๊ธ€๊ผด ์„ ํƒ - ํฐ๋“œ ๋ชฉ๋ก

  • ํŒŒ์›Œ์‰˜ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์—ด๊ธฐ
  • oh-my-posh font install: ๋‹ค์šด๋กœ๋“œ ๊ฐ€๋Šฅํ•œ ๊ธ€๊ผด ๋ชฉ๋ก ๋ณด์ž„. ์›ํ•˜๋Š” ๊ฒƒ ๋‹ค์šด๋กœ๋“œ.
  • ํŒŒ์›Œ์‰˜ ์ผ๋ฐ˜ ์—ด๊ธฐ - ์„ค์ • - ์ผ๋ฐ˜ - ๋ชจ์–‘ - ๊ธ€๊ผด ๋ณ€๊ฒฝ

5๏ธโƒฃ VSCode ์ ์šฉ

  • settings.json ์—ด๊ธฐ
  • "terminal.integrated.fontFamily": "CaskaydiaCove Nerd Font" : ํฐํŠธ ์„ค์ •

6๏ธโƒฃ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋“ฑ ์„ค์ •

  • ํ„ฐ๋ฏธ๋„์—์„œ notepad $PROFILE์œผ๋กœ ์„ค์ • ํŒŒ์ผ ์—ด๊ธฐ ํ›„ ์•„๋ž˜ ๋‚ด์šฉ ์ž…๋ ฅ
oh-my-posh init pwsh --config "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/atomic.omp.json" | Invoke-Expression

Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -PredictionViewStyle ListView

Set-PSReadLineOption -HistorySearchCursorMovesToEnd
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward

Import-Module posh-git

7๏ธโƒฃ Git bash ์ ์šฉ - ์ฐธ๊ณ  ๋งํฌ

  • ํ…Œ๋งˆ json ํŒŒ์ผ ๋กœ์ปฌ์— ์ €์žฅ
    • .bashrc ํŒŒ์ผ์— ์•„๋ž˜ ๋‚ด์šฉ ์ž…๋ ฅ ํ›„ ์ €์žฅ, ์ ์šฉ
eval "$(oh-my-posh --init --shell bash --config ~/atomic.omp.json)"

8๏ธโƒฃ ์ถ”๊ฐ€ ์ฐธ๊ณ  ๋งํฌ

Blender

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

1 watching

Forks

Contributors