Python Basic: Reverse Dict Mapping

아래에 class라는 dict가 하나 정의되어 있습니다. 번호와 이름이 맵핑되어있는 dict에요.

my_class = { \
    "1": "ellie", \
    "2": "kevin", \
    "3": "daniel" \
}

여기서 번호를 가지고 이름을 찾을때는 my_class[번호]로 이름을 찾을수가 있는데 반대로 이름을 가지고 번호를 찾고 싶을때는 배열을 뒤집어야겠죠. 아래와 같이 tuple쌍을 배열로 만들고 dict로 변환할수도 있지만

new_dict = dict([(val, key) for key, val in my_class.items()])

바로 dict로 만들면 더 간단명료해지겠죠?

new_dict = {val: key for key, val in my_class.items()}

이렇게 key와 value를 뒤집은 배열을 만든뒤, new_dict[번호]를 반환해주면 되겠죠?

Find Denied Field in JSON

When you take JSON data, you may want to reject certain fields from the JSON structure. Here’s an algorithm to compare the source JSON and the denied fields list and return True if there’s any field that is not allowed in the source JSON.

# Here's a function that checks if there's any not-allowed-fields are included in the source JSON data
def is_denied_field_in_json(deny={}, source={}):
    for key, t_val in deny.items():
        s_val = source.get(key)
        if s_val is None:
            continue
        elif not isinstance(t_val, dict):
            return True
        elif isinstance(t_val, dict)\
            and isinstance(s_val, dict)\
            and is_denied_field_in_json(t_val, s_val):
                return True
    return False

# This is the JSON data a user tries insert
source = {
    "a": 1,
    "b": {
        "bb": 2,
    },
    "c": 3,
    "d": {
        "dd": {
            "ddd": {
                "dddd": 4
            }
        }
    }
}

# Here're the test deny lists you can define in your code
deny_list_true1 = {
    "a": 0,
}
deny_list_true2 = {
    "n": 0,
    "a": 0,
}
deny_list_true3 = {
    "b": {
        "bb": 0
    }
}
deny_list_true4 = {
    "b": {
        "n": 0
    },
    "c": 3
}
deny_list_true5 = {
    "d": {
        "dd": {
            "ddd": 0
        }
    }
}
deny_list_false1 = {
    "n": 0,
}
deny_list_false2 = {
    "b": {
        "n": 0
    }
}
deny_list_false3 = {
    "d": {
        "n": {
            "dd": {
                "ddd": 0
            }
        }
    }
}
print(is_denied_field_in_json(deny_list_true1, source))
print(is_denied_field_in_json(deny_list_true2, source))
print(is_denied_field_in_json(deny_list_true3, source))
print(is_denied_field_in_json(deny_list_true4, source))
print(is_denied_field_in_json(deny_list_true5, source))
print(is_denied_field_in_json(deny_list_false1, source))
print(is_denied_field_in_json(deny_list_false2, source))
print(is_denied_field_in_json(deny_list_false3, source))

SQLAlchemy Tutorial

Starting from the basic connection, this lecture will tell you how to get the total number of the grouped subquery records.

Basic connection

# Access the app container
docker exec -it container_id sh

# Run python
python

# Connect to the database
import sqlalchemy as db
engine = db.create_engine('mysql+pymysql://root:root@container_name/db_name')
connection = engine.connect()

# Connection Test
metadata = db.MetaData()
table_name = db.Table('table_name', metadata, autoload=True, autoload_with=engine)

# Print all columns in the table
table_columns = table_name.columns.keys()

Query

query = db.select([table_name]).limit(1)
result_proxy = connection.execute(query)
result_set = result_proxy.fetchall()

Session

from sqlalchemy.orm import sessionmaker

Session = sessionmaker(bind=engine)
session = Session()

Model

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class TableName(Base):
    __tablename__ = 'table_name'
    id = db.Column('key', primary_key=True)
    name = db.Column('title')

class AnotherTableName(Base):
    __tablename__ = 'another_table_name'
    id = db.Column('id', primary_key=True)
    tablename_id = db.Column('tablename_id')
    title = db.Column('title')

