「string」を含む日記 RSS

はてなキーワード: stringとは

2022-08-13

プログラマー生産性は人により100倍くらい差があるというけれど

 割りとマジだよねと思う出来事をふと思い出したので書いてみる。

 といっても後輩が俺の思ってもいないところでつまづいて、それに俺がカルチャーショックを受けたというだけの話。

 問題の話なんだけど、とある有名サービスJSON APIを叩いて呼び出し結果を手元のオブジェクトマッピングするというただそれだけのコードを書くというもの

 普通に考えて一日もしないで出来ると思うような代物だけど、三日以上悩んで彼はそれでも出来なかった。

 何があったかというと、そのJSON API

{ ..., "count": 10000000000000000000000000000000000000, ...}

 という感じで多倍長整数リテラルとして書かれているのを前提として受け取る仕様だった。

 JavaScriptの通常の整数と違って、JSON整数リテラル仕様上大きさの制限記載がないので、上のようなのも合法

 で、彼の使ってたプログラミング言語オブジェクト から JSONの変換ライブラリが、多倍長整数文字列("")としてシリアライズするような仕様なことがわかって、彼は行き詰まった。

 そこで何をやり始めたかというと、JSON整数がそのまま1000000000000000みたいにシリアライズされるライブラリ探し始めたんだけど、それは見つからないまま。

 というわけで「増田さん、詰まってるんですけど……」と言われて助け舟出すことになったはいものの、彼のコード見るとJSON抽象構文木クラスがそのまま使えるようだった。

 なので、

String serialiaze(Ast.JsValue value) {
    return switch(value) {
        case Ast.JsNull nullValue-> "null";
        case Ast.JsInt bigIntValue -> bigIntValue.toString();
        case Ast.JsArray arrayValue -> arrayValue.stream().map(v -> serialize(v)).collect(Collectors.joining(", ", "[", "]"));
        // 他のJSONの木についても同様に処理
        default -> throw new RuntimeException("cannot reach")
    };
}

 1時間しない内にこんな感じのコード言語Javaじゃなかったけど、だいたいこういう感じ)を書いて無事問題解決。細かいタイポとかあるかもだけど、日記では確認してないのでそれはおいといて)。

 結局、JSONの形が期待と違って、しか既存APIじゃいいのがなかったのに延々API探すことしか出来なかったのが問題解決できなかった原因だけど、このくらいのは割りとちょこちょこある。

 きっと、それから一週間放置しても問題解決できなかっただろうし、どうも同じチームの同僚も問題解決できなかったようだった。

 最近APIは叩けるけど、そこでトラブルとどうにもならなくエンジニアにちょくちょく遭遇するんだけど、やっぱりもうちょっと基礎出来てないと駄目だなと思った出来事だった。

 具体的には、再帰が相性が良いプログラムを書けるとか、APIに頼れないときはさっさと自作する頭の切り替えとかもろもろ。

 それと、情報大学出てるのなら、せめて木構造に対してはサクっと再帰関数くらい書けてほしかったなと思う出来事だった。

2022-08-07

独学で未経験からWebエンジニアになり1年で月収が前職比50万アップした

第一に、増田にいる人間はろくでもない。

自分は上段に座しているつもりで偉そうな上から目線の半分的外れ説教だの、はたまたその体すら為していない放言だのを安全位置から投げつけたいだけのカスしかここにはいない。

このタイトルを見て、意識高い系文系イキリ勘違い野郎に何事か物申してやろうと考えたそこの画面の前でニチャニチャしているパソカタオタク(パソコンタカタキモオタク: 声は小さいがタイプ音はでかい)のことである

あるいは増田のことかもしれない。増田は日頃増田に生息している訳ではないが。

お分かりの通り、これは釣り記事であるそもそも意識高い系文系イキリ勘違い野郎増田記事を書くわけがない。が、一応タイトルに嘘はない。

ので意識高い系文系イキリ勘違い野郎を志す意識高い系文系イキリ勘違い野郎予備軍のことを思って以下を書く。

ちなみに、この記事タイトル増田が一番嫌いなタイプのそれである自分で設定したのに今、額に青筋が浮かんでいる。

1. やったこ

本項ではWebエンジニアになるにあたって増田がやったことを列挙する。

1. プログラミングを独学する

2. スクールに入る

3. アルバイトをする

なるほど、至極単純である。では順に詳細を見ていく。

プログラミングを独学する

ここに関しては特に言うこともない。

ネット記事を見ながらCだのDだのC++だのを実際に吐くまで勉強した。

その経験を踏まえて意識高い系文系イキリ勘違い野郎予備軍にアドバイスするならば、独学の上で最も身になるのは"C++を用いて簡単スクリプト言語インタプリタ実装する"ことである

インタプリタ実装という作業プログラミング言語のものに対する解像度を飛躍的に向上させる。

不可思議お約束の塊であった文法意味論因数分解されるように頭の中で整理され、ブラックボックスであった標準ライブラリの内部について想像が及ぶようになる。

道具たるプログラミング言語に対する理解は、当然その使途であるプログラミングのものを助ける。

ところでパソカタオタク諸兄姉は「なぜ今C++などという時代遅れのクソ言語を」と思ったかもしれない。

かにC++はもはや洗練から程遠い聳えるバベルの塔であるしかし、こと言語実装習得においてはこれほど適している言語もない。

C++GC付きの他言語比較して抽象度が低く、全てを自身管理しなければならないが故に"便利な魔法"にあまり頼れないのである

また、C++で導入された様々な思想イディオムは他の言語にも大きく引き継がれている。

例えば洗練という意味C++の対極に位置するRustという言語は、もはや本質的にはC++のものである

Rustの代名詞である所有権ライフタイムはそれぞれC++反省からまれ言語要素であるし、move semanticsはC++11におけるmove semanticsと同様のものである

GC付き言語利用者にとってしばしば混乱の原因となりそうな`str`と`String`も`std::string_view`と`std::string`を知ってさえいれば迷いの発生する余地はない。

他のより抽象化された言語についても、C++との対応を考えることでその言語や標準ライブラリのもの実装について十分に理解を深めることができる。

なぜならば過去の多くのスクリプト言語コンパイラC/C++によって実装されていることが多いかである

そんなわけで、増田は"C++を用いて簡単スクリプト言語インタプリタ実装する"ことを勧めている。

スクールに入る

増田が入ったスクールは、多くのそれが半年あたり70万程度の授業料を取る(らしい)のに対して同期間で28万程度と非常にリーズナブルであった。

ただし、卒業までは最低4年と長期間を要するし、増田卒業後も2年さらに通った。

そう、大学(院)である

おいそこの意識高い系文系イキリ勘違い野郎予備軍、カスみたいなプログラミングスクールに入るな。

教育機関情報工学を学べ。

ところでそろそろ察せられるだろうが、増田の前職とは学生を指している。

アルバイトをする

大学情報工学を教えてくれるが、別段それを学んだからといってプログラミングができるようになるわけではない。あくまでそれらは相補的なものである

一方で、独学では分野に偏りが出がちだし、なにより独学にも金が要るので学生身分にとってプログラマバイトは良い選択肢である

