AttackOnNunu

Once more into the fray


  • 홈

  • About

  • 태그

  • 카테고리

  • 아카이브

  • 검색

(PYTHON) 파이썬의 easter egg

작성일 2020-02-25 In LANGUAGE 🚀 , PYTHON , TERMINOLOGY 댓글:

Reference

  • antigravity.py 소스코드 - github.com/python/cpython/…
  • xkcd 링크 - xkcd.com/353
  • python easter eggs - repl.it/talk
  • Curated list of all the easter eggs and hidden jokes in Python - github.com/OrkoHunter/
  • 파이썬 선 번역 - kenial.tistory.com
  • sytax error not a chance - stackoverflow.com

개인적인 생각과 상상으로 작성한 내용들이 포함되어 있습니다


이메일로 받아보는 [🐍PyTricks]를 통해서 CPython에 있는 이스터에그(easter egg) 하나를 알게되었습니다.

Antigravity

우선 [🐍PyTricks]를 통해 알게된 Antigravity 모듈을 먼저 알아보겠습니다.

import antigravity 

antigravity 모듈을 호출하게되면 xkcd 홈페이지가 열리면서 짧은 만화를 볼 수 있습니다.

(Left: 원본, Right: 한국어 번역)

파이썬의 철학을 간결하고 재치있게 4컷 만화에 담았습니다.
여기서 끝이 아니라 antigravity.py 소스코드를 살펴보게 되면,

import webbrowser
import hashlib

webbrowser.open("https://xkcd.com/353/")

def geohash(latitude, longitude, datedow):
'''Compute geohash() using the Munroe algorithm. >>> geohash(37.421542, -122.085589, b'2005-05-26-10458.68')
37.857713 -122.544543
''' # https://xkcd.com/426/
h = hashlib.md5(datedow).hexdigest()
p, q = [('%f' % float.fromhex('0.' + x)) for x in (h[:16], h[16:32])]
print('%d%s %d%s' % (latitude, p[1:], longitude, q[1:]))

geohash() 함수가 숨어있는 것을 확인할 수 있으며 이에 대한 설명은 xkcd 홈페이지에서 찾을 수 있습니다.


이참에 Python의 다른 이스터에그는 어떤 것들이 있는지 찾아보았습니다.

Hello World!

프로그래밍을 배우는 사람이라면 꼭 외치는 한마디가 있죠.


> > > import **hello**
> > > Hello World!

The Zen of Python

this 모듈을 호출하면 파이썬의 철학 (the zen of python)의 전문을 바로 확인할 수 있습니다.


> > > import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

한글 번역은 다음과 같습니다. (임의로 앞에 번호를 붙였습니다)

1 아름다움이 추함보다 좋다.
2 명시가 암시보다 좋다.
3 단순함이 복잡함보다 좋다.
4 복잡함이 꼬인 것보다 좋다.
5 수평이 계층보다 좋다.
6 여유로운 것이 밀집한 것보다 좋다.
7 가독성은 중요하다.
8 특별한 경우라는 것은 규칙을 어겨야 할 정도로 특별한 것이 아니다.
9 허나 실용성은 순수성에 우선한다.
10 오류 앞에서 절대 침묵하지 말지어다.
11 명시적으로 오류를 감추려는 의도가 아니라면.
12 모호함을 앞에 두고, 이를 유추하겠다는 유혹을 버려라.
13 어떤 일에든 명확한 - 바람직하며 유일한 - 방법이 존재한다.
14 비록 그대가 우둔하여 그 방법이 처음에는 명확해 보이지 않을지라도.
15 지금 하는게 아예 안하는 것보다 낫다.
16 아예 안하는 것이 지금 당장 보다 나을 때도 있지만.
17 구현 결과를 설명하기 어렵다면, 그 아이디어는 나쁘다.
18 구현 결과를 설명하기 쉽다면, 그 아이디어는 좋은 아이디어일 수 있다.
19 네임스페이스는 대박 좋은 아이디어다 -- 마구 남용해라!
파이썬 핵심 개발자 Tim Peters가 제안한 가이드라인은 20개이며 빠진 내용은 “some bizarre Tim Peters in-joke.” 입니다. 누가 파이썬 창시자인 귀도 반 로섬에게 질문하고 들은 내용이라고 합니다

삭제된 하나의 가이드라인은 무엇이죠? - stackoverflow

C-style braces

아시다싶이 Python에서는 코드 블록을 구분할 때 괄호(brace)를 사용하지 않고 들여쓰기(indentation)를 사용합니다.
프로그래머 마다 각자 선호하는 코딩 스타일이 있고 이는 마치 종교처럼 나뉘어져 있습니다.
종교의 자유가 있듯이 파이썬에서도 괄호를 사용하는 코드 스타일을 허용해 줄까요?


> > > from **future** import braces
> > > File "<stdin>", line 1
> > > SyntaxError: not a chance

~ 어림도 없지!!! ~
__future__ 모듈은 파이썬 2, 3 사이의 호환성 문제를 해결하기 위한 모듈입니다. 파이썬 2에서도 파이썬 3에서 사용하는 문법을 쓸수 있도록 해줍니다. 단어대로 해석하자면 미래에 사용되는 ~한 기능을 가져와서 사용하겠다가 되겠습니다.
괄호 사용을 선호하는 프로그래머를 위해 braces 기능을 넣어주겠지? 하는 마음에 모듈을 호출해보면 SyntaxError로 not a chance 라고 그럴일은 없다고 단호하게 출력되는 것이 유머 입니다.


> > > from **future** import test
> > > File "<stdin>", line 1
> > > SyntaxError: future feature test is not defined

__future__ 모듈에 없는 임의의 모듈을 호출하면 그냥 선언되어 있지 않다고 왠지 모르게 밋밋한 답변을 볼 수 있습니다.



(PYTHON) 문자열 포맷팅

작성일 2020-02-24 In LANGUAGE 🚀 , PYTHON , TERMINOLOGY 댓글:

Reference

  • Python 공식 문서 - 7. Input and Output

개인적인 생각과 상상으로 작성한 내용들이 포함되어 있습니다


(본 내용에서 파일 입/출력은 생략하겠습니다)
조금 과장되게 말해서 파이썬에서 입력과 출력은 input() 함수와 print() 함수만 알면 끝입니다.
파이썬은 input() 함수를 통해 입력되는 모든 것을 string 자료형으로 통일시켜 마치 쌈 싸서 한 입에 먹는 것 처럼 처리합니다. (이 한 뭉텅이의 입력 데이터를 연산의 필요에 따라 int, list 등의 다른 자료형으로 변환시키거나 특정 구분자로 split() 함수를 사용해 분리시키기도 합니다. 중요한건 들어올 때는 참 쉽다는 것입니다.)
어떻게 입력 받는지 보다 어떻게 출력 되는지가 더 중요하다는 것은 아닙니다. 하지만 ‘보기 좋은 떡이 먹기도 좋다’ 라는 속담이 있듯이 많은 사람들이 입력 보단 프로그램의 결과물인 출력 방법에 더 정성을 쏟는 것 같습니다.

String Formatting

  • Python 3.8 공식 문서를 보면 3가지 방법이 소개 되어 있습니다.(manual formatting 생략)

Formatted String Literals

줄여서 f-strings 라고 불립니다. 파이썬 3.6 버전 이상부터 지원합니다.
문자열 '' 앞에 f 혹은 F 를 붙여서 사용하며 변수는 {} 안에 변수명으로 호출합니다.({} 안의 공간을 format field라고 부릅니다.)


> > > import math
> > > print(f'The value of pi is approximately {math.pi}.')
> > > The value of pi is approximately 3.141592653589793.

{expression} 안에 : 뒤에 optional format specifier를 지정할 수 있습니다.


> > > # optional format specifier 지정
> > >
> > > print(F'The value of pi is approximately {math.pi:.3f}.')
> > > The value of pi is approximately 3.142.

> > > # 문자열의 공간을 지정할 수 도 있습니다
> > >
> > > table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
> > > for name, phone in table.items():
> > > ... print(f'{name:10} ==> {phone:10d}')
> > > ...
> > > Sjoerd ==> 4127
> > > Jack ==> 4098
> > > Dcab ==> 7678

{} 안에서 기본적인 산술 연산이 가능합니다.


> > > a, b = 5, 7
> > > print(f'{a + b}')
> > > 12

호출할 변수를 나중에 선언하는 것도 가능합니다.


> > > h = f'Hello {w}'
> > > w = 'World!'
> > > print(h)
> > > Hello World!

str.format() Method

문자열 '' 뒤에 .format() 함수를 붙여 사용하는 방법입니다.


> > > print('We are the {} who say "{}!"'.format('knights', 'Ni'))
> > > We are the knights who say "Ni!"

format() 함수 안에 있는 객체들이 format field 즉, {} 안의 내용으로 대입됩니다. Format field 안에 번호를 붙여줌으로 객체들의 순서를 바꿀 수도 있습니다.


> > > print('{0} and {1}'.format('spam', 'eggs'))
> > > spam and eggs
> > > print('{1} and {0}'.format('spam', 'eggs'))
> > > eggs and spam

Format field에는 숫자뿐만이 아니라 keyword 이름으로 넣을 수 있습니다.


> > > print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred', other='Georg'))
> > > The story of Bill, Manfred, and Georg.

Old string formatting

C 언어의 printf 방식과 비슷한 방법입니다.
데이터 타입에 맞춰서 % 뒤에 오는 문자를 지정해 줘야하고 가독성이 떨어지는 단점이 있습니다.
(int 타입이지만 %s 를 사용해도 왜 정상적으로 출력되는 이유를 잘 모르겠습니다ㅠ 반대로하면 TypeError: %d format: a number is required, not type 에러가 출력됩니다.)


# example 1

> > > text = 'World!'
> > > print('Hello %s' % text)
> > > Hello World!

# example 2

> > > name = 'Eric Idle'
> > > age = 74
> > > job = 'comedian'
> > > affiliation = 'Monty Python'

> > > print('Hello %s. You are %d. You are a %s. You were a member of %s' % (name, age, job, affiliation))
> > > Hello Eric Idle. You are 74. You are a comedian. You were a member of Monty Python
> > > print('You are %s. Type? %s' % (age, type(age)))
> > > You are 74. Type? <class 'int'>

비교


# time.py written in PyCharm

from timeit import timeit

print('f-string: ', timeit("f'{name} is {age}'", setup='name = "Guido"; age=64'))
print('format(): ', timeit("'{} is {}'.format(name, age)", setup='name = "Guido"; age=64'))
print('% operator:', timeit("'%s is %s' % (name, age)", setup='name = "Guido"; age=64'))
f-string: 0.22740733000000002
format(): 0.471766373
% operator: 0.3950569239999999

f-string 방식이 가장 빠른 것을 확인할 수 있습니다.

결론

Formatted String Literals 즉, f-string 사용을 권장합니다.



(PYTHON) Day - 8 Strings(4)

작성일 2020-02-21 In LANGUAGE 🚀 , PYTHON , HACKERRANK 댓글:

Reference

  • 문제 출처 - HackerRank
  • 파이썬 연습 - Practice - Python

개인적인 생각과 상상으로 작성한 내용들이 포함되어 있습니다
문제를 풀고 Discussion Tab을 참고하며 코드 스타일을 개선하려고 노력하고자 합니다



HackerRank

HackerRank의 Python 연습문제들은 아래와 같은 카테고리로 분류 된다:

Subdomain

  • Introduction
  • Basic Data Types
  • Strings
  • Sets
  • Math
  • Itertools
  • Collections
  • Date and Time
  • Errors and Exceptions
  • Classes
  • Built-Ins
  • Python Functionals
  • Regex and Parsing
  • XML
  • Closures and Decorators
  • Numpy
  • Debugging


Strings

Problem

  • Capitalize!
  • The Minion Game
  • Merge the Tools!

기본 개념

Capitalize!

문제 : 사람 이름의 첫 문자를 대문자로 바꾸는 문제

  • INPUT
  • OUTPUT

chris alan

Chris Alan

os 패키지는 표준 라이브러리를 다루면서 한번 정리할 예정

def solve(s):
return ' '.join(i.capitalize() for i in s.split(' '))

if **name** == '**main**':
fptr = open(os.environ['OUTPUT_PATH'], 'w')

s = input()

result = solve(s)

fptr.write(result + '\n')

fptr.close()

The Minion Game

문제 : 문자열 S를 입력받으면 두 사람(Stuart, Kevin) 각각 자음(consonant), 모음(vowel)으로 시작하는 단어 조합의 총 개수를 비교하여 큰 사람의 이름과 그 숫자를 출력하는 문제
예제 : ‘BANANA’에서 ‘ANA’는 2번 나타나기 때문에 score는 2가 된다. 아래 그림을 참고
minion game

  • INPUT
  • OUTPUT

BANANA

Stuart 12

def minion_game(string):
player = {'Stuart': 0, 'Kevin': 0}
vowels = 'AEIOU'

str_l = len(string)
for i, c in enumerate(string):
if c in vowels:
player['Kevin'] += str_l - i
else:
player['Stuart'] += str_l - i

if player['Stuart'] == player['Kevin']:
print('Draw')
elif player['Stuart'] > player['Kevin']:
print('Stuart', player['Stuart'])
else:
print('Kevin', player['Kevin'])

if **name** == '**main**':
s = input()
minion_game(s)

Several optimizations.

  • Use frozenset for the vowels. This is the fastest to lookup in.

  • Iterate through characters instead of indexing

  • Iterate q reverse to avoid a subtraction in each sum

  • Avoid repeated calls to len

  • Only calculate Kevins score the hard way. Use the fact that the total number of substrings is n * (n + 1) / 2 and find Stuart’s score by subtracting Kevin’s from the total number of substrings.

    def minion_game(s):
    V = frozenset("AEIOU")
    n = len(s)
    ksc = sum(q for c, q in zip(s, range(n, 0, -1)) if c in V)
    ssc = n \* (n + 1) // 2 - ksc
    if ksc > ssc:
    print("Kevin {:d}".format(ksc))
    elif ssc > ksc:
    print("Stuart {:d}".format(ssc))
    else:
    print("Draw")

Merge the Tools!

입력 : 문자열 s와 정수 k를 입력받는다(k는 문자열 길이(n)의 약수)
출력 : k의 배수에 위치한 문자를 기준으로 sub-문자열을 구분하고 반복되는 문자는 삭제해서 출력
예제 : 문자열 ‘AABCAAADA’에서 길이 3으로 자르면 ‘AAB’ ‘CAA’ ‘ADA’ 3개의 sub-문자열로 나뉘고 여기서 중복되는 문자를 제거하면 ‘AB’ ‘CA’ ‘AD’가 된다

  • INPUT
  • OUTPUT

AABCAAADA
3

AB
CA
AD

문제의 조건을 직접 충실히 확인하는 기초적인 방법

def merge_the_tools(string, k):
sub_str = []
for i in range(len(string)):
if string[i] not in sub_str:
sub_str.extend(string[i])
if (i+1) % k == 0:
print(''.join(sub_str))
del sub_str[:]

if **name** == '**main**':
string, k = input(), int(input())
merge_the_tools(string, k)

main 함수일 때 실행한다는 코드는 생략

  • textwrap은 지난 문제에서 다뤘지만 OrderedDict 패키지는 처음봤지만 이런 방법도 있다

      from collections import OrderedDict
    import textwrap

    def merge_the_tools(string, k):
    b=textwrap.wrap(string,k)
    for i in range (len(b)):
    print("".join(OrderedDict.fromkeys(b[i])))
  • 가장 인기가 높은 해답

  • Discussion forum 참고!

    S, N = input(), int(input())
    for part in zip(_[iter(S)] _ N):
    d = dict()
    print(''.join([ d.setdefault(c, c) for c in part if c not in d ]))


1…111213…33
NUNU

NUNU

개인적으로 공부하면서 정리한 내용들을 블로그에 남기고 있습니다.
99 포스트
18 카테고리
53 태그
RSS
Creative Commons
© 2021 NUNU
Powered by Hexo v3.9.0
|
Theme – NexT.Mist v7.2.0