result = session.query(db.func.count(TableName.id),TableName.id).group_by(TableName.id).all()

Join

query = session.query(TableName)
query = query.outerjoin(AnotherTableName, TableName.id == AnotherTableName.tablename_id)
query = query.filter(AnotherTableName.title == "apple")
result = query.all()

Declare the Query

mysql> select count(*) from table_name group by id

+----------+
| count(*) |
+----------+
|        1 |
...
|        1 |
|        1 |
|        1 |
+----------+
1483 rows in set (0.25 sec)

mysql> select count(*) from (select count(*) from table_name group by id) a;
+----------+
| count(*) |
+----------+
|     1483 |
+----------+
1 row in set (0.01 sec)

Group by

query = session.query(TableName.id, func.count('*').label("count"))
query = query.outerjoin(AnotherTableName, TableName.id == TableName.tablename_id)
query = query.filter(AnotherTableName.title == 'apple'))
query = query.group_by(TableName.id)
result = query.all()

Subquery

query = session.query(TableName.id, func.count('*').label("count"))
query = query.outerjoin(AnotherTableName, TableName.id == AnotherTableName.tablename_id)
query = query.filter(AnotherTableName.title == 'apple'))
query = query.group_by(TableName.id)
t = query.subquery()

total = session.query(func.count(t.c.count)).scalar()

References

Flask + uWSGI + Docker

Flask

Install Flask.

$ pip install flask

Make an application.

$ vi hello.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

Test application.

$ FLASK_APP=hello.py flask run --port 5555

Check the result.

uWSGI

Create a uWSGI configuration file.

$ vi uwsgi.ini
[uwsgi]
module = hello:app
uid = www-data
gid = www-data
master = true
processes = 1

http = 0.0.0.0:5000
chmod-sock = 664
vacuum = true

die-on-term = true

Run uWSGI.

$ uwsgi --ini uwsgi.ini

Check the result.

Docker

Make a file to list the required modules to install in the docker container.

$ vi requirements.txt
Flask==1.0.2
uWSGI==2.0.17.1

Create Dockerfile.

FROM python:3.6-slim

COPY ./hello.py /app/hello.py
COPY ./uwsgi.ini /app/uwsgi.ini
COPY ./requirements.txt /app/requirements.txt

WORKDIR /app

RUN apt-get clean \
    && apt-get -y update

RUN apt-get -y install python3-dev \
    && apt-get -y install build-essential

RUN pip install -r requirements.txt --src /usr/local/src

CMD ["uwsgi", "--ini", "uwsgi.ini"]

Build Docker image

$ docker build . -t app_image

Run Docker

$ docker run --name app_container -p 80:5000 app_image

Check the result

References:

Manually Install Python Packages

만약 여러분의 local machine에 Python Package source code가 있다면, pip install을 이용하지 않고 모듈을 설치하는 방법이 있습니다. 바로 setup.py를 실행하는 방법인데요. 이 파일은 여러분이 Python Package를 만들고자 할때 root folder에 반드시 넣어야하는 파일인데요, python package를 만드는 방법에 대해서는 다음에 자세히 다루도록하겠습니다. 우선 소스코드가 있는 폴더로 이동을 하신후에 아래의 명령을 실행해주세요. 그러면 로컬 머신에 패키지가 설치가 됩니다.

python setup.py install

Dict as Class

class MyClass(object):
    a = '12'
    b = '34'
    def f(self):
        return self.a

getattr(MyClass, 'a')
getattr(MyClass, 'c')
getattr(MyClass, 'c', False)
callable(getattr(MyClass, 'a'))

d = {
    'a': '123',
    'b': '123',
    'c': '123',
    'f': '123'
}

for key in d.keys():
    try:
        if getattr(MyClass, key):
            if not callable(getattr(MyClass, key)):
                print(f'key: {key} is defined variable')
            else:
                print(f'key: {key} is a member function')
    except AttributeError:
        print(f'key: {key} is not defined')