アルバイトITエンジニア経験に含めなくて良いのか怪しいが、増田バイト業務内容はWebエンジニアと言いきってよいか悩ましい類だったので嘘は吐いていない。

ちなみに増田増田に書き込むような人間であるからして社会性というものが欠落している。

バイト大学院1回生ときにバックレてやめた。

2. 現職

大学院を卒業したのでいやいや就職した。

ちなみに月収は大学院2回生収入0時代から差分で算出して+50万なのでつまるところそれが現在の月収である

増田にとって低くはないが、決してITエンジニアとして高い方であると主張することはできない程度の額である

釣りのためにタイトルに含めた以上最低限の説明のはしたが、増田は金の話をすると脳の血管がブチギレそうになるのでこれ以上その話はしない。

3. 結びに意識高い系文系イキリ勘違い野郎予備軍へ

ここまで読んだならわかると思うが、増田意識高い系文系イキリ勘違い野郎(タイプ音がでかい)ではなく、パソカタオタク(パソコンタカタキモオタク: 声は小さいがタイプ音はでかい)である

そして、意識高い系文系イキリ勘違い野郎予備軍に言うべきことがあるとすれば、そもそもこの記事をここまで読んでいる時点でITエンジニアには向いていないので止めといたほうがよい。

また、ひょっとすると思い違いをしているかもしれないが、ITエンジニアというのは大抵 (増田社会経験がほぼないので一般論を言うことは出来ないが) 意識高い系イキリキラキラ野郎サイドではなくパソカタオタクばかりである

というよりTwitterにいる意識高い系イキリキラキラ野郎は多くの場合意識高い系文系イキリ勘違い野郎予備軍を養分にする人でなしである。騙されてはならない。

また、一つ理解しなければならないのは意識高い系文系イキリ勘違い野郎予備軍諸兄姉が張り合わなければならないのは、プログラミングスクールの同期でも、「#駆け出しエンジニアと繋がりたい」している有象無象でもなく、幼少から寝食や友人や遊びを自ら捨ててパソカタにのめり込んでいた、そして現在進行系でのめり込んでいる歴10年や20年をゆうに超えるSSRソカタオタクであるということである (そしてそれはNRソカタ増田も同様である)。

彼らが「スクール半年学びました」で並び立てるような人間でないのは単純な算数でわかるほど明らかである。悪いこと言わんからキラキラWebエンジニアを目指すのはやめとけ。

あるいはそれでも目指すのであれば自分が何を捧げられるのかを考えた方がいい。

2022-08-01

anond:20220731183342

自動安価をつけて返信するプログラムでもこんなに長く複雑になる(一部抜粋) 

/**************************************

以下のCSV_DIR, FILE_PATHS, SETTINGSを書き換えてね。 <h3>o- *************************************/</h3>

//CSVファイルが置かれてるディレクトリパス投稿前にエラー出たら大体ここの設定ミス。 例:"C:\\Users\\sakuraimasahiro\\Documents\\iMacros\\Macros\\rentou\\";

const CSV_DIR =

'C:\\Users\\USER\\Desktop\\iMacros\\Macros\\rentou\\';

//ファイルパスCSV絶対パスで、拡張子必要。iimは相対パスでよく、拡張子不要

const FILE_PATHS = {

//投稿文が書かれたCSVファイル

textCsv: CSV_DIR + 'textNoAnker.csv',

//レス投稿文が書かれたCSV。通常とレス用で分けないなら同じファイルを使えばいい。

replyTextCsv: CSV_DIR + 'textReply.csv',

};

const SETTINGS = {

//投稿後の基本待ち時間

baseWaitTime: 5,

//baseWaitTime+0~waitTimeRange(ランダム)だけ待つ

waitTimeRange: 5,

//連投しすぎだと忠告された場合に処理を一時停止させる時間(秒)

waitTimeForAvoidingPunishment: 60 * 30,

//メール

mail: 'sage',

//名前設定

nameSettings: {

//名前名無しなら''。

name: '',

//以下、偽装ワッチョイ設定。浪人ワッチョイを非表示にしてるときだけtrueにしてね。

//妙なニックネーム(ワッチョイ、アウアウウーなど)をランダムで決めて付加するかどうか。true=付加する。false=付加しない。

nickname: false,

//妙なニックネームの後に付く8桁の文字列ランダムで決めて付加するかどうか。

korokoro: false,

//IPランダムで決めて付加するかどうか。

ip: false,

//地域ランダムで決めて付加するかどうか。

area: false,

},

postSettings: {

//アンカー無し投稿をするならtrue。しないならfalse。noAnkerPostかreplyPostのどちらかはtrueにすること(両方trueでもOK)。

noAnkerPost: false,

//アンカー付き投稿(返信)をするならtrue。しないならfalse。もしnoAnkerPostとreplyPostの両方がtrue場合投稿は返信が優先され、返信対象が見つからなくなったらアンカー無し投稿をする。

replyPost: true,

//最初に取得するアンカー無し投稿CSVファイルの行番号。もし返信用と同じCSVファイルを使うなら-1と入力

noAnkerPostTextCsvStartRow: 1,

//最初に取得する返信用投稿CSVファイルの行番号。もしアンカー無しと同じCSVファイルを使うなら-1と入力

replyPostTextCsvStartRow: 1,

//テキストCSV/返信用テキストCSVの取得行が最終行に達したら最初の行まで戻るかどうか。true=戻る。false=マクロ終了。

textCsvLoop: true,

//返信する場合、これより小さなレス番には返信しない。返信を投稿すると、この数値は前回の返信先のレス番に更新される。

minAnker: 895,

//返信する場合名前に以下の文字列を含む投稿アンカーをつけて返信する(ワッチョイやIPなど名前フィールドにあるものならなんでも可)。配列複数指定可能指定無しなら空配列([])。filterNamesとfilterNamesNotIncluded共に無指定ならレス番1から順に返信していく(minAnkerが設定されてればそこから順に)。以下のfilter系は全て併用可能

filterNames: [],

//↑とは逆に、名前に以下の文字列を含まない投稿アンカーをつけて返信する。↑と併用も可能

filterNamesNotIncluded: [],

//返信する場合、本文に以下の文字列を含む投稿アンカーをつけて返信する。

filterText: ['自演かな', '自演わらわら', 'スクリプト使うの', '安価ガバ', '>>660', '自演擁護', '最後' ,'あいうえお', 'かきくけこ', 'さしすせそ', 'なにぬねの', 'はひふへほ', 'まみむめも', 'やいゆえよ', 'やゆよ', 'らりるれろ', 'わいうえを', 'わをん', 'わいうえをん'],

},

//自分IPアドレス確認VPNとかでIPを変更してマクロを動かしてるとき、突然VPN作動しなくなってIPが元に戻ったときマクロを止めるためのもの

ipSettings: {

//自分現在IPアドレス確認をする。

checkIp: true,

//以下の文字列自分現在IPアドレスに含まれている場合マクロを一時停止する。基本的自分の本当のIPアドレス入力

avoidTheIp: '133.206.99.224',

},

//浪人設定。最後動作確認したのは5年くらい前で、今も同じように動作するかは、浪人を持ってないか確認できずわからない。

roninSettings: {

//浪人ログインしてるかどうかをチェックするかどうか。trueらするfalseならしない。trueにしていてもし浪人ログインしていないことを確認したらログインしにいく。

checkLogin: false,

//浪人ログインメールアドレス

mailAdress: 'abc@def.com',

//浪人ログインパスワード

password: '1234',

},

//false: run()実行させず(デバッグ用)

run: true,

//true: 投稿処理だけしない デバッグ

skipPost: false,

};

/**************************************

設定箇所終わり。

書き込めない時の早見表 - 5ちゃんねるwiki

https://info.5ch.net/index.php/%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%82%81%E3%81%AA%E3%81%84%E6%99%82%E3%81%AE%E6%97%A9%E8%A6%8B%E8%A1%A8 <h3>o- *************************************/</h3>

/**************************************

メモ

クラスフィールド宣言できない。

・NULL演算子(??)は使えない。論理積(&&)は使える。

オブジェクトの分割代入はできない。

・importはできない。 <h3>o- *************************************/</h3>

/**************************************

関数 <h3>o- *************************************/</h3>

/**

* ここから始まる。

*/

function run() {

//設定ミスがないか調べる。

checkSettings();

var _TextCsvCursors = new TextCsvCursors(

new TextCsvCursor(

SETTINGS.postSettings.noAnkerPostTextCsvStartRow > 0

? SETTINGS.postSettings.noAnkerPostTextCsvStartRow - 1

: SETTINGS.postSettings.noAnkerPostTextCsvStartRow,

FILE_PATHS.textCsv,

SETTINGS.postSettings.textCsvLoop,

),

new TextCsvCursor(

SETTINGS.postSettings.replyPostTextCsvStartRow > 0

? SETTINGS.postSettings.replyPostTextCsvStartRow - 1

: SETTINGS.postSettings.replyPostTextCsvStartRow,

FILE_PATHS.replyTextCsv,

SETTINGS.postSettings.textCsvLoop,

),

);

var _LoopStatuses = new LoopStatuses(0, SETTINGS.postSettings.minAnker);

const _MyPosterName = new MyPosterName({

name: SETTINGS.nameSettings.name,

});

//スレURL指定

const _ThreadUrl = openPromptThreadUrl();

//ループ

while (true) {

//IP確認する設定なら、それをする。

SETTINGS.ipSettings.checkIp && checkCurrentIpNotTheIp();

//スレを開く

openUrl(_ThreadUrl.fullUrlHttps());

//浪人ログインする設定なら、浪人ログインしているかどうかを確認し、していなければログインしにいく。

if (SETTINGS.roninSettings.checkLogin) {

if (!checkRoninLogin()) {

loginRonin();

continue;

}

}

//投稿に使うテキスト取得。

const p = (function () {

if (SETTINGS.postSettings.replyPost) {

//返信あり設定の場合。返信対象が無いか調べる。

const targetAnkerNumber = createPostDOMList()

.filterPostnumberHigher(_LoopStatuses.currentMinAnker())

.filterByPostername(SETTINGS.postSettings.filterNames)

.filterByPosternameNotIncluded(

SETTINGS.postSettings.filterNamesNotIncluded,

)

.filterByText(SETTINGS.postSettings.filterText)

.lowestPostNumber();

if (targetAnkerNumber !== null) {

//返信対象があったのでアンカー付き投稿文を作る。

const r = _TextCsvCursors.takeNextRowTextAsReply(targetAnkerNumber);

messageDisplay(`返信対象有り。アンカー先: ${targetAnkerNumber}`);

return {

...r,

updatedLoopStatuses:

_LoopStatuses.updateMinAnker(targetAnkerNumber),

};

}

}

if (SETTINGS.postSettings.noAnkerPost) {

//返信対象無し、或いは返信しない設定の場合アンカー無し投稿文を作る。

const r = _TextCsvCursors.takeNextRowTextAsNoAnker();

messageDisplay('返信対象無し。アンカー無し投稿。');

return {

...r,

updatedLoopStatuses: _LoopStatuses,

};

}

return null;

})();

if (p) {

//投稿

postThenCheckError(

_ThreadUrl.serverName(),

_MyPosterName.randomize({

nickname: SETTINGS.nameSettings.nickname,

korokoro: SETTINGS.nameSettings.korokoro,

ip: SETTINGS.nameSettings.ip,

area: SETTINGS.nameSettings.area,

}),

SETTINGS.mail,

p.text,

);

//_TextCsvCursorsと_LoopStatusesを更新

_TextCsvCursors = p.updatedTextCsvCursors;

_LoopStatuses = p.updatedLoopStatuses.incrementPostCount();

messageDisplay([

`投稿回数: ${_LoopStatuses.currentPostCount()}`,

`minAnker: ${_LoopStatuses.currentMinAnker()}`,

`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,

`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,

]);

} else {

messageDisplay([

`返信対象が現われるのを待機中...。`,

`投稿回数: ${_LoopStatuses.currentPostCount()}`,

`minAnker: ${_LoopStatuses.currentMinAnker()}`,

`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,

`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,

]);

}

//短時間で連投しまくると規制されるので一定時間待機。

wait(SETTINGS.baseWaitTime + randomRange(0, SETTINGS.waitTimeRange));

}

}

/**

* 投稿処理と投稿結果を見てリトライしたりマクロ終了したり。

* @param {string} serverName サーバー

* @param {MyPosterName} _MyPosterName

* @param {string} postMail メール

* @param {MyText} _MyText

* @param {number} retryTimes

* @returns {void}}

*/

function postThenCheckError(

serverName,

_MyPosterName,

postMail,

_MyText,

retryTimes = 0,

) {

const r =

retryTimes === 0

? new ValuesOfPost(serverName, _MyPosterName, postMail, _MyText).post(

postTo5chTread,

postConfirm,

)

: new ValuesOfPost(

serverName,

_MyPosterName,

postMail,

_MyText,

).postSubstring(retryTimes, postTo5chTread, postConfirm);

if (r) {

back();

return;

}

//エラーページに飛ばされた。エラー情報取得。

wait(7);

const error = createPostErrorMessage().analyze();

messageDisplay(error.message);

if (error.order === 'KILL') {

kill();

} else if (error.order === 'SKIP') {

return;

} else if (error.order === 'TRUNCATE') {

back();

return postThenCheckError(

serverName,

_MyPosterName,

postMail,

_MyText,

retryTimes + 1,

);

} else if (error.order === 'WAIT') {

wait(SETTINGS.waitTimeForAvoidingPunishment);

return postThenCheckError(

serverName,

_MyPosterName,

postMail,

_MyText,

retryTimes,

);

} else if (error.order === 'LOGIN') {

//動作未確認

return postThenCheckError(

serverName,

_MyPosterName,

postMail,

_MyText,

retryTimes,

);

}

return;

}

/**

* 現在IPアドレスに、SETTINGS.ipSettings.avoidTheIpの値が含まれていないことを確認する。含まれていたらマクロを一時停止。

* @returns

*/

function checkCurrentIpNotTheIp() {

//IP確認ページへ飛ぶ

openUrl('https://www.cman.jp/network/support/go_access.cgi');

const _IpAdress = createIpAdressFromCMan();

if (_IpAdress.includes(SETTINGS.ipSettings.avoidTheIp)) {

pause('現在IP指定した値が含まれていることを確認。');

//ポーズ解除したならもう一度確認しに。

checkCurrentIpNotTheIp();

}

return;

}

/**

* 設定に致命的な問題が無いか検査

* @returns

*/

function checkSettings() {

if (

SETTINGS.postSettings.noAnkerPost === false &&

SETTINGS.postSettings.replyPost === false

) {

return kill('設定エラー。noAnkerPostとreplyPost両方ともfalseになってる。');

}

if (

SETTINGS.postSettings.noAnkerPostTextCsvStartRow < 0 &&

SETTINGS.postSettings.replyPostTextCsvStartRow < 0

) {

return kill(

'設定エラー。noAnkerPostTextCsvStartRowとreplyPostTextCsvStartRow両方とも-1になってる。',

);

}

if (

SETTINGS.postSettings.noAnkerPostTextCsvStartRow === 0 ||

SETTINGS.postSettings.replyPostTextCsvStartRow === 0

) {

return kill(

'設定エラー。noAnkerPostTextCsvStartRow/replyPostTextCsvStartRowの初期値は-1或いは1以上で。',

);

}

}

/**

* 入力フォームを表示して入力されたスレURLを受け取る。

* @returns {ThreadUrl}

*/

function openPromptThreadUrl() {

const url = prompt('スレURL入力');

return new ThreadUrl(url);

}

/**

* 開いてるスレレス全て読み取ってPostListインスタンスを作って返す。

* 重すぎるので使うのやめ。どうやらインスタンスの大量生成が原因な模様。

* createPostDOMListを使う。

* @returns {PostList}

*/

function createPostList() {

const posts = window.document.getElementsByClassName('post');

return new PostList(Array.from(posts).map((e) => new Post(e)));

}

/**

* 開いてるスレレス全て取得してPostDOMListに格納して返す。

* @returns

*/

function createPostDOMList() {

const posts = window.document.getElementsByClassName('post');

var arrPostDOMList = [];

for (let index = 0; index < posts.length; index++) {

//HTMLCollectionからElementを1つずつ抽出して配列に。

arrPostDOMList.push(posts.item(index));

}

return new PostDOMList(arrPostDOMList);

}

/**

* 開いてる投稿結果画面に表示されてるエラーを読み取ってPostErrorMessageインスタンスを作って返す。

* @returns {PostErrorMessage}

*/

function createPostErrorMessage() {

return new PostErrorMessage(

window.document

.g Permalink | 記事への反応(0) | 15:40

2022-03-23

Powershell

Convert-Stringってコマンドコマンドレット)がある。

使い方は、例を見てもらったほうが速いので、以下。

入力

("Hatsune Miku","Kagamine Rin","Kagamine Len") | Convert-String -Example "Kasane Teto=K. Teto"

出力

H. Miku
K. Rin
K. Len

やれることはわかった。

ただ、大文字/小文字判断や順番が入れ替わると対応できず、柔軟性はそれほどない。

これ、どういうときに使うと便利なやつ?

2022-02-27

anond:20220227173920

static int parseInt(String s)

とか。よくあるよ。

2022-02-22

anond:20220222132427

google apps script string bracket error」とかでググればええんちゃうの。知らんけど。

2021-12-06

きれそう

String path; // なかみはURI文字列

String uri; // なかみはパス文字列(/から始まるかどうかは不明)

ほんとこういうの書くやつ死んでくれ。殺意しかわかない

この実装のまま至るところで利用してるし、書いてる途中で自分脳みそがばぐってるこにきがつかねーのか?ああ?ころすぞボケ

2021-08-20

個人開発で終盤なんだが、DBとの兼ね合いで書き直せる変数が出てきたんだが修正すべき?

装備のセットにあたま、防具、こてみたいな種類があってそれをList<List<bool>>で管理していた

この変数とは別にアイテム一覧みたいな変数もあって(String[]{初級、冒険者、炎。。。}みたいな)そこと突き合わせて使っていた

 

これはDB管理するときに一つのこの変数自体を一つのKeyValueで管理していたからなんだけど

最近そういうもの管理するための方法が用意されてて、〇〇セットKeyValueで{頭 = true、防具。。。}みたいなセットごとに保存するAPIがあることを知った

からローカルのほうでもList<Bool>じゃなくてClassとか構造体に変えることも可能なんだけど、これってわかりやすさのために変えるべき?

 

開発終盤でショップ機能とか装備入れ替えで使ってるから結構修正いるんだが、DBから引っ張てくるときにList<bool>に変えることで対応可能

可読性は絶対的Classとか作った方がいいんだが、直すべき?

2021-08-16

【未経験から1ヶ月で】現役エンジニアが教える最良のプログラミング勉強法

プログラマーに憧れる皆さん!こんばんは。

自分文系から」「未経験から」と諦めていませんか?大丈夫です!プログラミングセンス不要です。正しい手順で学べば、文系や未経験でも、誰でも一流のプログラマとして活躍することができます

今日は、未経験から最短でWeb企業就職するための勉強法をご紹介します!

オススメ方法

もっとオススメ方法は、顕正会セミナーに参加することです。

顕正会は、日本で最大のエンジニアコミュニティであり、非常に良質なテキストを用いて、プログラミング初心者向けのセミナーをしていることで有名です。顕正会に入ることで、未経験からでも一流エンジニアノウハウを学ぶことができます

また、意外と知られていませんが、日本エンジニアの8割は顕正会出身です。実はあのひろゆきビル・ゲイツ顕正会出身です。ですので、顕正会ネットワークを介して就職先を斡旋してくれたりしますし、自分顕正会員だと、面接時にも非常に有利になります

顕正会セミナーは、インターネットからも応募することができますし、秋葉原などで声をかけられることもありますので、誰でも簡単に参加できます。会員もフレンドリーな方ばかりですので、是非、お気軽に応募してみて下さい!無料体験もできますよ。

準備

プログラミング勉強を始める前に、まず、必要ものを準備しましょう。必ず必要ものと、できればあると良いものは以下の通りです。

必ず必要もの

まず、プログラムを書いて実行するためにパソコン必須です。

可能な限りスペックの高いものを買いましょう。2021年現在であれば、CPUは18コア、36スレッドRAMは128GBくらいはあると良いでしょう。ストレージSSDであれば1TBもあれば十分です。

OSは、Windowsで開発するならWindowsが、Macで開発するならMac必要です。よく分からなければMacを買っておく方が良いでしょう。基本的MacにできてWindowsにできないことはありません。

インターネットは、この記事を見ている人は既に持っているでしょう。ただし、モバイル回線で見ている人は、自宅に有線のインターネット環境を用意した方が良いです。

顕正会に入会すれば、上記スペックPC無料で貸し出ししてくれます。また、法人向けの専用線無料で取付工事を行ってくれる上に、通信費を全て負担してくれます

できればあると良いもの

まず、他の会員と連絡を取るために、SNSアカウントを持っていると良いでしょう。

最近は完全にPC上での学習もできますが、やはり、勉強の基本は紙のノートに直接書くことです。医学的にも、手指の動きと脳の記憶回路が関連していることは証明されており、手を動かすことで効率的ものを覚えることができます

Kindleなどの電子書籍リーダーは持っておいた方が良いです。紙の本は時代遅れです。いやしくもITプロを目指そうという人間が、このような最先端デバイスを使っていないのは恥だと思うべきです。紙の本を買わないことは、環境を守ることにも繋がります現金も持つのはやめましょう。

自宅での学習

せっかくセミナーに参加しても、受身聴くだけでは、プログラミング習得することは難しいです。ここでは、自宅でどのような勉強をすればよいのか、ご紹介します。

教科書写経する

まずは、教科書参考書写経することから始めましょう。教科書参考書の本文を一字一句正確に書き写すのです。

よく、「写経理屈を学べないからだめだ」と批判されますが、まずは正しい「型」を体に覚え込ませるのが先です。野球水泳などでも、細かい理屈よりも先にフォームを固めるのと同じです。書き写している内に理屈自然と身に付きます

また、写経メリットは「飛ばし読み」を防げるところです。一字一句正確に写経をすれば、細かい部分を「分かったつもり」になって飛ばししまうことを防げます。たとえば、比較演算子の等号は=ではなくて、==です。プログラミングはこういうところに注意して学ばなければいけません。

ソースコードフローチャートUML)に変換する

教科書サンプルコードノートに書き写したら、それを今度は自力フローチャートUML)に変換してみましょう。そうすることで、自分が本当にそのコード理解しているのか、確かめることができます

フローチャートUMLが素早く正確に描けることは、プログラマーとして働く上で非常に重要スキルです。それらはソフトウェア設計の基礎となりますし、ソースコードを読めない営業顧客にとっては貴重な資料となるからです。プロエンジニアは、COBOLソースコード10万行を1週間でフローチャートにして、Excel転載することができます

ここで一つ注意すべきことがありますフローチャートを描くときは、必ず専用の定規を用いて描いて下さい。フリーハンドで描いたもの業務ではフローチャートとは認められません。これはまともな企業就職すれば研修などで必ず習うことですから、今の内に覚えておきましょう。

Excel勉強する

エンジニアを目指すのであれば、プログラミングだけではなく、Excelの使い方も学びましょう。Excelエンジニアにとっての万能プラットフォームです。エンジニアはあらゆる作業Excelで行いますセル結合や罫線を用いて、見栄えの良い資料を作る技術は、エンジニアにとって必須です。

プログラミング学習中であれば、たとえば以下のような題材の資料を作ってみると良いでしょう。

尤も、以上の資料は、ツールを使うことで自動作成することもできます。たとえば、ソースコード更新履歴Gitなどのバージョン管理システムを使うことでも管理できますしかし、それらの資料としてのクオリティは非常に低いため、アマチュアしか使うことはありません。プロを目指す皆さんは、必ずExcelを使いこなせるようになりましょう!VBA習得必須です。

プログラミングのコツ

以上、プログラミング勉強法について解説しました。ここからは、実際にソースコードを書くときのコツを紹介していきます。他のプログラマと差をつけることができる技術ですので、意識するようにして下さい。

変数名は短く

プログラムで使う変数名は可能な限り短くしましょう。

理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。

また、変数宣言使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分ミスしにくくなります

変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。


なるべく関数を作らない

多くのプログラミング言語には、クラス関数といった機能がありますが、これらは基本的ライブラリ提供者などが使う想定の機能であり、一般プログラマが使うのは好ましくありません。したがって、クラス関数はなるべく使わないようにして下さい。

関数を作ると、以下のデメリットがあります

不要関数を作らないためのテクニックには、以下のようなものがあります

まず、関数引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数複数の処理をすることができます

function f(i) {
  switch(i) {
    case 1:
      // i = 1のときの処理
      break;
    case 2:
      // i = 2のときの処理
      break;
    case 3:
      // i = 3のときの処理
      break;
    // ...
  }
}

この方法は、以下に述べる「変数寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます

クラス不要関数を作らないようにするには、「継承」を用います複数クラスで用いる関数定義したクラスを1つ作っておき、そのクラス継承すれば、新しいクラス関数定義する必要はありません。

理想的には、プログラム内のすべての関数を同一のクラス定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、プログラマからはこの上なく尊ばれています

class God {
  f1() {
    // 関数1
  }
  
  f2() {
    // 関数2
  }
  // ...
}

class C1 extends God {
  // 何も書かなくても上の関数が使える!
}

class C2 extends God {
  // 何も書かなくても上の関数が使える!
}
// ...

変数寿命を長くする

変数宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数寿命が長い」と言います

たとえば、以下のコードのaは、関数定義の外側からは参照することができません。

function f() {
  var a = 1;
  return a;
}

一方、以下のコードのaは関数の内外どちらからでも参照することができます

var a = 1;

function f() {
  a = 2;
  return a;
}

変数寿命を長くするのは、プログラマの腕の見せ所です。

せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまます

また、変数寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数寿命を長くするとプログラムを変更しやすくなります。つまり保守性が上がります

例外を潰す

例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイル存在しない場合は、例外となります

例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマ例外をきちんと処理しなければなりません。

ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。

try {
  // 例外が発生し得る処理
  // ex. ファイルを開く
}
catch (e) {
  // 例外が発生したときに、実行する処理
}

例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラム動作を続けます

try {
  // 例外が発生し得る処理
}
catch () {}

全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから例外が発生し得るコードは、積極的上記try-catch構文を用いて、例外を潰すようにしましょう。

おわりに

全体的に専門用語盛りだくさんの記事になってしまいましたが、

部分的にでも理解すればプログラミングを見る目が変わるはずです。

うさんくさい記事インターネットには多いですが、

そういう情報に惑わされずに本物の技術を身につけてもらえればと思います

2021-07-15

オリパラ音楽担当になった小山田圭吾の悪評をreddit投稿しようと考えてる。

このグーグル翻訳を駆使した英文大丈夫か教えてほしい。

増田仕様のせいで空行が入らないので読みにくいかも)

追記:ブコメですでに記事があるという指摘があったので、いまさら投稿しなくてもいいか

なにかに流用したい人がいるかわからんが好きに使ってくれていい。

A creative member of the Tokyo Olympics opening ceremony music was found to have been a fierce bullying assailant in the past.

Keigo Oyamada (born 1969) became a creative member of the Tokyo Olympics opening ceremony music.

In an interview with a music magazine in the 1990s, He talked about being a perpetrator of bullying as if it were a funny thing.

Interview in the January 1994 issue of the music magazine "Rockin' On Japan 20,000-word interview with Keigo Oyamada"

