Skip to content

Conversation

chaemon
Copy link
Contributor

@chaemon chaemon commented May 3, 2021

前に出したプルリクには他のが混ざっていたので切り分けました。ついでに以下を行いました。

  • swiftも対応
    配列の入力がappendしていく方式になっていましたがこれだとメモリ確保が倍々に行われてしまって非効率と思われるので、最初にサイズを指定する形式に変更しました
  • cppのscanfを呼び出す際にカンマの後に空白を挿入(他の部分と統一)

@codecov-commenter
Copy link

codecov-commenter commented May 3, 2021

Codecov Report

Merging #228 (0a5f72c) into stable (8af0cbd) will decrease coverage by 0.43%.
The diff coverage is 96.08%.

Impacted file tree graph

@@            Coverage Diff             @@
##           stable     #228      +/-   ##
==========================================
- Coverage   89.64%   89.20%   -0.44%     
==========================================
  Files          55       56       +1     
  Lines        2877     2363     -514     
==========================================
- Hits         2579     2108     -471     
+ Misses        298      255      -43     
Impacted Files Coverage Δ
...odegen/code_generators/universal_code_generator.py 95.79% <95.79%> (ø)
atcodertools/codegen/code_generators/cpp.py 100.00% <100.00%> (+3.70%) ⬆️
atcodertools/codegen/code_generators/cs.py 100.00% <100.00%> (+4.67%) ⬆️
atcodertools/codegen/code_generators/d.py 100.00% <100.00%> (+3.73%) ⬆️
atcodertools/codegen/code_generators/java.py 100.00% <100.00%> (+8.16%) ⬆️
atcodertools/codegen/code_generators/nim.py 100.00% <100.00%> (+5.66%) ⬆️
atcodertools/codegen/code_generators/python.py 100.00% <100.00%> (+17.18%) ⬆️
atcodertools/codegen/code_generators/rust.py 100.00% <100.00%> (+4.93%) ⬆️
atcodertools/codegen/code_generators/swift.py 100.00% <100.00%> (+3.33%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8af0cbd...0a5f72c. Read the comment docs.

@chaemon
Copy link
Contributor Author

chaemon commented May 3, 2021

        if type == Type.float:
            return self.info["input_func"]["float"]
        elif type == Type.int:
            return self.info["input_func"]["int"]
        elif type == Type.str:
            return self.info["input_func"]["string"]

といった感じのif分岐は全部enumで置き換えたほうがいいですかね?つまり、return self.info["input_func"][type.value]とシンプルに書くことができると思います。

@kyuridenamida kyuridenamida changed the title ユニバーサルコードジェネレータの2.2.0に対応(修正版) Universal Code Generator for supporting new languages easily May 3, 2021
@kyuridenamida kyuridenamida changed the title Universal Code Generator for supporting new languages easily Universal Code Generator to support new languages easily May 3, 2021
self._format = format_
self._config = config
self.info = toml.load(
Path(__file__).parent / "universal_generator" / "{lang}.toml".format(lang=lang))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このファイル名そのものを外から挿入できるようにしたほうが使い勝手が良いので、お願いできますか?

func get_builtin_code_generator_info_toml_path(lang):
    return Path(__file__).parent / "universal_generator" / "{lang}.toml".format(lang=lang))

とかを別途このファイルで定義しておけば、呼び出し側は、

code_parameters = UniversalCodeGenerator(
        args.format, args.config, get_builtin_code_generator_info_toml_path("java")).generate_parameters()

とかでよくなります。

これのメリットとして、ディレクトリ構造に非依存になるので、カスタムコードジェネレーターで、わざわざコードをuniversal_generator以下に配置しなくてもUnivesalCodeGeneratorが使えるようになります。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらは、universal_code_generatorにはpathを渡すという要望で.atcodertools.tomlからcustom_code_generator.pyみたいな感じでtomlを呼べるようにするところまではまだしなくていいんですよね?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

しなくていいです。

ワークアラウンドとして最悪ユーザーのcustom_code_generator.pyにパスをハードコードすればいいので

README.md Outdated


### ユニバーサルコードジェネレーター
ユニバーサルコードジェネレータはループ・配列アクセス方法等のいくつかの言語仕様を記述するだけでカスタムコードジェネレータよりも簡単にコード生成することを意図して作成したジェネレータです。設定ファイル`(言語名).toml`を`atcodertools/codegen/code_generators/universal_generator`に配置してください。設定ファイルの書き方は以下です。
Copy link
Owner

@kyuridenamida kyuridenamida May 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

先程の部分を訂正するとこの部分がいらなくなるはず

