はてなキーワード: 演算子とは
掛算の順序と学習指導要領の話おもしろかったです。
「りんごが5つ載った皿が4枚ある場合にりんごがいくつになるか」という問題を立式するときは、
という話だと思いました。
4✕5は4[個/枚] * 5[枚]に変換されるので、正解にならない。
✕は乗算の演算子と思ってしがいがちだけど、被乗数と乗数の順序を考慮するときは、その順序を含めた乗算のシンタックスシュガーになっている。
なんか、このシンタックスシュガーいけてないなと思うのは、計算するときは交換法則適用していいよと言われているところと、乗法を習うこの単元以外では立式の際もシンタックスシュガーではなく乗算の演算子として取り扱われているところ。
でも、いけてないシンタックスシュガーは世に溢れているので、まあいいや。
被乗数と乗数の関係を考えていて思い出したのが、消費税が導入されたとき、大学生協の書籍代はどうなるのかという話。
乗算は交換法則が成り立つから1000*0.9*1.03でも1000*1.03*0.9でも良いです。
✕も計算のときは交換法則を適用して良いから1000✕0.9✕1.03でも1000✕1.03✕0.9でも良いです。
でも✕で立式するときはどうなるのか。
1000[円/冊]✕1[冊]✕0.9✕1.03と1000[円/冊]✕1[冊]✕1.03✕0.9のどちらが正しいのか。
0.9と1.03は単位がないから乗数、被乗数の順序を考慮しなくて良いのかな。
僕が小学生の頃は乗数、被乗数は「かける数」「かけられる数」と言われてました。
「この式の4は『かける数』でしょうか『かけられる数』でしょうか」みたいなテストの問題があったけど、「この話は、ここでしか出てこないので、気にしなくて良いです」と先生が言って、採点対象外になってました。
javascriptの結合性について
a=b=1;のような場合、この文に使われている演算子はどちらも同じ=という種類であり、優先順位に差が無いので、左側から解析し、もう一つ同じ演算子があるので演算子の実行を保留し、右側の=を見つけて、右から代入するというのはわかります。
では()すなわちグループ化のような場合はどうなのでしょうか?さいわいこれには結合性はないようですが、あったとしたらどう考えればいいのでしょうか?
=のように右と左をオペランドに挟まれた形ではないので、左側とか右側とかいってもよくわかりませんし、(...)+2の)+のように演算子同士が隣接する場合も考えるとますますどういうアルゴリズムなのかよくわかりません。
それともだからこそ、()には結合性を設けないとしたのでしょうか?
dot dot dotさん
2024/2/25 15:38
a = b = 1
は
a = (b = 1)
調べましょうでもいいんですが、知ってるならそのあなたが同じ疑問にあたったときに調べて解決につながった情報だけを一通り書いてくれるのが一番ありがたいのですが。
足し算と足し算を足したらどうなるのかを研究してる子がいるそうだ。
その結果を数値で表してそれを逆写像で演算子に戻すことで研究してるんだってさ。
ぶっちゃけこんなの作用素環論で研究しつくされてるだろって思った。
だいたい最初に数値で表す意味がわからない。直接演算子を答えとすりゃいいじゃん。「なんか大がかりな研究したように見せる」はったりを利かせるために、手続きを無駄に複雑にしただけって見える。内申狙いでわかってやってるなら策士だがな。
なぜ教師もこんな車輪の再発明にしかならないことを止めなかったのか。高校生にすら小学生の自由研究と本質的には変わらない「もう人類が知ってる結果を研究させる」ことをさせてしまっているのか。
生物系の子はムラサキツユクサのおしべとめしべの間の毛で原形質流動が起こるのはなぜかの研究をしているらしく、こっちはまだわかってない可能性がありそうなので意味のある研究だと思う。
まあ小学生でも生物の新種発見することはあるし、高校生に研究者の真似事させるなら生物だけやらせときゃいいんじゃないかなって思う。数学とか物理じゃ絶対本職の研究者は出し抜けないものね。
dorawiiより
自分には6年付き合った年上の彼女がいた。名前はPHP。学生の時からの付き合いで、自分にとっては初めての彼女だった。付き合った当初は全てが新鮮で、オブジェクト指向やSOLID原則、大事なことは全て彼女から教えてもらった。(そう思われるかもしれないが、)時間が経って彼女の魅力が感じられなくなってしまったということはなくて、彼女は歳をとっても魅力的なままだった。むしろreodonlyプロパティやEnum、null safe演算子など、新しい機能が導入されてますます綺麗になっていったように思う。最近ではジェネリクスさえ導入されたようだ。彼女は本当に努力家だ。
(褒められた話ではないが一応、彼女以外の女性を全く知らなかったわけではなく、TypeScriptという若い子と少し遊んでいたこともある。TypeScriptは昔からの知り合いのJavaScriptの妹で、大雑把な姉と違って几帳面で、少しオタク気質もある個性的な子だった。よく新しい型パズルを考案して楽しそうに話してくれたが、自分には正直よく分からなかった笑。)
そんな中でも基本的には6年間PHPとずっと一緒に過ごしてきた。前述の通り彼女に何か不満があったわけではない。ただ、彼女との将来に不安を覚えるようになってしまっていた。周囲に彼女と付き合っていることを話すと、「え、まだPHPと付き合ってたんだ?(昔は人気だったけど、最近はそうでもないよね)」みたいなことを、彼女のことをよく知らない人から言われたりもした。そこまで直接的ではなかったけれど。自分も、彼女以外の女性のことをほとんど知らずにずっと彼女と付き合っていて大丈夫なのかななんて思ってしまったりしていた。
結局自分はPHPと別れて、新しい女性と付き合う決断をした。新しい彼女の名前はGo。彼女は若いのに自分の芯がしっかりしていて、みんなの憧れの格好良い女性といった人だった。そんな彼女と付き合いだして、最初は戸惑うことも多かった。
例えばこんな感じだ。
また、今まで当たり前だと思っていたPHPの良さに気づくことも多い。PHPStanを使えば静的型付け言語と同じように型安全性を担保できていたし、彼女のWeb FWには歴史が長いだけあって痒いところまで手が届く様々な機能が完備されていた。経験豊富でこちらの要望をなんでも受け止めてくれるような包容力があったことに今更気づいた。
とはいえ、いつまでも昔の彼女を引きずっていてもしょうがない。Goにはこちらに積極的に合わせてくれるような包容力はないが、彼女なりの哲学を持っていてそれ故の美しさがあると思う。そして正直、まだ彼女の10分の1も理解できていない。彼女が得意だという並行処理や、実行速度が求められるような処理も、自分はまだ実際に実装したことはない。でもこれからしっかり向き合って、Goのことをもっと理解して、実りのある交際にしていきたいと考えている。PHPと別れてGoと付き合う決断したのは自分なのだから。
https://qiita.com/NaYuA/items/1cda0211ec44fb25d422
みんな大絶賛してるけど、これやばいやつよね
いわゆる「学生チート」ってやつで、社会人が言ったら全力全方位で駄目だしされるやつ
この「手放し称賛」が人を伸ばすんだと言う話をするなら、そのへんの大人も手放し称賛されるべきよね
さておき
POSの時【POSはPoint of Saleの略です】と説明してるのに対して
みたいなのが、非常に「わかってない感」を出しちゃってるよね
いや多分、脳内ではわかってるんだろうけど
説明口調で書くなら
みたいになる
技術用語として「await 演算子はプロミス(Promise)を待ち」みたいに直訳でドキュメンが出回ってるし
非同期で行うサーバーサイドの処理ではPromiseを使いましょうみたいなのが
サーバー書き込みなので、当然Promiseを返します、になってるんだろうけど
新人とかの、「わかってないけど書けます」連中が、大体こういう理解の仕方をしてるから
(Promiseを返すのはなんでだ?サーバー処理だから(キリッ)
もちろん、学生なんだから良いじゃん、良いじゃん、すげぇじゃん
というのもアリなんだけども
このわかってない感満載の文章を、手放しで称賛して、「考えて行動するだけでスゴイ」みたいになってるの
「みんながあんまり誉めたりするから、私自分が優秀な人間だって勘違いしちゃったじゃない!!」を思い出させる
方程式を解く最中に自分が何をしているのか分からないということになっている。
数学においてはなんとなく生きてなんとなく死ぬという酔生夢死で終わるのではなかろうかという心地だ。
たとえば速度に関する関係式としてx(t+Δt)-x(t)≒v(t)Δtというのがあるわけだ。
ここから変位xを求めようという解法のテクニックとしてΔτ=t/nとおくとかΔτk=kΔτとおくとか、極め付けにはt=τkとおくことで区分求積法に帰着させる解法が載ってたりするわけだ。
しかしこうした変換式の設定が無意味ではないとどうして分かるのかと思ってしまうというわけだ。
もしそれぞれのtが出てる式についてt=と変形したとき、各式の左辺を等式で結ぶと恒偽式になるような状態だったら無意味な置き方だということぐらいは私にも分かる。
たとえばa=x+yと置く一方でa^2=x^2+2xy+y^2+1と置いたのではこれは1=0を導く関係式を導くのでこの置き方は無意味だと分かる。
他にも自明な例だけどもx=1と置きながらx=2と置いたり、x+y=2と置きながら2(x+y)=2と置くのも無意味だろう。
しかしこれらは経験的に自明なだけでなく各式をxy平面にグラフとして表したときに交わらないということでも視覚的に自明と分かる。
a+b=tとおくと同時に(a+b)^2=t+1と置いたらどうだろう。これは経験的には自明な無意味な置き方に思われるが実際にtだけの式に直すとt^2+t-1=0となる。少なくとも恒偽式ではない式が出てくるわけだ。
となれば経験的にそれとなく直感されない置き方についてはそれが無意味な置き方であるかどうかどうやって検討すればいいのかという話になる。
物理の式なんてものは多変数で高次式なわけだから恒偽式かどうか到底視覚化して判断できるものじゃない。もちろん経験的な勘が働くほど単純な式というのも多くはない。2aF/(M(a+b)+4ab)-gと(F+Mg)ab/(2ab+Ma+Mb)が常に等しいか常に等しくないのかなんて判断できっこないのだ。ある式で置くということにこうした複雑な式を出されたらその置き方が論理的に妥当かという検証などもうあきらめてとりあえず従っておくしかないわけである。
思えばなんで連立方程式は加減法や代入法で解けるのか、それをその方法で解くということの意味について深く教わった覚えがない。二元や二次方程式までならグラフなり平行移動なりの考えで方程式を解くことの図形的な意味合いの考察を垂らされた覚えがなくもないのだが、それは一般の方程式について解くことの意味の説明にはなっていない。
かくして応用が利かない中途半端な説明しか教授されてない結果として自分が何をしているのかも分からず形式的に方程式を解くだけかあるいはその連立方程式の妥当性が検証できないような悲しい人間が出来上がってしまっているわけである。
とはいえ任意の個数だけそれぞれが任意の関数であるもの同士が任意の個数の任意の演算子で結びついている表現されている何ものかについて、それを解くことの意味を解説されても分かる気がしないわけだけども(たとえば∫a+bはaという関数に一項演算子の積分演算子が作用した後、二項演算子+によってbと結び付けられ何がしかの値を示している、みたいなことをものすごく抽象化した話を言っている)。
この問題の難しさは、ある変数が変化すればそれ以外の全ての変数が変化する一方である変数以外の変数が変化した場合もある変数を含む全ての変数が変化するというその挙動の掌握することの難しさにあるのだろう。これが変化したらあれもこれも変化するという条件の中で論理的整合性を考えるというのは変数の数だけ変数の挙動を追跡する考える余力がないといけないというわけで凡人なら簡単に頭がパンクしてしまうわけだ。
当初は真面目な口調で解説しようと思ったのだけれど、堅っ苦しくするのもエントリの空気感自体が専門的になりすぎる気がしたので多少くだけた口調で進めさせて貰うね。
んで、まずはすべての絵師の皆様へ伝えたいことがある。
前提として、この「すべての絵師の皆様へ」の見出しの段は以降の見出しの段を書き終えてから追記したものだ。編集後記みたいなものか。
それでは話そう。
皆さんは絵師で絵を描き、ボクはプログラマーでプログラムを書いている。
大きなカテゴリで言えば同じくモノ作りをする属性を持った人間だろうと思わせてもらいたい。
同じくモノ作りをする人間として、絵師の皆様の混乱を知って「あぁコレは絵師の豊かな想像力が悪い方向に働いちゃってるな」と感じたんだ。
間違ってたら申し訳ないけれど、おそらく多くの絵師がイメージしたのは創作内に出てくる人工知能だ。
人工知能の暴走によりディストピアが発生する。そのようなイメージが湧いたんじゃないかな?
そして絵師たちは、ディストピアの前段として自分たちの画風・技術を学んだ人工知能が自分たちのオリジナリティを奪い、自分たちの生活を、自分たちの価値を崩壊させるんじゃないか?と不安になった。
ターミネーターのスカイネットような、火の鳥未来編のハレルヤとダニューバーのような人工知能の支配と暴走が起きるのではないかと。
もしも違う、そうではないと思うのであればココで読み終えたら良いと思う。このエントリは上記を前提に話が進められる。
しかし「その通りなんだ!人工知能はよくわからないけど自分の絵が盗まれるんじゃないかと怖くて怖くて仕方ないんだ!」と思ったのならばボクはこのエントリを書いた意味がある。
絵師だけでなく多くの一般人は知らないが、わかりやすく「人工知能とはなにか?」を解説する際に大半の情報技術者が納得する極々シンプルな表現に「人工知能とは計算機である」という表現があるんだよね。
つまり1 + 1 = 2を計算できる電卓の超高度版が人工知能ということであって、情報技術に関してちょっと疎い人は信じられないかも知れない。
しかし、電卓の中でもちょっと高度な関数電卓になると筆算で苦戦する人がそこそこいるであろう平方根√の計算は出来るし、時間計算に便利な60進数換算が出来たりもする。
そもそも、いわゆるパソコンも計算機の一種であって実際に話題になっているStable Diffusionもパソコン上で動く。
ただし、多くの人工知能は電卓やパソコンのようにハードウェアではないソフトウェア計算機であるという違いがある。
普通の電卓と人工知能の何が違うのか?
それは見かけ上で入力する「パラメータ」に違いがあるんだよね。
それではパラメータとは何か?
これは1 + 1 = 2で説明すると非常にわかりやすい。
パラメータとは1 + 1 = 2のような非常にシンプルな計算式では「1」のこと。早い話が数字なんだ。
そして計算結果を出すには計算式が必要で、足すのか引くのか、掛けるのか割るのか、その振る舞いを決めるのが「+」である。
この計算の振る舞いを人工知能へ置き換えると「アルゴリズム」と呼ばれるようになる。
細かいことを抜きにすると1 + 1 = 2の+部分はアルゴリズムとまずは理解しよう。
演算子はアルゴリズムなのか?とツッコミたくなる有識者も居るだろうけど話を複雑にするツッコミは取り敢えず横に置いておこう!
「1」がパラメータ、「+」がアルゴリズムと言うのは理解できるけど、人工知能へ置き換えられてしまうと理解が難しい。
そんな人は安心してくれ。人工知能へ置き換えたって意外とシンプルだ。
例えば普通の電卓よりも高度な関数電卓でパラメータ「円周率」を入力したい場合どうしたら良いの?
「3.141592…」と入力していくのだろうか?
それは思い違いで、関数電卓には円周率が格納された「π」があるんだ。
しかもたいていはπボタン一発で入力できる。入力手順が多くてもボタンを2回3回押下するだけだ。
関数電卓を扱える者は高度な円周率をたった1つのπで利用できてしまうわけで、何だかこれはどこかで聞いた話じゃないかな。
ご想像の通り、人工知能の、特に今話題のイラストレーションAIのパラメータとは「Sky(空)」や「Sea(海)」などの言葉なんだ。
普通の電卓ではパラメータ「1」が選択でき、関数電卓ではパラメータ「π」が選択でき、イラストレーションAIではパラメータ「Sky(空)」が選択できる。
この時点で絵師や多くの一般人が「人工知能は本質的に超高度計算機である」ことが理解できたはず。
扱えるパラメータボタンがメッチャクチャ多いのが人工知能なんだ!
しかもイラストレーションAIが扱えるのは「+」や「-」というアルゴリズムだけでなく「絵を描く」というアルゴリズムまで扱える。
「Sky(空)」「次のパラメータを加えて絵を描く」「Sea(海)」の計算結果として「空と海が描かれたイラスト」を得られてしまうのがイラストレーションAIなんだ。
これは大変センセーショナルだよね。
しかもイラストレーションAIが機械学習によって既存のイラストから学びを得てイラストを生成していると言うじゃないか!
絵師が自身のオリジナリティをイラストレーションAIに盗まれてしまうかも知れないという危機感は物凄く理解できる。
普通の電卓から関数電卓、パソコン、人工知能に至るまで計算機の最大の欠点とも言って良い要素に「計算機はパラメータの意味を知らない」というものがあるんだ。
それこそボクのこの話が意味不明だろうから解説しよう。
例えば皆さんが単純に「1 + 1 = 2」という計算式を認識したとき、この計算式がなにを意味しているか、なにを計算したのかわかるだろうか?
さっそく答えを言ってしまえばわかるわけがないのだ。
この「1」や「2」は人数かも知れないし個数かも知れないし、日数かも?電力?重さ?年齢?さっぱりわからないよね。
当然の話だよね。ボクたち人間は計算を用いる際は何らかのシチュエーションに於いて、何らかの意味を求めて計算をするのだから。
単純に「1 + 1 = 2」と記述されても各々のパラメータが意味することが明示されていないから誰にも理解できない。
同じように、あなたが鉛筆の数を計算しようとして普通の電卓へ「1」というパラメータを渡しても、その「1」が鉛筆のことであると決して電卓は理解しない。
それが関数電卓であってもパソコンであっても人工知能であっても計算機は決してパラメータの意味を理解することはないんだ。
「1」が鉛筆であると知っているのは今まさに電卓で計算しようとしている本人だけだ。
絵師の皆様へ問おうじゃないか。
あなたの「Sky(空)」はどのようなものか?と。あなたの「Sea(海)」はどのようなものか?と。
イラストレーションAIを活用したいと考える皆様へ問おうじゃないか。
あなたの「Sky(空)」はどのようなものか?と。あなたの「Sea(海)」はどのようなものか?と。
あなたの藍はどれほど青いのか、絵師の藍がどれほど青いのか、個々人の藍がどれほど青いのか、イラストレーションAIは機械学習をどれだけ重ねてもそのパラメータを理解することはない。
なぜ理解しないのか?
イラストレーションAIは計算機だから、道具だから、そして新しい時代の絵筆だから。
はっきりと言ってしまえば、イラストレーションAIが教師データとして収集した既存イラスト群へ機械学習をかけ、そこから新規イラストを生成しようとしても、イラストレーションAIが保持しているパラメータが意味するものは、個々人の主観と同一のものであるとは限らないだよね。
しかも、イラストレーションAIのパラメータは既存イラスト群から統計的に成立させたものであるから特定個人の主観と100%合致することはないと言って良い。
「私の空は緑から青のグラデーション」と考える人が居ても、その人が求めている緑や青などの色、グラデーション感、そもそも空の描画の仕方、雲があるのか無いのか、光はどうなのか、イラストレーションAIへ与えるべきパラメータを想定するだけで膨大になっちゃう。
少なくとも「緑から青のグラデーションの空」程度のパラメータでは現在のイラストレーションAIでは理想的なイラストが生成される可能性は著しく低いはず。
これはもう完全に「この色とあの色を混ぜてどうのこうの」という状況とまったく同じであり、だからこそ「Stable Diffusionのパラメータがどうのこうの」という記事が乱立しているんだ。
断言して言おう。
現在のイラストレーションAIという絵筆を最も上手く扱えるのは絵師の皆様であると。大半の一般人よりも「Sky(空)」や「Sea(海)」の奥行や深みを知る絵師のパラメータ調整はボクたちのような情報技術者は決して敵わないだろうし、多くの一般人などは写像の言語化すら困難なはずだ。
例えmimicのような特定の絵師の特徴量を学習できるようなイラストレーションAIが登場しようが、そのパラメータを区切り設計しているのは絵師よりも「Sky(空)」や「Sea(海)」を知らないボクたち情報技術者だ。
ボクたちは絵師がどこまでを「Cheek(頬)」と考え、どこまでを「Forehead(おでこ)」と捉えるかを知らない。
ほぼ間違いなく我々はあなたの絵柄を完璧に出力することはできない。あなたの絵柄と比較してどこか違う、どこか違和感のあるイラストしか出力できない。
情報技術者はあなたではないから、あなたの認識の範囲を知ることができず、そうならざるえないんだ。
あなたであれば知っていることをmimicは決して理解できない。なぜならmimicは計算機だから。
計算機は1 + 1 = 2の意味を理解しない。あなたのイラストの特徴量を学習しても出力されたイラストがなんなのか計算機は、人工知能は理解していない。
イラストレーションAIであなたの作品を出力できる人間はこの世でたった1人、あなた自身だ。
イラストレーションAIは新しい絵筆であり、今後新たな絵筆がどんどん登場するはずだ。
例えば描画キャンパス全体の傾向からペンの入り抜きを自動的に補正するイラストレーションAIペンなど面白いかも知れない。
これを実現するにはmimicと同じようにあなたのイラストを人工知能へ学ばせることが必要になるだろう。
しかし、その入り抜きが正しいか判断するのはあなた自身なんだ。何故ならばイラストレーションAIは絵筆であり、絵筆の振る舞いが正しいか決めるのは意志のない絵筆ではなく使用者だから。
そうやって広がりつつあるのが、ノーコード界隈なんだけども、そもそも、プログラミングというのは、プログラミングによって何ができるのか?と言う勉強から始まり、何ができないのか、と言うことも含めて勉強。
つまり、ドラッグアンドドロップで、IF文の矢印を分岐させることは、別に、プログラムできない人からすると便利なのか?というと、そんなことないでしょ。
例えば、SUM関数動かすために、SUMのブロックを繋ぐ、足し算するために、変数という概念が必要で変数はこのブロックに、入れます、、みたいなことを果たしてビジュアルだからってより簡単理解できるのか?ってのを考えてみてほしいな。
それならそもそもPythonでsum関数使うなら+演算子使うなりして、やる方が保守もやりやすいでしょ。
ビジュアルプログラミングの場合、各ブロックが何をしてるかは、そのブロックにちゃんと名前つけたり、ダブルクリックで詳細画面に飛ばないとわからなかったり、詳細画面の中に、実はプログラミングコードがあったりしてそこで魔改造されたりしてる。
これを知れば地獄とわかるでしょ
自動で安価をつけて返信するプログラムでもこんなに長く複雑になる(一部抜粋)
/**************************************
以下のCSV_DIR, FILE_PATHS, SETTINGSを書き換えてね。 <h3>o- *************************************/</h3>
//CSVファイルが置かれてるディレクトリのパス。投稿前にエラー出たら大体ここの設定ミス。 例:"C:\\Users\\sakuraimasahiro\\Documents\\iMacros\\Macros\\rentou\\";
'C:\\Users\\USER\\Desktop\\iMacros\\Macros\\rentou\\';
//ファイルのパス。CSVは絶対パスで、拡張子も必要。iimは相対パスでよく、拡張子不要。
const FILE_PATHS = {
textCsv: CSV_DIR + 'textNoAnker.csv',
//レス用投稿文が書かれたCSV。通常とレス用で分けないなら同じファイルを使えばいい。
replyTextCsv: CSV_DIR + 'textReply.csv',
};
baseWaitTime: 5,
//baseWaitTime+0~waitTimeRange(ランダム)だけ待つ
waitTimeRange: 5,
//連投しすぎだと忠告された場合に処理を一時停止させる時間(秒)
waitTimeForAvoidingPunishment: 60 * 30,
//メール
mail: 'sage',
//名前設定
name: '',
//以下、偽装ワッチョイ設定。浪人でワッチョイを非表示にしてるときだけtrueにしてね。
//妙なニックネーム(ワッチョイ、アウアウウーなど)をランダムで決めて付加するかどうか。true=付加する。false=付加しない。
//妙なニックネームの後に付く8桁の文字列をランダムで決めて付加するかどうか。
},
//アンカー無し投稿をするならtrue。しないならfalse。noAnkerPostかreplyPostのどちらかはtrueにすること(両方trueでもOK)。
//アンカー付き投稿(返信)をするならtrue。しないならfalse。もしnoAnkerPostとreplyPostの両方がtrueの場合、投稿は返信が優先され、返信対象が見つからなくなったらアンカー無し投稿をする。
//最初に取得するアンカー無し投稿文CSVファイルの行番号。もし返信用と同じCSVファイルを使うなら-1と入力。
noAnkerPostTextCsvStartRow: 1,
//最初に取得する返信用投稿文CSVファイルの行番号。もしアンカー無しと同じCSVファイルを使うなら-1と入力。
//テキストCSV/返信用テキストCSVの取得行が最終行に達したら最初の行まで戻るかどうか。true=戻る。false=マクロ終了。
//返信する場合、これより小さなレス番には返信しない。返信を投稿すると、この数値は前回の返信先のレス番に更新される。
minAnker: 895,
//返信する場合、名前に以下の文字列を含む投稿にアンカーをつけて返信する(ワッチョイやIPなど名前フィールドにあるものならなんでも可)。配列で複数指定可能。指定無しなら空配列([])。filterNamesとfilterNamesNotIncluded共に無指定ならレス番1から順に返信していく(minAnkerが設定されてればそこから順に)。以下のfilter系は全て併用可能。
//↑とは逆に、名前に以下の文字列を含まない投稿にアンカーをつけて返信する。↑と併用も可能。
//返信する場合、本文に以下の文字列を含む投稿にアンカーをつけて返信する。
filterText: ['自演かな', '自演わらわら', 'スクリプト使うの', '安価ガバ', '>>660', '自演で擁護', '最後' ,'あいうえお', 'かきくけこ', 'さしすせそ', 'なにぬねの', 'はひふへほ', 'まみむめも', 'やいゆえよ', 'やゆよ', 'らりるれろ', 'わいうえを', 'わをん', 'わいうえをん'],
},
//自分のIPアドレスの確認。VPNとかでIPを変更してマクロを動かしてるとき、突然VPNが作動しなくなってIPが元に戻ったときにマクロを止めるためのもの。
//以下の文字列が自分の現在のIPアドレスに含まれている場合、マクロを一時停止する。基本的に自分の本当のIPアドレスを入力。
},
//浪人設定。最後に動作を確認したのは5年くらい前で、今も同じように動作するかは、浪人を持ってないから確認できずわからない。
//浪人にログインしてるかどうかをチェックするかどうか。trueならする。falseならしない。trueにしていてもし浪人にログインしていないことを確認したらログインしにいく。
password: '1234',
},
};
/**************************************
設定箇所終わり。
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>
/**
* ここから始まる。
*/
checkSettings();
var _TextCsvCursors = new TextCsvCursors(
SETTINGS.postSettings.noAnkerPostTextCsvStartRow > 0
? SETTINGS.postSettings.noAnkerPostTextCsvStartRow - 1
: SETTINGS.postSettings.noAnkerPostTextCsvStartRow,
SETTINGS.postSettings.textCsvLoop,
),
SETTINGS.postSettings.replyPostTextCsvStartRow > 0
? SETTINGS.postSettings.replyPostTextCsvStartRow - 1
: SETTINGS.postSettings.replyPostTextCsvStartRow,
SETTINGS.postSettings.textCsvLoop,
),
);
var _LoopStatuses = new LoopStatuses(0, SETTINGS.postSettings.minAnker);
const _MyPosterName = new MyPosterName({
name: SETTINGS.nameSettings.name,
});
const _ThreadUrl = openPromptThreadUrl();
//ループ
while (true) {
SETTINGS.ipSettings.checkIp && checkCurrentIpNotTheIp();
//スレを開く
openUrl(_ThreadUrl.fullUrlHttps());
//浪人にログインする設定なら、浪人にログインしているかどうかを確認し、していなければログインしにいく。
if (SETTINGS.roninSettings.checkLogin) {
}
}
if (SETTINGS.postSettings.replyPost) {
const targetAnkerNumber = createPostDOMList()
.filterPostnumberHigher(_LoopStatuses.currentMinAnker())
.filterByPostername(SETTINGS.postSettings.filterNames)
.filterByPosternameNotIncluded(
SETTINGS.postSettings.filterNamesNotIncluded,
)
.filterByText(SETTINGS.postSettings.filterText)
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) {
//投稿。
nickname: SETTINGS.nameSettings.nickname,
korokoro: SETTINGS.nameSettings.korokoro,
area: SETTINGS.nameSettings.area,
}),
SETTINGS.mail,
p.text,
);
//_TextCsvCursorsと_LoopStatusesを更新。
_TextCsvCursors = p.updatedTextCsvCursors;
_LoopStatuses = p.updatedLoopStatuses.incrementPostCount();
`投稿回数: ${_LoopStatuses.currentPostCount()}`,
`minAnker: ${_LoopStatuses.currentMinAnker()}`,
`今回アンカー無し投稿取得行: ${_TextCsvCursors.currentRows().noAnker}`,
`今回アンカー有り投稿取得行: ${_TextCsvCursors.currentRows().reply}`,
]);
} else {
`返信対象が現われるのを待機中...。`,
`投稿回数: ${_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 メール
*/
serverName,
postMail,
_MyText,
retryTimes = 0,
) {
const r =
retryTimes === 0
? new ValuesOfPost(serverName, _MyPosterName, postMail, _MyText).post(
postTo5chTread,
)
serverName,
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();
serverName,
postMail,
_MyText,
retryTimes + 1,
);
} else if (error.order === 'WAIT') {
wait(SETTINGS.waitTimeForAvoidingPunishment);
serverName,
postMail,
_MyText,
retryTimes,
);
} else if (error.order === 'LOGIN') {
serverName,
postMail,
_MyText,
retryTimes,
);
}
return;
}
/**
* 現在のIPアドレスに、SETTINGS.ipSettings.avoidTheIpの値が含まれていないことを確認する。含まれていたらマクロを一時停止。
* @returns
*/
function checkCurrentIpNotTheIp() {
openUrl('https://www.cman.jp/network/support/go_access.cgi');
const _IpAdress = createIpAdressFromCMan();
if (_IpAdress.includes(SETTINGS.ipSettings.avoidTheIp)) {
pause('現在のIPに指定した値が含まれていることを確認。');
}
return;
}
/**
* @returns
*/
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を受け取る。
*/
function openPromptThreadUrl() {
const url = prompt('スレURLを入力');
}
/**
* 開いてるスレのレス全て読み取ってPostListインスタンスを作って返す。
* 重すぎるので使うのやめ。どうやらインスタンスの大量生成が原因な模様。
*/
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');
for (let index = 0; index < posts.length; index++) {
//HTMLCollectionからElementを1つずつ抽出して配列に。
arrPostDOMList.push(posts.item(index));
}
return new PostDOMList(arrPostDOMList);
}
/**
* 開いてる投稿結果画面に表示されてるエラーを読み取ってPostErrorMessageインスタンスを作って返す。
*/
function createPostErrorMessage() {
window.document