"Also, the bullying was really bad at my school."

 But you said you were the bully.

"Yeah. I bullied him. When I think about it now, it was really awful. I'd like to take this opportunity to apologize (laughs) because I've been bullying him pretty hard."

 Did you do something that bad?

"Yes. Yes, it's against the rules of humanity. I would strip them completely naked, wrap a string around them, and make them masturbate. They feed you shit. And backdropping him after he ate shit."

The school he attended was a combination of primary, secondary, high school and university.

The school offers "joint education" where normal children and disabled children are placed in the same class.

A writer who read this interview planned a dialogue between the "bully" and the "bullied", but it did not happen.

It became a personal interview with Keigo Oyamada.

There was a guy named Sawada. He was a very epoch-making guy, and he came to the school when I was in the second grade. It was a shock to the whole school (laughs). When he moved to a new school and introduced himself, he would suddenly say (in a tone that sounded like he had a speech impediment), "I'm Sawada. It's like, "Wow, that's great! Then, on the first day at the new school, I took a dump. It's a felony for elementary school students to take a dump at school, isn't it?

There was a cardboard box or something like that, and I put Sawada in it, tied it all up with duct tape, made air holes in it (laughs), and said, "Hey, Sawada, are you okay? (laughs) Then, with a chalkboard eraser or something, I slapped it around and said, "Poison gas attack! (laughs) Then, I took a blackboard eraser and said, "Poison gas attack! ...? He said something really interesting. I don't know what it was, but he said something like "Mommy" or something like that (laughs), and everyone burst out laughing.

When it comes to his jersey, everyone takes it off, but it's nothing for him to take his dick out, so he just walks around with it out. But he's got a big dick, and it's been that way since elementary school, but in high school it got even bigger (laughs). (laughs) The girls would react to it, so we would take it off on purpose and have him walk down the hallway.

2021-07-11

昨日からjava勉強し始めたんだけど

ラッツ予想の計算過程を出力するプログラム書いたんだけどもっと簡単に簡略して書く方法おしえてけろ

public class Calc{
	public static void main(String[] args) {
		for(int i=2; i>0; i++) {
			int a = i;
			System.out.println("-----"+ a +"の場合-----");
			while(a != 1) {
			if(a % 2 == 0) {
					System.out.println(a +" ÷ 2 = "+(a = a / 2));
				}else{
					System.out.println(a +" × 3 + 1 = "+(a = 3* a +1));
				}
			}
		}
		}
}

2021-07-02

初心者から中級者になるためのプログラミングのコツ

変数や構文などのプログラミングの基礎は覚えた人向けに、ソースコードを書くときのコツを紹介していきます。どれも今日から実践できるものばかりです。他のプログラマと差をつけることができる技術ですので、ぜひ意識するようにして下さい。良い子はまねしないで下さい。

変数名は短く

プログラムで使う変数名は可能な限り短くしましょう。

理想は、aやxなどの一文字です。ただし、これだけだと26文字しか使えないので、a1, a2, ...のように連番でグルーピングすると良いです。

また、変数宣言使用箇所が離れた場合に、変数の型がすぐに分かるように、たとえばint型であればi1, i2, ...、string型であればs1, s2, ...のように命名すると、読む人に親切で自分ミスしにくくなります

変数名を長くするのは、以下のデメリットがあるため、絶対にやめましょう。


なるべく関数を作らない

多くのプログラミング言語には、クラス関数といった機能がありますが、これらは基本的ライブラリ提供者などが使う想定の機能であり、一般プログラマが使うのは好ましくありません。したがって、クラス関数はなるべく使わないようにして下さい。

関数を作ると、以下のデメリットがあります

不要関数を作らないためのテクニックには、以下のようなものがあります

まず、関数引数に「フラグ」を渡し、関数内部で処理を切り替えれば、1つの関数複数の処理をすることができます

function f(i) {
  switch(i) {
    case 1:
      // i = 1のときの処理
      break;
    case 2:
      // i = 2のときの処理
      break;
    case 3:
      // i = 3のときの処理
      break;
    // ...
  }
}

この方法は、以下に述べる「変数寿命を伸ばす」効果もあります。つまり、この関数内で宣言された変数は、すべての処理で共通して使用することができます

クラス不要関数を作らないようにするには、「継承」を用います複数クラスで用いる関数定義したクラスを1つ作っておき、そのクラス継承すれば、新しいクラス関数定義する必要はありません。

理想的には、プログラム内のすべての関数を同一のクラス定義し、それを継承するべきです。そのようなクラスは俗に「神」と呼ばれ、その利便性からプログラマからはこの上なく尊ばれています

class God {
  f1() {
    // 関数1
  }
  
  f2() {
    // 関数2
  }
  // ...
}

class C1 extends God {
  // 何も書かなくても上の関数が使える!
}

class C2 extends God {
  // 何も書かなくても上の関数が使える!
}
// ...

変数寿命を長くする

変数宣言する場所によって、ソースコードのどの範囲から参照できるかが決まっています。この範囲が広いことを、「変数寿命が長い」と言います

たとえば、以下のコードのaは、関数定義の外側からは参照することができません。

function f() {
  var a = 1;
  return a;
}

一方、以下のコードのaは関数の内外どちらからでも参照することができます

var a = 1;

function f() {
  a = 2;
  return a;
}

変数寿命を長くするのは、プログラマの腕の見せ所です。

せっかく作った変数がすぐに死んでしまうのは、非常にもったいないです。ソースコードの表面には現れませんが、変数を作ったり捨てたりするのには、計算コストがかかります。したがって、寿命の短い変数を作りすぎてしまうと、プログラムが遅くなってしまます

また、変数寿命が長いということは、変数をたくさん作らなくても、1つの変数を色々なところで利用できるということであり、とても便利です。たとえば、上記の前者のコードでは、関数の外部からaの値を参照したくなっても、参照することができません。後者のように書いておけば、プログラムのどの箇所からでも、aの値を参照したり、更新することができます。したがって、変数寿命を長くするとプログラムを変更しやすくなります。つまり保守性が上がります

例外を潰す

例外とは、プログラムが予期しない処理をしようとした場合に、プログラムの実行を停止し、呼び出し元にエラーを通知する機能です。たとえば、「test.txt」というファイルを開こうとしても、そのファイル存在しない場合は、例外となります

例外が発生すると、プログラムが停止してしまうため、非常に困ります。したがって、プログラマ例外をきちんと処理しなければなりません。

ほとんどのプログラミング言語には、例外処理のための機構があります。たとえば、以下のような構文です。

try {
  // 例外が発生し得る処理
  // ex. ファイルを開く
}
catch (e) {
  // 例外が発生したときに、実行する処理
}

例外への対処は実はとても簡単です。是非ここで覚えて下さい。上記のような機構のある言語であれば、catch節の中身を何も書かなければ、例外が発生しても、何事もなくプログラム動作を続けます

try {
  // 例外が発生し得る処理
}
catch () {}

全ての例外を潰せば、決して不慮の動作で停止することのないプログラムを作ることができます。ですから例外が発生し得るコードは、積極的上記try-catch構文を用いて、例外を潰すようにしましょう。

2021-05-31

https://github.com/kokorohamoe/OpenProfile/blob/master/700_sample/Java/Jurina/reader.cpp

とてもシンプルコード

int main(int argc,const char*argv[]){

int v;

char buffer[1024];

while(1){

printf("input\n");

scanf("%s%d",buffer,&v);

if(strcmp(buffer,"print")==0)

fprintf(stderr, "public class base{\n"

"public static void main(String[] args){\n"

"int i = %d;\n"

"System.out.println(i);}}\n",v);

}

return 0;

}

jurina

cat filename.jurina

print "Hello world";

という命令ファイルから受け取ったら

public class filename{

public static void main(String[] args){

System.out.println("Hello world");

}

}

と出力するプログラムをjurinaと名付けるとする

cat filename.jurina

int i=1;

print i;

public class filename{

public static void main(String[] args){

int i=1;

System.out.println(i);

}

}

ものすごく単純なPythonっぽい独自言語

Javaに置き換えて出力するだけのJava プリプロセッサである

さて、このJurina言語JAVA VMで動くと思うか?

   

言いたいことVMを解析して、OPコードを吐くコンパイラを作ろうとしていたが

そもそもコンパイラが作れるならJavaソースコードを吐いてしまえば良いことに気がついた

2021-05-18

javaString a = new java.util.Scanner(System.in).nextLine();」

pytnon「a =input()」

java冗長すぎかよ糞言語だな

2021-05-04

anond:20210426025101

public class Main {

public static void main(String args[]) {

System.out.println("ア゙ァーッ ォギョヴァアア!!");

}

}

2021-04-23

anond:20210423131826

愚直にやるとしたらstring化して"."でsplitしてint arrayを作って

ループindex小さい方から比較する方法かなあ

JavaScript簡単な例を書いてみた

(ちょっと直した)

https://jsfiddle.net/gea5nm2f/

https://jsfiddle.net/1y5ewcu7/

実際にはバージョンクラスとか比較用のヘルパーみたいなのは

言語で利用しやす状態になってることは少なくないかな~

2021-03-28

[]2021年3月27日土曜日増田

時間記事文字数文字数平均文字数中央値
009610833112.841.5
01717854110.647
02456951154.567
03263787145.770.5
04143140224.352
05171924113.278
0619152180.154
07444749107.943
08477325155.946
09758094107.943
1088863498.141.5
11528150156.753
128110264126.741
1380706388.338
1489803590.342
15717499105.637
1611613466116.155.5
171871707491.343
1810513272126.465
1965584589.941
201331233192.740
2114615193104.143.5
2214016781119.942
2313719912145.353
1日1944219697113.046

本日の急増単語 ()内の数字単語が含まれ記事

池内(7), afa(3), リアルフォース(3), 赤潮(3), ディスクシステム(3), String(3), 5d2(3), c65(3), 古谷(3), c73(3), 398円(3), 聖火(3), ひろゆき(13), ぶつかり(10), 五輪(17), ぶつかっ(12), 美し(7), ファミマ(5), 意図的(6), ウマ(5), 飲める(5), シン(7), 女性差別(11), 明治(7), 転換(6), お菓子(10), 本屋(6), キーボード(7), 明るい(6), irasutoya(8), 思いつく(5), 素人(20), 英語(28), yahoo(13), c(11), 現象(12), 乗る(10), 狙っ(9), 集まる(9), 潰し(9), オリンピック(12)

頻出トラックバック先 ()内の数字は被トラックバック件数

最近ネット見ていると「素人時代」が終わったんだなと悲しい /20210326175758(35), ■全然使われないダースかい単位 /20210327082442(14), ■英語を喋るしか能がない人 /20210327201219(12), ■名前みたいな姓ってどんなのがある? /20210326143830(12), ■癌で死ぬ男と分子標的薬(抗がん剤) /20210326173438(11), ■初代ゼルダの伝説は最高のゲームである。 /20210327082514(11), ■日に日にサウナ雰囲気が悪くなっている /20210326160158(10), ■ブクマカは自らが4610であることを自覚せよ /20210326185842(9), ■いいねRTを欲しがる創作界隈の人に思うこと /20210327160215(8), ■東京はなにもかにもが高い /20210327090622(7), ■はてな冷笑系クラスタたち一覧 /20210327175320(7), ■ジェンダーフリーの50年後 /20210327111830(7), ■ガチ人生変えたい どうしたらいいの? /20210327001758(7), ■女性にわざとぶつかりにくる男について /20210327210556(6), ■#werise という反コロナイベントが行われる /20210326191647(6), ■金玉吸って!!😠 /20210327071218(6), ■東山動物園でも行くか /20210327123938(6), ■ /20210327173520(6), ■本末転倒感のする行動 /20210327102411(5), ■アンチフェミとは何か /20210327000305(5), ■昔大好きだったダイの大冒険リメイクアニメについて思うこと。 /20210327202353(5), ■オリンピックパートナー≒不買推奨企業リスト になったよね /20210327124416(5), ■フェミニズムってそもそも弱者男性を想定してるのかしら? /20210327000111(5), ■多様性大事っていう人は差別主義者だよね /20210327170749(5), ■凡人がはてな匿名ダイアリーという村を見つけました。 /20210325224726(5), ■全員Amazonハチャメチャ配達員みたいになればいいのに /20210326182722(5), ■彼女がいないと言い張る男 /20210326130831(5), ■キモいオタクツイッターアカウント絶対書いてること /20210327024609(5), ■小汚い爺が歩きタバコしてた /20210327093929(5)

2021-03-27

anond:20210327213156

きょうのC#勉強LINQのSortBy()で止まった

参考書かにアルファベット順って呑気に書いてあるけどこれいわゆるASCII順だよねと思って

(彼らが揃いも揃ってアルファベットだけで構成された単語比較例だけしか出さず、数字開始あり・空白ありの文字列比較をさせないのは怠慢だと思う)

比較に使ってるメソッドなんだろうと思って、String.CompareToからString.Compareに行ってCompareOptionsを見て、

.NET での文字列の比較に関するベスト プラクティス | Microsoft Docs

うわー、うん、なんか見なかったことにしておく

もし俺が参考書書くときアルファベットだけで構成された単語比較例だけ出すことにしようと思う

anond:20210327222756

まぁstringはSystem.Stringエイリアスからstringのほうがいい。

intはSystem.Int32のエイリアスなんだけど、ふつーintを使って、Int32なんて使わないでしょ。

boolとSystem.Booleanも同じかな。

https://stackoverflow.com/questions/7074/what-is-the-difference-between-string-and-string-in-c

エイリアスなんで、パフォーマンスには全く関係いから、ぶっちゃけなんだっていいと思う。

anond:20210327213156

ずっと思ってるんだけど、List<string> って List<String> じゃ駄目なの?

2021-03-20

anond:20210320174526

7と8。

技術的なところが気になる人はこれだけ読んでくれたらいい

7. アプリケーションコード自体はRocketChatのものとほぼ同じ

最後技術的な観点からエアレペルソナが純国産ではないということを指摘する。

結論から先に述べると、このアプリは純国産ではない。

RocketChatという海外で開発されたOSSチャットアプリフォーク、改変したもののよう。

ttps://github.com/RocketChat/Rocket.Chat.ReactNative

ttps://rocket.chat

フォーク元はバリバリ多国籍外資である。(RocketChat自体問題のないアプリであり、このエアレペルソナとはフォーク関係を超える関係はないと思われる)

冒頭のこの部分に関してである

ttps://play.google.com/store/apps/details?id=chat.airlex.reactnative

Google Playで公開されているエアレペルソナAndroidアプリリバースエンジニアリングして調べてみた。

ちなみに、エアレペルソナには利用規約のようなものは見当たらず、リバースエンジニアリング禁止条項も無いようだった。

ttps://apps.evozi.com/apk-downloader/

ttps://github.com/pxb1988/dex2jar

この辺を使ってapkダウンロードし、apk解凍し、chat.airlex.reactnative/classes.dexjar fileに変換した。

classes.dexから変換されたjarファイルを展開するとchat/airlex/reactnativeというフォルダパッケージが見つかる。

このパッケージ内のファイル(.classクラス)がエアレペルソナの処理を行うもののようである

特徴的なクラスにEjsonという名前のものがある。

このクラスJadを使い、デコンパイルしてみた。その結果が以下である

ttp://www.javadecompilers.com

ちなみにここからapkアップロードするとdex2jarをしなくてもJavaソースコードにまでデコンパイルしてくれた。便利。

package chat.airlex.reactnative;

import android.content.Context;
import com.ammarahmed.mmkv.SecureKeystore;
import com.facebook.react.bridge.ReactApplicationContext;
import com.tencent.mmkv.MMKV;

public class Ejson {
    private String TOKEN_KEY = "reactnativemeteor_usertoken-";
    String cardId;
    String host;
    String messageId;
    String messageType;
    /* access modifiers changed from: private */
    public MMKV mmkv;
    String msg;
    String notificationType;
    String rid;
    Sender sender;
    String senderName;
    String type;

    public Ejson() {
        ReactApplicationContext reactApplicationContext = CustomPushNotification.reactApplicationContext;
        if (reactApplicationContext != null) {
            MMKV.initialize((Context) reactApplicationContext);
            new SecureKeystore(reactApplicationContext).getSecureKey(C0617Utils.toHex("com.MMKV.default"), new RNCallback() {
                public void invoke(Object... objArr) {
                    if (objArr[0] == null) {
                        MMKV unused = Ejson.this.mmkv = MMKV.mmkvWithID("default", 1, objArr[1]);
                    }
                }
            });
        }
    }

    public String getAvatarUri() {
        if (this.type == null) {
            return null;
        }
        return serverURL() + "/avatar/" + this.sender._id + "?rc_token=" + token() + "&amp;amp;rc_uid=" + userId();
    }

    public String token() {
        String userId = userId();
        MMKV mmkv2 = this.mmkv;
        return (mmkv2 == null || userId == null) ? "" : mmkv2.decodeString(this.TOKEN_KEY.concat(userId));
    }

    public String userId() {
        String serverURL = serverURL();
        MMKV mmkv2 = this.mmkv;
        return (mmkv2 == null || serverURL == null) ? "" : mmkv2.decodeString(this.TOKEN_KEY.concat(serverURL));
    }

    public String privateKey() {
        String serverURL = serverURL();
        MMKV mmkv2 = this.mmkv;
        if (mmkv2 == null || serverURL == null) {
            return null;
        }
        return mmkv2.decodeString(serverURL.concat("-RC_E2E_PRIVATE_KEY"));
    }

    public String serverURL() {
        String str = this.host;
        return (str == null || !str.endsWith("/")) ? str : str.substring(0, str.length() - 1);
    }

    public class Sender {
        String _id;
        String username;

        public Sender() {
        }
    }
}

フィールド名を見てみると、cardId, host, messageId, messageType, mmkv, msg, notificationType, rid, sender, senderName, typeが存在する。

メソッドには、getAvaterUri、token、userId、privateKey、severURLが存在する。

ところで、RocketChatというOSSチャットアプリ存在する。

ttps://rocket.chat

そのRoketChatのAndroid実装の中に同名のEjsonというクラス存在する。

ttps://github.com/RocketChat/Rocket.Chat.ReactNative

ttps://github.com/RocketChat/Rocket.Chat.ReactNative/blob/develop/android/app/src/play/java/chat/rocket/reactnative/Ejson.java

見比べてみると、フィールドにcardIdが追加されている以外はフィールドメソッド名、そしてその処理の内容まで一致している。

他にもReplyBroadcastなど、同様のクラスがエアレペルソナに見つかる。

以上のことからエアレペルソナはRocketChatをフォークして、パッケージ名を変えて作られたチャットアプリであり、開発の大部分はRocketChat社の努力と多数のOSSコントリビュータによってなされたものであると思われる。

これを純国産日本製と呼ぶには大分無理がある気がする。

そもそもこのOSS時代に純だの何だの言っている時点で怪しい。

8. OSSライセンスに関して

さて、エアレペルソナがRocketChatをフォークして作られたものであるとすると、気になるのはライセンスである

RocketChatのOSSライセンスMITライセンスである

ttps://github.com/RocketChat/Rocket.Chat.ReactNative/blob/develop/LICENSE

MITライセンスは非常に緩いライセンスであるため、エアレペルソナの様にフォークして別のアプリケーションとして公開することにはおそらく問題がないということは強調しておく。

現状エアレペルソナログインできておらず(2要素認証コード送信されないといった問題が起きている模様)、使用している各OSSライセンス表示が適切に行われているかまでは調べられていない。

2021-03-04

javascriptに詳しい人、教えてくれぇええ~~

ツクールゲーム作ってみたくてプラグイン見てるんだが

DWindow.jsっていうののプログラムの流れが分からんのだ。

部分的抜粋しているが、

        if (arguments.length &lt; 2) min = -Infinity;
        if (arguments.length &lt; 3) max = Infinity;
        return (parseInt(value, 10) || 0).clamp(min, max);

これがさっっっぱり分からん。Infinityは何処から出てきた?

10か0かっていうのも、窓の数は最大10って書いてあったが、それが問題なのか?

min,maxはどこから来たんだ…。

やりたいのが、これと同じように「変数」の値を設定するとして、

その変数には配列を入れたいと思っているんだ。

配列ループして色々確認したいのだが、そもそも配列はどうやってやるん?となってる。

getParamNumber配列はできるのか…?

Numberだけでなく、String配列も使う予定だ。うーーーーーーーーーーーん。

javascript勉強サイト確認したら分かるものなのか?

もっとソース貼ろうとしたら、匿名ダイアリーに怒られたので載せられん…。

すまんが、詳しい人教えてくれ。

2021-01-20

anond:20210120180109

山括弧stringスラッシュ山括弧閉じでもいいしstyleでfont-weight: boldでもいい

ログイン ユーザー登録
ようこそ ゲスト さん