設定ファイル(言語名).tomlatcodertools/codegen/code_generators/universal_generatorに配置してください。設定ファイルの書き方は以下です。

#include <iostream>
#include <vector>
#include <cassert>
#include<bits/stdc++.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Xcode(macOS)とVisual Studio(Windows)にはbits/stdc++が存在しない(テストが通らない)ので、普通のヘッダのほうがうれしいです。

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>

代替案としてこのへんが現実的なヘッダかなと思いますがどう思いますか

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cassertがなかったので追加しておきました!

Enumを使う方式に変更してコードをシンプルに
@kyuridenamida
Copy link
Owner

        if type == Type.float:
            return self.info["input_func"]["float"]
        elif type == Type.int:
            return self.info["input_func"]["int"]
        elif type == Type.str:
            return self.info["input_func"]["string"]

といった感じのif分岐は全部enumで置き換えたほうがいいですかね?つまり、return self.info["input_func"][type.value]とシンプルに書くことができると思います。

可読性の観点からこれは十分シンプルなのでこれでいいと思います。

メンテ性の観点からはあんまり今後頻繁に型が増えるとは思えないのでこのままで十分です

@chaemon
Copy link
Contributor Author

chaemon commented May 4, 2021

C++のbits/stdc++.hを使わないようにしました。また、formatのキーワードの指定を一々指定するのではなくて、専用の関数から展開するようにしました。これによって、割とコードがシンプルになったと思います。

上記のコメントを読む前にif分岐の部分もenumから配列アクセスするようにしてしまいましたが、不評でしたら戻します。

@kyuridenamida
Copy link
Owner

kyuridenamida commented May 4, 2021

ありがとうございます。
正直のところ不必要にコードを間接的にしたくないという気持ちはあって、以前のほうが好きなんですよね。

あとinput_funcに関してなんですが、こっちもより間接的になっている気がします。この記法のユーザー的なメリットを教えて頂けたら納得できるかもしれません。教えて頂けますか?

README.md Outdated


### ユニバーサルコードジェネレーター
ユニバーサルコードジェネレータはループ・配列アクセス方法等のいくつかの言語仕様を記述するだけでカスタムコードジェネレータよりも簡単にコード生成することを意図して作成したジェネレータです。設定ファイルの書き方は以下です。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivialな表記揺れですが

  • ジェネレータ -> ジェネレーター (またはジェネレータに統一する)
  • python -> Python
  • perl -> Perl
  • php -> PHP

@chaemon
Copy link
Contributor Author

chaemon commented May 4, 2021

では、if分岐のところはもとに戻します。キーワードをまとめるのも便利だと思ったんですが、間接化してることになっちゃいますかね?

input_funcを使うメリットはpythonで確保と入力をfor文を使わないでA = [int(next(tokens)) for _ in range({length})]といった形に書けるようなものもサポートしていて、これをやるときにint, float, strごとに違う関数を指定しなければならないところが、input_funcを定義しておくと下記のように共通して書けるということですかね。あと、もう一つは入力で使うint(next(tokens))というのの繰り返しを避けたり、変更があったときにinput_funcを変えるだけでできるようになるので少し便利ということもありますね。もともと、tomlではなくpythonで書いていた頃には文字列の継ぎ接ぎで対応していて、universal_code_generatorは感知しない状態だったんですが、tomlにするとuniversal_code_generatorの変数として扱わなければならなくなりました。

# 確保と入力
[allocate_and_input]
seq = "{name} = [{input_func} for _ in range({length})]"
2d_seq = "{name} = [[{input_func} for _ in range({length_j})] for _ in range({length_i})]"

# 宣言と確保と入力
[declare_and_allocate_and_input]
seq = "{name} = [{input_func} for _ in range({length})]  # type: \"List[{type}]\""
2d_seq = "{name} = [[{input_func} for _ in range({length_j})] for _ in range({length_i})]  # type: \"List[List[{type}]]\""

@kyuridenamida
Copy link
Owner

@chaemon なるほどなるほど、よくわかりました。ではinput_funcに関してはそれでいきましょう。

@kyuridenamida
Copy link
Owner

では、if分岐のところはもとに戻します。

これごめんなさい。戻してくれたところを改めて見て、やっぱり戻さないほうがキレイに見えました。これは完全に僕の勘違い&間違った指示です。スミマセン...

@kyuridenamida
Copy link
Owner

LGTM, @chaemon マージしてよかったら教えてください

@chaemon
Copy link
Contributor Author

chaemon commented May 6, 2021

では、if分岐ではなくenumのvalueを使う方にしました!

これでマージしていただいて構いませんよ〜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants