SlideShare a Scribd company logo
リーダブルコード
 読み易いコードの書き方
リーダブルコード

• Dustion Boswell,
  Trevor Foucher 著

• 角征典 訳

• 1-2週間で読める

•  他の書籍より読み易い
  のでオススメ
リーダブルコードとは? 

• リーダブルコード、つまり読み易いコード

• 読み易いと何がいいの?

• 他人が最短時間で理解できるようになる
 (他人とは半年後の自分も含む)
理解とは?

• 仕様がわかる     

• バグがわかる

• 変更方法がわかる

• 他との連携する方法がわかる
理解しやすいコードの
   書き方
表面上の問題
ネーミング 
名前に情報を詰め込む

• 明確な単語を選ぶ

 Getじゃなくてfetchとかdownloadとかにする

 例)send     deliver, dispatch, distribute

     find       search, extract, locate 

     start      launch, create, begin, open

     make     create, set up, build, generate, add, new
汎用的な名前は避ける

• tmpとかresultとか     

• でもローカル変数で使う場所が狭ければ
 使ってもいいよ!

• ループのイテレータとかはi・j・kでOK
名前に情報を追加する

• time -> time_ms
• size -> size_mb
 名前の長さ



• スコープが小さければ、短い名前でよい
名前のフォーマット(例
• kConstantName          定数

• CONSTANT_NAME     マクロ

• ClassName                   クラス

• methodName               メソッド

• variable_name             変数
誤解されない名前(例     
• min, max     限界値を含む

• first, last      範囲指定

• begin, end   包含、排他的範囲(endは含まれない

• bool             isやhasをつける、否定型にしない

• get             getは軽量アクセサである

             getで重くなるような計算してはいけない
美しさ
余白、配置、順序
余白


• インデント、空行によってブロックや段
 落を整える(縦のラインを意識

• 論理的な区切りができる
配置


• 同様の処理はシルエットを える

• メソッドを使って える
 DRY化にもなる
順序

• 順序は変えない

• A・B・Cとあった情報をB・C・Aにして
 はいけない

• 一貫性が大事
コメント
コメントすべきこと
 コメントすべきでは"ない"こと

• コードからわかることを書かない

• コメントのためのコメントを書かない

 例)関数には必ずコメントを書かなければならない

   // 名前を取得する  ←意味がない

   getName();

• ひどいコードの場合はコメントを書くより修正する
自分の考えを記録する

• 映画のコメンタリーのようなもの

• コードを書いた時の背景や理由がわかる

• Why, How, Whatは特にこだわらなくて
 もよい
欠陥をコメントする



• // TODO:もっと高速化が必要

• // XXX:破壊的なメソッド!
 全体像をコメントする


• // このクラスはキャッシュです、システ
 ムのことは関知しません

• // このクラスはファイルシステムに関す
 るヘルパー関数を提供します
要約をコメントする

• // ロックを取得

• // ユーザの情報をDBから読む

• // 情報をファイルに書き出す

• // ロックを開放
正確で完結に
完結に書く



• 領域に対する情報の比率が高くなければ
 いけない
代名詞はさける    



• それ、これ
 ⇒ データを、価格を
 正確に記述する



• // 行数を返す
 ⇒   // 改行文字(n)を数える
実例を使う



• // 例) Strip("abba/a/ba", "ab") => "/a/"
コードの意図を書く



• // 逆順で表示する
 ⇒ // 値段の高い順に表示する
ループとロジックの単純化
制御フロー
自然に書く

• if( length > 10 )    ←こっちのほうがいい
 if(10 <= length)

• 左側:調査対象の式、変化する

• 右側:比較対象の式、あまり変化しない
if/elseブロックの書き方


• 否定形よりも肯定形

• 単純な条件を先に

• 関心を引く条件や目立つ条件を先に
三項演算子



• 使うならわかりやすく
関数から早く返す



• ガード節とか
ネストは浅く



• 早めに返す、内部のネストを関数化する
式の分割



• 巨大な式を飲み込みやすい大きさに
説明変数を導入する


• line.split(":").[0] == “Bob”
• user_name = line.split(":").[0];
  user_name == “Bob”
ロジックを書き直す

• ド・モルガンの法則を使う

• 反対にすると、簡単になるかもしれない

• 重なる範囲を探す
 ⇒ 重ならないケースを探す
変数と読みやすさ

• 変数を削除する

• 変数のスコープを縮める

• 変数は一度だけ書き込む

 変数がどこで書き変えられたかを追跡するのは難しい

 constやfinalでイミュータブルにするのは有効
コードの再構成
無関係の下位問題

1. このコードの高レベルな目標は何かを見定める

2. 高レベルの目標に直接関係あるのか、無関係の
下位問題なのか見分ける

3. 無関係の下位問題を抽出する
無関係の下位問題


• プロジェクト固有のコードから汎用コードを
 分離すること

• ヘルパーをたくさん作る
1度に1つのことを

• コードは1つずつタスクを処理しなけれ
 ばならない

• タスクは小くできる

• そのコードで行なわれているタスクを列
 挙し、分割し、適用させる
コードに思いを込める



• ロジックを簡単な言葉で説明する、それ
 に合せてコードも書く
短いコード
質問と要求の分割

• 「その機能の実装について悩まない、
 きっと必要ないから」

•  過剰な機能を抑えて、単純に実装する

• 全てのプログラムがあらゆる入力に対応
 し、高速である必要はない
コードを小く保つ



•  定期的に見直す
ライブラリを使う

• 平均的なエンジニアが1日に書く"出荷用"のコー
 ドは10行

• 設計・デバッグ・修正・文章・最適化・テストな
 どのコストを含んだ値

• なるべくコードを再利用をする
  Unixのコマンドを使う


• 実装するよりコマンドを直接呼んだ方が
 いい

•  awkとかegrepとか便利
テスト
テストも読み易く
 保守しやすいものにする

• テストが複雑だと…

• 本物のコードを修正しなくなる

• テストを追加しなくなる
最小のテストを作る  



• 入出力のテストなどは1行でかけると良い
独自のミニ言語を実装する



• テスト用に実装しちゃう

• DSLとか
エラーメッセージ

• エラーが発生しました!
 じゃわからない

• エラー時の変数の値を出力すると良い

• assertを書き変えてカスタマイズするの
 もアリ
テストの入力値


• コードをテストする最も単純な入力値の
 組み合せにする

 checkScore("999.97, -246, 3", )
 checkScore("1e100, -1, 2")
1つの機能で複数のテスト

•  小さなテストを複数作る
 assert(“Barack”, person.firstName)

 assert(“Obama”, person.familyName)

 assert(“male”, person.sex)
テストの名前は適切に



•  テストからしか呼ばれないので、冗長で
 説明的でよい
やりすぎ注意  

• テストのために本物のコードを犠牲にする

• テストのカバレッジを100%にしないと気が
 すまない     

 90%でよい、残りの10%はUIやどうでもい
 いエラーである
まとめ
• ネーミング

 わかりやすい名前をつける

• 分割

  飲み込みやすい大きさに分割

• コメント

 そのコードの狙いは、なぜそのコードを書いたのかを書く

• スタイル(見た目)

 インデントやブロックを   えて見た目で理解できるように
 理解しやすいコードを書こう!
END

More Related Content

What's hot

fastTextの実装を見てみた
fastTextの実装を見てみたfastTextの実装を見てみた
fastTextの実装を見てみた
Yoshihiko Shiraki
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Shin Ohno
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
Kumazaki Hiroki
 
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
NTT DATA Technology & Innovation
 
継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator
Yahoo!デベロッパーネットワーク
 
Bloom filter
Bloom filterBloom filter
Bloom filter
Kumazaki Hiroki
 
Apache Solr 検索エンジン入門
Apache Solr 検索エンジン入門Apache Solr 検索エンジン入門
Apache Solr 検索エンジン入門
Yahoo!デベロッパーネットワーク
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
Recruit Technologies
 
LT資料「リーダブルコードまとめ」
LT資料「リーダブルコードまとめ」LT資料「リーダブルコードまとめ」
LT資料「リーダブルコードまとめ」
Atelier Frameworks
 
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
gree_tech
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
murachue
 
RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話
Takuto Wada
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
Ryuji Tsutsui
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
NTT Communications Technology Development
 
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
Takayuki Yato
 
差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)
Kentaro Minami
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
Kumazaki Hiroki
 
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
Yahoo!デベロッパーネットワーク
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
Seiya Mizuno
 
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
Takayuki Shimizukawa
 

What's hot (20)

fastTextの実装を見てみた
fastTextの実装を見てみたfastTextの実装を見てみた
fastTextの実装を見てみた
 
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
Mercari JPのモノリスサービスをKubernetesに移行した話 PHP Conference 2022 9/24
 
本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話本当は恐ろしい分散システムの話
本当は恐ろしい分散システムの話
 
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
MLOps に基づく AI/ML 実運用最前線 ~画像、動画データにおける MLOps 事例のご紹介~(映像情報メディア学会2021年冬季大会企画セッショ...
 
継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator継続的なモデルモニタリングを実現するKubernetes Operator
継続的なモデルモニタリングを実現するKubernetes Operator
 
Bloom filter
Bloom filterBloom filter
Bloom filter
 
Apache Solr 検索エンジン入門
Apache Solr 検索エンジン入門Apache Solr 検索エンジン入門
Apache Solr 検索エンジン入門
 
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけRDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
 
LT資料「リーダブルコードまとめ」
LT資料「リーダブルコードまとめ」LT資料「リーダブルコードまとめ」
LT資料「リーダブルコードまとめ」
 
PHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったことPHPからgoへの移行で分かったこと
PHPからgoへの移行で分かったこと
 
目grep入門 +解説
目grep入門 +解説目grep入門 +解説
目grep入門 +解説
 
RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)分散トレーシング技術について(Open tracingやjaeger)
分散トレーシング技術について(Open tracingやjaeger)
 
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
 
差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)差分プライバシーとは何か? (定義 & 解釈編)
差分プライバシーとは何か? (定義 & 解釈編)
 
分散システムについて語らせてくれ
分散システムについて語らせてくれ分散システムについて語らせてくれ
分散システムについて語らせてくれ
 
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
Kubernetes as a ServiceをProduction環境で2年活用し、直面してきた課題と解決策 / YJTC19 in Shibuya A...
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
 
Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略Webアプリを並行開発する際のマイグレーション戦略
Webアプリを並行開発する際のマイグレーション戦略
 

Similar to リーダブルコード

リーダブルコード 1.0'
リーダブルコード 1.0'リーダブルコード 1.0'
リーダブルコード 1.0'
Yamamura Takashi
 
Web本文抽出 using crf
Web本文抽出 using crfWeb本文抽出 using crf
Web本文抽出 using crfShuyo Nakatani
 
プログラマ人生論
プログラマ人生論プログラマ人生論
プログラマ人生論
ymmt
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
mitim
 
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
Yahoo!デベロッパーネットワーク
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
Hajime Yanagawa
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
Shigenori Sagawa
 
ロジカル資料作成講座【作成編】株式会社okunote
ロジカル資料作成講座【作成編】株式会社okunoteロジカル資料作成講座【作成編】株式会社okunote
ロジカル資料作成講座【作成編】株式会社okunote
TakamasaTayano
 
チーム開発をうまく行うためのコーディング規約論
チーム開発をうまく行うためのコーディング規約論チーム開発をうまく行うためのコーディング規約論
チーム開発をうまく行うためのコーディング規約論Kentaro Matsui
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
増田 亨
 
プログラミングNet framework3のお題
プログラミングNet framework3のお題プログラミングNet framework3のお題
プログラミングNet framework3のお題
Kazushi Kamegawa
 
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについてNobukazu Hanada
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで
増田 亨
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
Hiro Yoshioka
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
信之 岩永
 
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング
keki3
 
Programming camp code reading
Programming camp code readingProgramming camp code reading
Programming camp code reading
Hiro Yoshioka
 
第1回python勉強会
第1回python勉強会第1回python勉強会
第1回python勉強会
Yoshio Shimomura
 
フロント作業の効率化
フロント作業の効率化フロント作業の効率化
フロント作業の効率化
Yuto Yoshinari
 

Similar to リーダブルコード (20)

リーダブルコード 1.0'
リーダブルコード 1.0'リーダブルコード 1.0'
リーダブルコード 1.0'
 
Web本文抽出 using crf
Web本文抽出 using crfWeb本文抽出 using crf
Web本文抽出 using crf
 
プログラマ人生論
プログラマ人生論プログラマ人生論
プログラマ人生論
 
Start!! Ruby
Start!! RubyStart!! Ruby
Start!! Ruby
 
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
PHP版レガシーコード改善に役立つ新パターン #wewlc_jp
 
モジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェースモジュールの凝集度・結合度・インタフェース
モジュールの凝集度・結合度・インタフェース
 
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
 
ロジカル資料作成講座【作成編】株式会社okunote
ロジカル資料作成講座【作成編】株式会社okunoteロジカル資料作成講座【作成編】株式会社okunote
ロジカル資料作成講座【作成編】株式会社okunote
 
チーム開発をうまく行うためのコーディング規約論
チーム開発をうまく行うためのコーディング規約論チーム開発をうまく行うためのコーディング規約論
チーム開発をうまく行うためのコーディング規約論
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
プログラミングNet framework3のお題
プログラミングNet framework3のお題プログラミングNet framework3のお題
プログラミングNet framework3のお題
 
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて
現在のWebフロントエンドの現状と愚痴と、それに対するHaxeフロントエンドライブラリMageについて
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで
 
Programming camp 2008, Codereading
Programming camp 2008, CodereadingProgramming camp 2008, Codereading
Programming camp 2008, Codereading
 
Tdd
TddTdd
Tdd
 
C# design note sep 2014
C# design note sep 2014C# design note sep 2014
C# design note sep 2014
 
2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング2018年度 若手技術者向け講座 リファクタリング
2018年度 若手技術者向け講座 リファクタリング
 
Programming camp code reading
Programming camp code readingProgramming camp code reading
Programming camp code reading
 
第1回python勉強会
第1回python勉強会第1回python勉強会
第1回python勉強会
 
フロント作業の効率化
フロント作業の効率化フロント作業の効率化
フロント作業の効率化
 

リーダブルコード

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n