20211125のJavaScriptに関する記事は26件です。

JSでCSV操作

JavaScriptで CSVをDTOに csv→dto.js // CSVをDTOのListに直す let csvToDto = (csv) => { let rows = csv.split("\r\n"); let header = rows[0].split(","); let records = []; for (let i = 1; i < rows.length; i++) { let row = {}; rows[i].split(",").forEach((val, index) => { row[header[index]] = val; }); records[i - 1] = row; } return records; }; DTOをCSVに dto→csv.js // DTOのListをCSVに直す let dtoToCsv = (list) => { console.log(list); let csv = Object.keys(list[0]).join(",") + "\r\n"; list.forEach((dto) => { csv += Object.values(dto).join(",") + "\r\n"; }); return csv; };
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ブラウザとROSの通信

はじめに ブラウザとROSの通信方法をまとめます!!! 環境 ros noetic ubuntu 20.04 準備 1.rosbridge_bridgeサーバーのインストール sudo apt-get install ros-noetic-rosbridge-server 2.ブラウザプログラムの準備 2.1 ブラウザディレクトリ作成 mkdir webpages cd webpages 2.2 ブラウザプログラム index.htmlの作成し,roslibjs/exmaple/simple.htmlをコピーしroslibjsのインポートパスを変更 webpages/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script> <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script> <script> // Connecting to ROS // ----------------- var ros = new ROSLIB.Ros(); // If there is an error on the backend, an 'error' emit will be emitted. ros.on('error', function(error) { document.getElementById('connecting').style.display = 'none'; document.getElementById('connected').style.display = 'none'; document.getElementById('closed').style.display = 'none'; document.getElementById('error').style.display = 'inline'; console.log(error); }); // Find out exactly when we made a connection. ros.on('connection', function() { console.log('Connection made!'); document.getElementById('connecting').style.display = 'none'; document.getElementById('error').style.display = 'none'; document.getElementById('closed').style.display = 'none'; document.getElementById('connected').style.display = 'inline'; }); ros.on('close', function() { console.log('Connection closed.'); document.getElementById('connecting').style.display = 'none'; document.getElementById('connected').style.display = 'none'; document.getElementById('closed').style.display = 'inline'; }); // Create a connection to the rosbridge WebSocket server. ros.connect('ws://localhost:9090'); // Publishing a Topic // ------------------ // First, we create a Topic object with details of the topic's name and message type. var cmdVel = new ROSLIB.Topic({ ros : ros, name : '/cmd_vel', messageType : 'geometry_msgs/Twist' }); // Then we create the payload to be published. The object we pass in to ros.Message matches the // fields defined in the geometry_msgs/Twist.msg definition. var twist = new ROSLIB.Message({ linear : { x : 0.1, y : 0.2, z : 0.3 }, angular : { x : -0.1, y : -0.2, z : -0.3 } }); // And finally, publish. cmdVel.publish(twist); //Subscribing to a Topic //---------------------- // Like when publishing a topic, we first create a Topic object with details of the topic's name // and message type. Note that we can call publish or subscribe on the same topic object. var listener = new ROSLIB.Topic({ ros : ros, name : '/listener', messageType : 'std_msgs/String' }); // Then we add a callback to be called every time a message is published on this topic. listener.subscribe(function(message) { console.log('Received message on ' + listener.name + ': ' + message.data); // If desired, we can unsubscribe from the topic as well. listener.unsubscribe(); }); // Calling a service // ----------------- // First, we create a Service client with details of the service's name and service type. var addTwoIntsClient = new ROSLIB.Service({ ros : ros, name : '/add_two_ints', serviceType : 'rospy_tutorials/AddTwoInts' }); // Then we create a Service Request. The object we pass in to ROSLIB.ServiceRequest matches the // fields defined in the rospy_tutorials AddTwoInts.srv file. var request = new ROSLIB.ServiceRequest({ a : 1, b : 2 }); // Finally, we call the /add_two_ints service and get back the results in the callback. The result // is a ROSLIB.ServiceResponse object. addTwoIntsClient.callService(request, function(result) { console.log('Result for service call on ' + addTwoIntsClient.name + ': ' + result.sum); }); // Advertising a Service // --------------------- // The Service object does double duty for both calling and advertising services var setBoolServer = new ROSLIB.Service({ ros : ros, name : '/set_bool', serviceType : 'std_srvs/SetBool' }); // Use the advertise() method to indicate that we want to provide this service setBoolServer.advertise(function(request, response) { console.log('Received service request on ' + setBoolServer.name + ': ' + request.data); response['success'] = true; response['message'] = 'Set successfully'; return true; }); // Setting a param value // --------------------- ros.getParams(function(params) { console.log(params); }); // First, we create a Param object with the name of the param. var maxVelX = new ROSLIB.Param({ ros : ros, name : 'max_vel_y' }); //Then we set the value of the param, which is sent to the ROS Parameter Server. maxVelX.set(0.8); maxVelX.get(function(value) { console.log('MAX VAL: ' + value); }); // Getting a param value // --------------------- var favoriteColor = new ROSLIB.Param({ ros : ros, name : 'favorite_color' }); favoriteColor.set('red'); favoriteColor.get(function(value) { console.log('My robot\'s favorite color is ' + value); }); </script> </head> <body> <h1>Simple roslib Example</h1> <p>Run the following commands in the terminal then refresh this page. Check the JavaScript console for the output.</p> <ol> <li><tt>roscore</tt></li> <li><tt>rostopic pub /listener std_msgs/String "Hello, World"</tt></li> <li><tt>rostopic echo /cmd_vel</tt></li> <li><tt>rosrun rospy_tutorials add_two_ints_server</tt></li> <li><tt>roslaunch rosbridge_server rosbridge_websocket.launch</tt></li> </ol> <div id="statusIndicator"> <p id="connecting"> Connecting to rosbridge... </p> <p id="connected" style="color:#00D600; display:none"> Connected </p> <p id="error" style="color:#FF0000; display:none"> Error in the backend! </p> <p id="closed" style="display:none"> Connection closed. </p> </div> </body> </html> ※ プログラムのROSインタフェースまとめ Topic Pub: /cmd_vel(geometry_msgs/Twist) Topic Sub: /listener(std_msgs/String) Service Advertise: /set_bool(std_srvs/SetBool) Service Call: /add_two_ints(rospy_tutorials/AddTwoInts) Set Param: max_vel_y Get Param: favorite_color 実行 1.rosbridge_server起動 roslaunch rosbridge_server rosbridge_websocket.launch 2.ブラウザプログラム起動 cd webpages python3 -m http.esrver 3.ブラウザ起動 http://0.0.0.0:8000/ にアクセス ブラウザ <=> ROSの通信確認 1.ブラウザからのPublish 1.topic受信コマンド実行 rostopic echo /cmd_vel 2.ブラウザをリロード ※値がechoされる 2.ブラウザでSubscribe 1.ブラウザのデバッグコンソールを開く 2.ブラウザにパブリッシュ rostopic pub /listener std_msgs/String "data: 'aaaaa'" ※コンソールで送られた値を見れる 3.ブラウザのros service server 1.ブラウザのデバッグコンソールを開く 2.サービスコールを実行 rosservice call /set_bool "data: false" ※コンソールで送られた値を見れる 4.ブラウザのros service client 1.サーバープログラムインストール sudo apt install ros-noetic-rospy-tutorials 2.サーバーを起動 rosrun rospy_tutorials add_two_ints_server 3.ブラウザリロード ※サーバープログラムが値を受信したのを確認できる ※rossrv show rospy_tutorials/AddTwoIntsで見つからない場合ブラウザプログラムもこの型を使えないのでインストールする 参考 ROS画像をブラウザに送信 roslibjsまとめ(roslibjsでrosserviceをwaitする方法も乗っている)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ブラウザとROS 通信

1.はじめに ブラウザとROSの通信方法をまとめます!!! 2.環境 ros noetic ubuntu 20.04 3.準備 1.rosbridge_serverのインストール sudo apt-get install ros-noetic-rosbridge-server 2.ブラウザプログラムの準備 2.1 ブラウザ用ディレクトリ作成 mkdir webpages cd webpages 2.2 ブラウザプログラム index.htmlの作成し,roslibjs/exmaple/simple.htmlをコピーする. (roslibjsのインポートパスは変更が必要) webpages/index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script> <script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script> <script> // Connecting to ROS // ----------------- var ros = new ROSLIB.Ros(); // If there is an error on the backend, an 'error' emit will be emitted. ros.on('error', function(error) { document.getElementById('connecting').style.display = 'none'; document.getElementById('connected').style.display = 'none'; document.getElementById('closed').style.display = 'none'; document.getElementById('error').style.display = 'inline'; console.log(error); }); // Find out exactly when we made a connection. ros.on('connection', function() { console.log('Connection made!'); document.getElementById('connecting').style.display = 'none'; document.getElementById('error').style.display = 'none'; document.getElementById('closed').style.display = 'none'; document.getElementById('connected').style.display = 'inline'; }); ros.on('close', function() { console.log('Connection closed.'); document.getElementById('connecting').style.display = 'none'; document.getElementById('connected').style.display = 'none'; document.getElementById('closed').style.display = 'inline'; }); // Create a connection to the rosbridge WebSocket server. ros.connect('ws://localhost:9090'); // Publishing a Topic // ------------------ // First, we create a Topic object with details of the topic's name and message type. var cmdVel = new ROSLIB.Topic({ ros : ros, name : '/cmd_vel', messageType : 'geometry_msgs/Twist' }); // Then we create the payload to be published. The object we pass in to ros.Message matches the // fields defined in the geometry_msgs/Twist.msg definition. var twist = new ROSLIB.Message({ linear : { x : 0.1, y : 0.2, z : 0.3 }, angular : { x : -0.1, y : -0.2, z : -0.3 } }); // And finally, publish. cmdVel.publish(twist); //Subscribing to a Topic //---------------------- // Like when publishing a topic, we first create a Topic object with details of the topic's name // and message type. Note that we can call publish or subscribe on the same topic object. var listener = new ROSLIB.Topic({ ros : ros, name : '/listener', messageType : 'std_msgs/String' }); // Then we add a callback to be called every time a message is published on this topic. listener.subscribe(function(message) { console.log('Received message on ' + listener.name + ': ' + message.data); // If desired, we can unsubscribe from the topic as well. listener.unsubscribe(); }); // Calling a service // ----------------- // First, we create a Service client with details of the service's name and service type. var addTwoIntsClient = new ROSLIB.Service({ ros : ros, name : '/add_two_ints', serviceType : 'rospy_tutorials/AddTwoInts' }); // Then we create a Service Request. The object we pass in to ROSLIB.ServiceRequest matches the // fields defined in the rospy_tutorials AddTwoInts.srv file. var request = new ROSLIB.ServiceRequest({ a : 1, b : 2 }); // Finally, we call the /add_two_ints service and get back the results in the callback. The result // is a ROSLIB.ServiceResponse object. addTwoIntsClient.callService(request, function(result) { console.log('Result for service call on ' + addTwoIntsClient.name + ': ' + result.sum); }); // Advertising a Service // --------------------- // The Service object does double duty for both calling and advertising services var setBoolServer = new ROSLIB.Service({ ros : ros, name : '/set_bool', serviceType : 'std_srvs/SetBool' }); // Use the advertise() method to indicate that we want to provide this service setBoolServer.advertise(function(request, response) { console.log('Received service request on ' + setBoolServer.name + ': ' + request.data); response['success'] = true; response['message'] = 'Set successfully'; return true; }); // Setting a param value // --------------------- ros.getParams(function(params) { console.log(params); }); // First, we create a Param object with the name of the param. var maxVelX = new ROSLIB.Param({ ros : ros, name : 'max_vel_y' }); //Then we set the value of the param, which is sent to the ROS Parameter Server. maxVelX.set(0.8); maxVelX.get(function(value) { console.log('MAX VAL: ' + value); }); // Getting a param value // --------------------- var favoriteColor = new ROSLIB.Param({ ros : ros, name : 'favorite_color' }); favoriteColor.set('red'); favoriteColor.get(function(value) { console.log('My robot\'s favorite color is ' + value); }); </script> </head> <body> <h1>Simple roslib Example</h1> <p>Run the following commands in the terminal then refresh this page. Check the JavaScript console for the output.</p> <ol> <li><tt>roscore</tt></li> <li><tt>rostopic pub /listener std_msgs/String "Hello, World"</tt></li> <li><tt>rostopic echo /cmd_vel</tt></li> <li><tt>rosrun rospy_tutorials add_two_ints_server</tt></li> <li><tt>roslaunch rosbridge_server rosbridge_websocket.launch</tt></li> </ol> <div id="statusIndicator"> <p id="connecting"> Connecting to rosbridge... </p> <p id="connected" style="color:#00D600; display:none"> Connected </p> <p id="error" style="color:#FF0000; display:none"> Error in the backend! </p> <p id="closed" style="display:none"> Connection closed. </p> </div> </body> </html> ※ プログラムのROSインタフェースまとめ Topic Pub: /cmd_vel(geometry_msgs/Twist) Topic Sub: /listener(std_msgs/String) Service Advertise: /set_bool(std_srvs/SetBool) Service Call: /add_two_ints(rospy_tutorials/AddTwoInts) Set Param: max_vel_y Get Param: favorite_color 4.実行 1.rosbridge_server起動 roslaunch rosbridge_server rosbridge_websocket.launch 2.ブラウザプログラム起動 cd webpages python3 -m http.esrver 3.ブラウザ起動 http://0.0.0.0:8000/ にアクセス 5.ブラウザ-ROSの疎通確認 5.1 Publisher 1.topic受信コマンド実行 rostopic echo /cmd_vel 2.ブラウザをリロード ※値がechoされる 5.2 Subscriber 1.ブラウザのデバッグコンソールを開く 2.ブラウザにパブリッシュ rostopic pub /listener std_msgs/String "data: 'aaaaa'" ※コンソールで送られた値を見れる 5.3 Service Server 1.ブラウザのデバッグコンソールを開く 2.サービスコールを実行 rosservice call /set_bool "data: false" ※コンソールで送られた値を見れる 5.4 Service Client 1.サーバープログラムインストール sudo apt install ros-noetic-rospy-tutorials 2.サーバーを起動 rosrun rospy_tutorials add_two_ints_server 3.ブラウザリロード ※サーバープログラムが値を受信したのを確認できる ※rossrv show rospy_tutorials/AddTwoIntsで見つからない場合ブラウザプログラムもこの型を使えないのでインストールする 6.参考 ROS画像をブラウザに送信 roslibjsまとめ(roslibjsでrosserviceをwaitする方法も乗っている)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TypeScriptメモ 〜オブジェクト編〜

ファクトリ関数 値を生成するための関数。 同じ形式のオブジェクトを何回も作れる。 function Person(n:string, a: number) { return { name: n, age: a, print: function(){ console.log(this.name) console.log(this.age) } } } オブジェクトの分割代入 type person = { name: { first: string, second: string }, age: number } const foo:person = { name: { first: 'foo', second: 'bar' }, age: 20 } const { name: { first, second }, age } = foo クラス class Person { name: string = 'default' email?: string age?: number print(): void { // 何らかの処理 } } インスタンスのクラスを調べる インスタンス instanceof クラス // boolean インスタンスのクラス名を得る インスタンス.constructor.name 継承 class Person {...} class Student extends Person {} アクセス修飾子 プロパティのアクセスを制限する時に 修飾子 説明 public 外部から自由にアクセス可 protected クラスと継承クラスからアクセス可 private クラス内のみアクセス可 setterとgetter 「直接アクセスされては困るが、完全にアクセスできないのも困る」という時に。 private+setter/getterという使い方が一般的 class Person { private age: number get getAge():number { return this.age } set setAge(n:number) { this.age = n } } インターフェイス クラスの構造の定義をするためのもの。 インターフェイスで定義したプロパティをクラスは用意しなければならない。 enum School { junior = 'junior', juniorHigh = 'juniorHigh', high = 'high' } interface Human { name: string print(): void } class Person implements Human { name: string = 'no-name' mail: string age: number constructor(name: string, mail: string = 'no-mail', age: number = -1) { this.name = name this.mail = mail this.age = age } print():void { console.log(this.name) console.log(this.mail) console.log(this.age) } } class Student implements Human { name: string = 'no-name' school: School grade?: number constructor(name: string, school?: School, grade?: number) { this.name = name this.school = school this.grade = grade } print():void { console.log(this.name) console.log(this.school) console.log(this.grade) } } 利点としては継承関係にないインスタンスをインターフェイスによってまとめられる const taro: Person = new Person('taro', 'taro@yamada', 20) const hanako: Student = new Student('hanako', School.high, 2) const sachiko: Person = new Person('sachiko') const jiro: Student = new Student('jiro', School.high) const data:Human[] = [taro, hanako, sachiko, jiro] インターフェイスの継承 interface People extends Human {...} 抽象クラス interface同様クラスにメソッドを用意するために使用。ただし、抽象クラスに用意される抽象メソッドは実装がないため継承しても使えない。 abstract class Human { abstract print(): void } class Person extends Human {...} class Student extends Human {...} 抽象クラスとインターフェイスの違い 他にクラスを継承するか? 他のクラスを継承するのであれば、抽象クラスは使用できない プロパティを義務付ける必要があるか? 抽象クラスは基本的に「メソッド」を定義するもの。 実装クラスに必ずプロパティをもたせたいなら、インターフェイスを使用 protectedか、publicか? インターフェイスはpublicなメソッドを定義。protectedメソッドは使えない。 静的メンバー インスタンスを作る必要がないクラス。クラスのプロパティやメソッドを静的メンバーとしてまとめる。 class StaticHuman { static fullname:string // nameは予約語なので使用できない! static age:number static set(nm:string, age:number):void { this.fullname = nm this.age = age } static print():void { console.log(this.fullname) console.log(this.age) } } StaticHuman.set('taro', 40) StaticHuman.print() StaticHuman.set('foo', 20) StaticHuman.print() パラメータプロパティ readonlyを使用。読み取り専用のプロパティを使用できる class Human { constructor(readonly name:string, readonly age:number) {} } 総称型の利用 class Data<T> { data?:T[] constructor(...item:T[]) { this.data = item } print():void { if (this.data) { for(let item of this.data) { console.log(item) } } else { console.log('no data...') } } } const data1 = new Data<string>('one', 'two', 'three') const data2 = new Data<number>(1, 2, 3) ユーティリティ型 ここでは、Requiredというユーティリティ型を使用している。これにより、Personのhumanプロパティではname, mail, ageのすべての値が必須になる。 type Human = { name:string mail?:string age?:number } class Person { human:Required<Human> constructor(nm:string, ml:string, ag:number) { this.human = { name:nm, mail:ml, age:ag } } print():void { console.log(this.human) } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

変数とは何か、わかりやすく解説してみた【OBGノウハウ】

どのプログラミング言語を学んでいる上でも絶対必要となる知識がいくつかあると思うのですが、今回は初歩の初歩!変数について私なりの解釈と講習会で使用している説明でのたとえ話なんかをまとめてみました! RPAツールやpythonやjs……どの言語を触っていても必ず付いてくるものですが、逆に言うと理解さえしてしまえば別の言語を触る時にも「アッ……これ、○○でやったやつだ……!」と役に立つ基礎がいくつかあると思っております。 その中で今回は、変数についてまとめてみました! ※今回、変数って何…?というプログラミングにこれから一歩を踏み出すぞ!という方向けに、「変数の概念が何となくわかった気になる」「変数コワクナイ!変数大事!(・∀・)」と思って貰えることを目的として記事を作成しております。 あえて抽象度を高めにしている例え話を用いております。 変数とは何か 変数とは、データを入れるための箱です。 また、箱には「型」と呼ばれる種類が存在します。 日常生活の中でも、「入れ物」に「中身」をいれることってありますよね。 引っ越しの荷造りだったり、ペットボトルに飲み物を入れたり、スーパーのカゴに食材をいれたり……。 例えば、宅配便が届いたとします。 箱の外側に貼られている伝票には「品名:食品」……丁度お腹もすいたし、何が入っているかな~! \パカッ!/ わぁ!あったかそうな毛布が出て来た~! ……なんでやねんっ……!毛布は食べられないわ! 例えば、食事の時。 お茶碗の中に味噌汁が、マグカップの中にほかほかの白米がよそられて提供されました。 ……なんでやねんっ……!(2回目) 何が言いたいかと言いますと、入れ物と中身が一致していないと戸惑っちゃいますよねって話です。 我々人間でさえ戸惑うのですから、より繊細なプログラミング言語はもっと戸惑ってしまいます。 変数を扱う際には型の概念が必須事項になります。具体的な型の名称や種類については後述します! 変数があることのメリット さて、変数=データを入れるための箱、と言うのは理解頂けたかと思います。 じゃあプログラミングをする上で、なぜ変数という型が必要なの?という解説をしていきます。 突然ですがここでまた、例え話をしていきます。 まず、カレーを作るプログラムを作りたいとします。 今回のカレーに使用する材料はじゃがいも、ニンジン、玉ねぎ、鶏肉だとします。 カレーを作るプロセスを大まかに書き出すと、こんな感じでしょうか。 細かい作業は色々ありますが、今回はあえて省いております。 この状態でも確かにカレーは作れますが、色々と不便な場所があります。 汎用性の向上 例えば、今日はカレーの気分じゃないんだよな、肉じゃがが食べたい……。そう思った時に変数を用いていないと、肉じゃがのプログラムを1から作らなければいけません。 もしくは2から4の「じゃがいも、ニンジン、玉ねぎ、鶏肉」をすべて「じゃがいも、ニンジン、玉ねぎ、牛肉、しらたき、しいたけ」と変えなければいけません。ちょっと面倒ですし、我々人間はどうしてもうっかりしてしまう生き物なので変更漏れが出てしまうかもしれません。 そんな時に便利なのが変数です!まずはカレーのプログラムの、1から4のプロセスに1つ追加をして、変数「材料」を使用して書き換えてみます。 ※関数・オブジェクト指向での解決は今回考えておりません。変数の使い方だけに焦点を絞っています。 そして、肉じゃがが食べたい……と思ったら、「1.材料=じゃがいも、ニンジン、玉ねぎ、鶏肉とする」の部分を「1.材料=じゃがいも、ニンジン、玉ねぎ、牛肉、しらたき、しいたけとする」とだけ変えてしまえば良いわけです。 メンテナンス性の向上 扱う材料の内容がカレーの材料から肉じゃがの材料に変更になった……など、データの変更があった際はステップ1の部分だけを変更すればいいのでメンテナンス性も向上しますし、変更漏れの可能性を低くすることも出来ます。 可読性の向上 変数の名前に一目で見て内容が察することが出来るような名前を付けておけば、コードの解読も容易になり可読性が一気に向上します。 変数の命名には規則があるので、それについてはまた後日、詳しく解説していきます。 変数(データ)の型について さて、変数が便利な事は伝わったかと思います! 繰り返しにはなりますが、変数はデータを入れる為の入れ物になります。日常生活で周りを見まわした際に段ボール、カゴ、お茶碗、タンブラーなどなど……色んな種類の入れ物があると思います。そしてその入れ物に適したものを入れる必要があると冒頭でも記述しました。この入れ物の種類の事を「変数の型」と言います。 ここでは代表的な型を紹介していきます。 取り扱えるデータの種類はどの言語も大体同じですが、表記が異なる場合があります。 今回はpythonとUiPathに焦点を当てていこうかと思います。 ちなみに、pythonは変数に値を入力すると自動で型が判定されます。 UiPathに関しては変数の作成方法によって自動で判定されるものもありますが、基本的には自分で変数を作成した際には自分で型を設定する必要があります。 文字列を扱う str型(python) 変数名 = ‘ オブジェクティブグループ ’ ; string(UiPath) 変数名 = “ オブジェクティブグループ “ 数字を扱う 整数 int型(python) 変数名 = 123 ; int32(UiPath) 変数名= 123 小数 float型(python) 変数名= 1.234 ; double(UiPath) 変数名= 1.234 真(true)か偽(false)を扱う bool型(python) 変数名 = True ;(もしくはfalse) boolean(UiPath) 変数名= True(もしくはfalse) 複数のデータを扱う list型(python) 変数名 = [ ‘ apple ’ , ‘ orange ’ , ‘ banana ’ , ‘ peach ’ ] ; tuple型(python) 変数名 = ( ‘ apple ’ , ‘ orange ’ , ‘ banana ’ , ‘ peache ’ ) ; dictionary型(python) 変数名 = { ‘ fruit ’ : ‘ apple ’ ,’ ID ’ : ‘ 001 ’ , ‘ name ’ : ‘ tochiotome ’ } ; Array of [ T ](UiPath) 変数名= { “ apple” , “ orange “ , “ banana ” , “ peach “ } ※変数名(数字)で何番目のデータを表示が出来る UiPath独自の型 Data Table = ExcelやCSVからデータを読み込みしたり、書き込みしたりする際に使用する Generic Value = 文字列型と数値型など複数の型を持つことができる超チート型。困ったらとりあえずGeneric Valueを使っておけばイケる……かと思いきや、チートだからこそエラーの原因になることも。こいつだけ使えればOKという訳ではない…。 変数の宣言の仕方は言語によって異なるので、自分がよく触る言語の変数の仕方については手を動かしている内に身についてくるかと思います。 次回は変数の命名についてもまとめてみたいと思います!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【javascript】非同期処理

前提知識 ブラウザとスレッド 連続して実行される一本の処理の流れ。 処理A 処理B 処理C ブラウザのjavascriptに関わるスレッド 1. Main Thread > JavaScriptが関わるスレッド 1. Service Worker 1. Web Worker メインスレッド(Main Thread) JavaScriptの実行とレンダリング(画面描写処理)を行う。 javascript => レンダリング FPS(Flames Per Second) 1秒間あたりの画面(フレーム)更新頻度 1秒間に60回画面更新 => 60fps = 16.7秒に1回画面更新されている。 重い処理があると画面が更新されなくなる。 JavaScript側で16.7ms以上かかる処理のケース 同期処理と非同期処理 同期処理 メインスレッドでコードが順番に実行される。 1つの処理が完了するまで、次の処理には進まない。 重い処理があった場合は、処理が完了するまで次の処理に進まない。 case 3秒後に実行されるsleep関数を用意 ブラウザーをロードした時に3秒後にsleep doneが表示される。 その後button clickedがレンダリングされコンソール状に表示されるようになる。 3秒間中にボタンを何回押しても'button clicked'が表示されないことに注目したい。 かならず、sleep doneが表示された後にbutton clickedが表示される。 すなわち、javascriptのスレッドが処理されている時には次の処理(レンダリング)がされていないことがわかる。 function sleep(ms) { const startTime = new Date(); while (new Date() - startTime < ms); console.log('sleep done'); } const btn = document.querySelector('button'); btn.addEventListener('click', function(){ console.log('button clicked'); }); sleep(3000); case2(非同期処理) webAPIのsetTimeoutを使用して2秒後にsleep関数を実行する。 sleep関数を実行するまでの2秒間にボタンを押す。 >>> button clickedが表示される。 3秒後にsleep done またその後にボタンを押すとbutton clickedが表示される。 setTimeoutはjavascriptが占有するメインスレッドを解放されレンダリングが先に実行される。 そして、3秒後にjavascriptがメインスレッドを占有しsleep doneを表示する。 すなわち、非同期処理とはjavascriptが一時的にメインスレッドから処理の解放されている時に実行されること function sleep(ms) { const startTime = new Date(); while (new Date() - startTime < ms); console.log('sleep done'); } const btn = document.querySelector('button'); btn.addEventListener('click', function(){ console.log('button clicked'); }); setTimeout(function(){ sleep(3000) },2000) 非同期APIの例 setTimeout Promise queueMicrotask etc... UIイベントではクリックなども非同期として渡すことができる。 そのほか、NWイベント、i/oイベントなどがある。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3.0 + Vite + Cropperjs

はじめに 前回の記事でVue3.0でCropperjsを使用する方法をまとめました。今回はビルド高速化の為にこれにViteを使った方法を記載します。 方法 1.パッケージの作成 + Viteのインストール + cropperjsのインストール vue create aaaaa cd aaaaa npm init vite-app vue-todo-list cd vue-todo-list npm install npm install cropperjs 2.vue-todo-list/src/App.vueを書き換える vue-todo-list/src/App.vue <template> <img ref="cropImg" alt="Vue logo" src="./assets/logo.png" /> <HelloWorld msg="Hello Vue 3.0 + Vite + Cropperjs" /> </template> <script> import HelloWorld from './components/HelloWorld.vue' import Cropper from 'cropperjs'; import "cropperjs/dist/cropper.css"; export default { name: 'App', components: { HelloWorld }, mounted() { this.cropper = new Cropper(this.$refs.cropImg, { background: false, modal: false, highlight: false, viewMode: 1 }); }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 3.実行 npm run dev 4.結果は以下のようになります 環境 ubuntu20.04 参考 Viteの使用方法: https://qiita.com/Toshiaki0315/items/1ab4e479007bb0f76f06
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】非同期処理⑨ 例外処理とエラー

はじめに Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。 前回の記事 目的 非同期処理についての理解を深める 本題 1.例外処理とエラー 例外処理とはなにかエラーが発生した際に飛ぶ特別な処理のこと 基本構文 try{ throw new Error(); } catch(e) { // エラーハンドリング } finally { // 終了処理 } 例1 基本的な使い方 main.js // 動かしたいコードをtryの中に記述していく try{ console.log("start"); // エラーを出力する → catchに移行する throw new Error("error message"); // 上記で処理がcatchに移行するので下記endは出力されない console.log("end") } catch(e) { console.error(e); } finally { // 出力される終了処理 console.log('bye'); } 上記の出力結果は以下の通り console. start > Error: error message at main.js:5 bye 例2 さらに実践的な使い方 前提 jsonファイルからデータを引っ張ってくるがあえてここではからにしておく(エラーを出すため) user.json [ ] main.js async function fetchUsers() { const response = await fetch('users.json'); const json = await response.json(); return json; } async function init(){ const users = await fetchUsers(); for(const user of users) { console.log(`I'm ${user.name}, ${user.age} years old`) } } init(); user.jsonファイルが空欄なので何も出力されていないが、ここにエラーを表示する async function fetchUsers() { const response = await fetch('users.json'); // 条件分岐でデータがうまく渡っている場合そうでない場合で分ける if (response.ok){ const json = await response.json(); // ここでjsonファイルが0だった場合にthrowでエラー処理をcatchに移行したい // jsonファイルのlength(配列の長さ)が0だった場合falseなので!演算子でtrueにする if(!json.length){ throw new Error("no data found") } return json; } } async function init(){ // 上記の内容をtryで捌く try { const users = await fetchUsers(); for(const user of users) { console.log(`I'm ${user.name}, ${user.age} years old`) } }catch(e){ // ここでthrowを受けることでno data foundとエラー表示される console.error(e); }finally{ // 終了処理はどちらにせよ出力される console.log('bye'); } } init(); 例3 カスタムエラーに関して async function fetchUsers() { const response = await fetch('users.json'); if (response.ok){ const json = await response.json(); if(!json.length){ // ここでNoDataErrorを出力できるようにする throw new NoDataError("no data found") } return json; } } // Errorを継承 // 条件分岐でエラーを出力したい場合に行う class NoDataError extends Error { constructor(message){ super(message); this.name = `NoDataError`; } } async function init(){ try { const users = await fetchUsers(); for(const user of users) { console.log(`I'm ${user.name}, ${user.age} years old`) } }catch(e){ console.error(e); }finally{ console.log('bye'); } } init(); 今日はここまで! 参考にさせて頂いた記事 【JS】ガチで学びたい人のためのJavaScriptメカニズム Let'sプログラミング JavaScript入門
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

InDesign用連続置換スクリプト(プログレスバー付き)

『InDesignのスクリプト配給所』からいただいた 「連続文字置換用スクリプト.jsx」から古いバージョン用のコードを外し、 『Adobe Support Community』 の記事「Progress bar script running」 から willcampbell7さんの例を組み込んでみた。 連続置換.jsx /* 置換設定ファイルを読み込んで連続置換するスクリプト(新字→旧字等の文字置換用) 置換設定ファイルはTab区切りテキストで 検索文字列 置換文字列 字形 OpenTypeFeatures の形になっていること。 例 卿 卿 エキスパート字形 逢 逢 なし ["jp04",1] 龍 龍 なし ["aalt",3] based on 2008.12.17 by MishimaBaikamo http://www4.tokai.or.jp/high-sea-fleet/ 置換設定ファイルのエンコーディングはUTF-16にしておく(サロゲートペアの問題を避けるため) */ main(); function main(){ //var filename = File.openDialog("開く置換設定ファイルを指定してください","ChangeTextTable.txt"); var filename = "~/Dropbox/置換表/常用漢字・拡張新字体→旧字体.txt"; if (filename){ var fileObj = new File(filename); if (fileObj.open("r")){ var ctTable = new Array(); try { for (var i = 0; !fileObj.eof; i++) ctTable[i] = fileObj.readln(); } catch(e) { alert("ファイルの読み込みに失敗しました。"); return; } fileObj.close(); } else { alert("ファイルを開けませんでした。"); return; } //var range = app.activeDocument; //置換範囲はドキュメント全体 //var range = app.selection[0].parentStory; //置換範囲は文字キャレットのある親ストーリー var range = app.selection[0]; //置換範囲は選択範囲のみ // 検索・置換機能を使用するので、それらを退避しておく var findTextPreferencesOld = app.findTextPreferences.properties; var changeTextPreferencesOld = app.changeTextPreferences.properties; var findChangeTextOptionsOld = app.findChangeTextOptions.properties; app.findTextPreferences = 1851876449; //NothingEnum.nothing; app.changeTextPreferences = 1851876449; //NothingEnum.nothing; app.findChangeTextOptions = 1851876449; //NothingEnum.nothing; //プログレスバーを表示しながら置換していく var steps = ctTable.length; progress(steps); for (var i = 0; i < steps; i++) { progress.message("置換中 " + i); //置換手続き changeTextFunction(ctTable[i],range); progress.increment(); } // All done. progress.close(); /* for (var i = 0, len = ctTable.length; i < len; i++){ //進行状況をコンソールに表示する var j = i +1; if (j %10 == 0){ $.writeln(j +"/"+ len +", "+ ctTable[i]); } //置換手続き changeTextFunction(ctTable[i],range); } */ // 退避しておいた検索・置換の設定を復帰 app.findTextPreferences.properties = findTextPreferencesOld; app.changeTextPreferences.properties = changeTextPreferencesOld; app.findChangeTextOptions.properties = findChangeTextOptionsOld; if (app.findTextPreferences.kerningMethod=="None") app.findTextPreferences.kerningMethod = 1851876449; if (app.changeTextPreferences.kerningMethod=="None") app.changeTextPreferences.kerningMethod = 1851876449; } else { alert("キャンセルされました。"); return; } } function changeTextFunction(ctTable,range){ TAB = String.fromCharCode(0x0009); //タブ var ct = ctTable.split(TAB); app.findTextPreferences.findWhat = ct[0]; app.changeTextPreferences.changeTo = ct[1]; app.changeTextPreferences.glyphForm = glyphFormFunction(ct[2]); //置換済み箇所に文字色を付ける場合はあらかじめスウォッチをつくっておく必要がある app.changeTextPreferences.fillColor = "旧字体に変換"; var replace_Texts = range.changeText(); if (ct[3] != "" && ct[3] != undefined){ for (var j=0; j<replace_Texts.length; j++){ replace_Texts[j].opentypeFeatures = eval("["+ct[3]+"]"); } } } function glyphFormFunction(str){ switch (str){ case "ExpertForm": case "エキスパート字形": return 1247897445; //AlternateGlyphForms.EXPERT_FORM case "等幅全角字形": return 1247897446; //AlternateGlyphForms.FULL_WIDTH_FORM case "JIS2004字形": case "JIS 2004 字形": case "JIS 04 字形": case "JIS04字形": return 1247897396; //AlternateGlyphForms.JIS04_FORM case "JIS78Form": case "JIS 78 字形": case "JIS78字形": return 1247897399; //AlternateGlyphForms.JIS78_FORM case "JIS 83 字形": case "JIS83字形": return 1247897400; //AlternateGlyphForms.JIS83_FORM case "JIS 90 字形": case "JIS90字形": return 1247897401; //AlternateGlyphForms.JIS90_FORM case "等幅半角字形": return 1247897453; //AlternateGlyphForms.MONOSPACED_HALF_WIDTH_FORM case "印刷標準字形": return 1247897454; //AlternateGlyphForms.NLC_FORM case "NLCForm": case "標準字形": case "標準字形に戻す": case "なし": return 1852796517; //AlternateGlyphForms.NONE case "プロポーショナル字形": return 1247897456; //AlternateGlyphForms.PROPORTIONAL_WIDTH_FORM case "等幅4分字形": case "等幅4分字形": return 1247897457; //AlternateGlyphForms.QUARTER_WIDTH_FORM case "等幅3分字形": case "等幅3分字形": return 1247897448; //AlternateGlyphForms.THIRD_WIDTH_FORM case "TraditionalForm": case "旧字体": return 1247897460; //AlternateGlyphForms.TRADITIONAL_FORM default : return 1852796517; } } //プログレスバーの作成 //https://community.adobe.com/t5/indesign-discussions/progress-bar-script-running/m-p/10461132 /* // Example is ten things to do. That is the number of 'steps' to do. var steps = 1000000; progress(steps); // Your loop of something to do... for (var i = 0; i < steps; i++) { progress.message("Doing step " + i); // Do something. progress.increment(); } // All done. progress.close(); */ function progress(steps) { var b; var t; var w; w = new Window("palette", "Progress", undefined, {closeButton: false}); t = w.add("statictext"); t.preferredSize = [450, -1]; // 450 pixels wide, default height. if (steps) { b = w.add("progressbar", undefined, 0, steps); b.preferredSize = [450, -1]; // 450 pixels wide, default height. } progress.close = function () { w.close(); }; progress.increment = function () { b.value++; }; progress.message = function (message) { t.text = message; }; w.show(); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Webの勉強はじめてみた その3

今日は2コマ受講しました。 ちょっとした自己紹介ページとJavaScriptのさわり。 今日やったこと 1. 動画埋め込み 2. document.write 気付いたこと 1. ニコニコ動画はscript、YouTubeはiframe 2. JavaScriptにもバージョンがあった 3. テンプレートリテラル 1. JavaScript と iframeの違い あとvideoタグ、使ったことないけれど適宜使い分ける感じなのかな。 JavaScriptのバージョン これ、初めて知りました。 とはいえよくわからないのが本音。 使うときにはそんな意識することでもないんだろうか? テンプレートリテラル こういうちょっとしたの好きかもしれない。 三項演算子みたいな。 document.write(101×180+3001÷11は${101*180+3001/11}です); まとめ いよいよJSに取り掛かるけれど、 忘れてるところも多数あるので一からやるつもりでがんばります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存の自作scriptを簡単にChrome拡張機能にするためのテンプレートを作った

Chrome拡張機能を初めて作ったので作り方の備忘録です。 きっかけは、コーディングしたWebページをデバッグする際に使っていた自作のスクリプト。これまではHTMLファイルにscriptタグを挿入して実行していましたが、ブラウザのボタンから実行できた方が便利です。そこで、既存のスクリプトからコピペで簡単に「Chrome拡張機能化」できるようなテンプレートを作っておくことにしました。この記事では、その自作テンプレートcxt-templateについて書きます。対応するプラットフォームは、Manifest V3 for Chrome Extensions (MV3)です。 ソース: https://github.com/kazhashimoto/cxt-template cxt-templateはそれ自体がChrome拡張として動作し、提供する機能とUIは単純です。 表示中のページのコンテンツに「ユーザー定義のスクリプト」のコードをinjectして実行する。※スタブとして記述されているscriptは、console.logに1行出力するだけのものです。 表示中のページのコンテンツに「ユーザー定義のCSS」をinjectする オプション項目の設定値の保存と読み込み UI: オプションページ(サンプル) UI: Chromeツールバーに表示される拡張アイコンのトグル(ON/OFF表示) この拡張機能に対するボタンのアイコンイメージは提供しません。ツールバーには、Chromeがデフォルトで設定した"cxt-template"の頭文字"C"が表示されるだけです。 インストール 適当なディレクトリにリポジトリをcloneします。 $ git clone https://github.com/kazhashimoto/cxt-template.git Chromeを起動して、以下の手順でcxt-templateを拡張機能として読み込みます。 chrome://extensions/にアクセスし、拡張機能の管理ページを開きます。(画面の詳細はこちら) 「デベロッパーモード」をONにします。 「パッケージ化されていない拡張機能を読み込む」をクリックします。 ファイル読み込みのダイアログで、ローカルに展開したリポジトリの./cxt-template/extensionディレクトリを選択します。 適当なWebサイトを開いてDevToolsを起動し、cxt-templateのボタンをクリックすると、スタブのscriptが実行されたことを示すメッセージがconsole.logに出力されます。右側のObjectの内容はoptionsの初期値です。 ### start process ### ▶︎Object ファイル構成 テンプレートのファイル一式は、extensionフォルダにあります。ファイル構成は下表のとおりです。 ファイル名 説明 background.js Chrome拡張のservice workerに使われるbackgroundスクリプトです。 content.css Chrome拡張からターゲットのWebページのコンテンツに挿入される「ユーザー定義のスタイルシート」です。 content.js Chrome拡張からターゲットのWebページのコンテンツに挿入される「ユーザー定義のscript」です。 manifest.json Chrome拡張のmanifestファイルです。 options.css オプションページのスタイルシートです。 options.html Chrome拡張のオプションページのHTMLファイルです。 options.js オプションページのロジックを実装するJavaScriptファイルです。 Permissions manifest.jsonで指定しているpermissionは以下の3つです。 manifest.json "permissions": [ "activeTab", "scripting", "storage" ], permission 目的 activeTab ユーザーが拡張アイコンをクリックして呼び出した時、現在アクティブなタブへのアクセス権を一時的に与えるため。 scripting chrome.scriptingAPIを使用して、ターゲットのWebページのコンテンツにスクリプトやスタイルシートを挿入するため storage chrome.storage APIを使用して、optionの設定値を保存・読み込みするため  ユーザー定義のscript ユーザー定義のscriptはcontent.jsの関数内に記述します。 content.jsは以下の構造になっています。機能の組み込みにコーディングが必要な箇所は、コメントに示した[1],[2],[3]の部分です。 content.js (function(classname, init_options, process) { // .... })('_example', // [1] <body>に追加するclass名 function(options) { // [2] オプションの初期値を設定するコードをここに書く }, function(options, active) { // [3] 機能を実装するコードの本体をここに書く if (!active) { // アイコンの状態がOFFになって呼ばれた時 // OFFの時の処理をここに書く return; } // 以下、アイコンの状態がONの時のコード }); class名[1]は次のようにbody要素に設定されます。 表示中のタブについて、ユーザーがツールバーのcxt-templateアイコンを最初にクリックした時、もしくは状態がOFF表示のアイコンをクリックした時: html <body class="_example _example-active"> 状態がON表示のアイコンをクリックした時: html <body class="_example"> オプションページ options.htmlは、サンプルとして2つのcheckboxと2つのカラーピッカーを含んでいます。 ユーザーが「保存」ボタンをクリックすると、以下のプロパティを持つオブジェクトの設定値がChromeのstorageに書き込まれます。 optionsオブジェクトの例 { items: {item1: true, item2: true}, colors: {color1: #ff0000, color2: #0000ff} } ツールバーのcxt-templateアイコンがクリックされると、storageからオプションの設定値が読み込まれ、上記[3]に示したユーザー定義scriptを実行する関数の1番目のパラメーターにセットされます。 javascript function(options, active) storageに保存されたオプションがない場合、[3]のscriptに渡されるoptionにはプリセット値(上記[2]で初期化した値)が入っています。プリセット値かどうかは、プロパティpresetの値(true/false)で確認できます。 javascript if (options.preset) { // optionsには初期値が入っている ... } else { // optionsにはstorageから読み込まれた値が入っている ... } 実施例 cxt-templateを使ってサクッと書いたChrome拡張のサンプルimg-markerです。img-markerは、カレントのタブに表示されたページのコンテンツに含まれるimg要素、および背景画像が設定された要素について枠線を表示します。 ソース: https://github.com/kazhashimoto/img-marker
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3でcropperjsを使う

はじめに vueでcropperjsを使用する方法です 方法 1.プロジェクトの作成 vue create aaaaa 2.作成したプロジェクトに入り,cropperjsをインストール cd aaaaa npm install cropperjs 3.src/App.vueを以下のように変更 src/App.vue <template> <img ref="cropImg" alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </template> <script> import HelloWorld from './components/HelloWorld.vue' import Cropper from 'cropperjs'; import "cropperjs/dist/cropper.css"; export default { name: 'App', components: { HelloWorld, }, data() { return { imgSrc: "./assets/logo.png", }; }, mounted() { this.cropper = new Cropper(this.$refs.cropImg, { background: false, modal: false, highlight: false, viewMode: 1 }); }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 4.実行します npm run serve 5.実行後ブラウザで開くと以下のようにロゴの写真をクロップできるようになります(※クロップ後の画像が欲しい場合はthis.cropperが持っているのでそこから取得します) 参考 vueとcropperjsによる映像クロップ 環境 ubuntu20.04
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3.0 + Cropperjs

はじめに vueでcropperjsを使用する方法です 方法 1.プロジェクトの作成 vue create aaaaa 2.作成したプロジェクトに入り,cropperjsをインストール cd aaaaa npm install cropperjs 3.src/App.vueを以下のように変更 src/App.vue <template> <img ref="cropImg" alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </template> <script> import HelloWorld from './components/HelloWorld.vue' import Cropper from 'cropperjs'; import "cropperjs/dist/cropper.css"; export default { name: 'App', components: { HelloWorld, }, mounted() { this.cropper = new Cropper(this.$refs.cropImg, { background: false, modal: false, highlight: false, viewMode: 1 }); }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 4.実行 npm run serve 5.結果 ※クロップ後の画像が欲しい場合はthis.cropperが持っているのでそこから取得します 参考 vueとcropperjsによる映像クロップ: https://codesandbox.io/s/vue-cropperjs-video-u56xz?file=/src/main.js 環境 ubuntu20.04
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3でcropperjsを使用する

まず適当にプロジェクトを作成します。 vue create aaaaa 次に,作成したプロジェクトに入り,cropperjsをインストールします。 cd aaaaa npm install cropperjs src/App.vueを以下のように変更します src/App.vue <template> <img ref="cropImg" alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </template> <script> import HelloWorld from './components/HelloWorld.vue' import Cropper from 'cropperjs'; import "cropperjs/dist/cropper.css"; export default { name: 'App', components: { HelloWorld, }, data() { return { imgSrc: "./assets/logo.png", }; }, mounted() { this.cropper = new Cropper(this.$refs.cropImg, { background: false, modal: false, highlight: false, viewMode: 1 }); }, } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 以下のように実行します npm run serve すると,以下のようにロゴの写真をクロップできるようになりました(※クロップ後の画像が欲しい場合はthis.cropperが持っているのでそこから取得します)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

YOUのボイスはジャニーズっぽい! #音声認識 #ジャニーズ

『POICE』~あなたの声は「○○っぽいっす」~ SMAPが解散し、嵐も休止し、つい先日V6も解散し、色んなメンバーが巣立っていったジャニーズ。 少し寂しい気もしますが、今も昔も男性アイドルの事務所と言えば、やっぱりジャニーズ。 「あなたってジャニーズっぽいよね!」は褒め言葉の王道と言っても過言ではないですが、(多分) いざ言われると「本当にそう思ってるの……?」と疑ってしまいますよね。 でも!声なら!声だけなら!あなたもジャニーズになれるかもしれません! すみません。言いすぎました。 でもせめて「っぽい」と判定されてちょっとだけテンションあげませんか? TeachableMachineの音声認識を利用して、 「ボイス(VOICE)」を「○○っぽいっす!」と判定するので、 『POICE』(ポイス)と名付けました。(安直!) 話のきっかけにいかがですか? (投稿主はこの技術を別に応用したく作ってみたしだいです。) いざオーディション! 下記リンク先でお試しいただけます。 使用の際は「マイク使用の許可」を行ってください。 判定されると、作成者の独断と偏見で選ばれたおすすめ公式動画が表示されます。 対象アーティスト ・SMAP(公式動画なし) ・TOKIO(公式動画なし) ・V6 ・KinKi Kids ・嵐 ・タッキー&翼 ・NEWS ・関ジャニ∞ ・KAT-TUN ・Hey! Say! JUMP ・Kis-My-Ft2 ・Sexy Zone ・A.B.C-Z ・ジャニーズWEST ・King & Prince ・Snow Man ・SixTONES ・なにわ男子 使ってみた! 無事にジャニーズWESTと判定されました! デビューできます! 使ったもの ・TeachableMachine ・CodePen ・Netlify ライブラリ ・Bootstrap ・ml5.js ・axios ・jQuery 参考CodePenテンプレート 完成コード 下記CodePenをご確認ください。 See the Pen POICE by kamakurakae (@kamakurakae) on CodePen. デビューできましたか? その日のコンディションにもよるかと思いますが、どこかのグループに所属することはできたでしょうか。 無事に入所しグループに所属できた方、デビューおめでとうございます! 知らないグループもいたかと思います。 そんなときは、表示されたおすすめ動画をご覧いただき彼らの魅力を発見してみてください♪ 完成までのあれこれ いつもどおりZennのスクラップ記事をご覧ください。 反省会 毎度おなじみ反省会のコーナーです。 お時間のある方のみどうぞ。 ・止まらない! →止まりました! 一回判定されたら推論のループを止めたかったのですが、 処理の停止を指示するコードをあれこれ試したのですが止められませんでした。 近日中に更新したいところです。 →一度判定されたら止まるように更新いたしました! SoundClassifierのclassifier.classify()はループがいらない処理とのことでした。 CodePenの内容は更新されています。 これでYoutube動画も表示されるようになりました♪ ・TeachableMachineでの歌唱判定は難しい! 今回の「POICE」ですが、元は「歌をうたう人向けの音声認識アプリを作りたい」が発端となっています。 しかしながら、TeachableMachineを使用しての「歌」や「音程」の判定は、 現在の自分の力では作成が難しく、今回の「○○っぽい判定」に落ち着くところとなりました。 私自身が常に安定した音程で歌えればいいのですが、そうもいかず……。 ・とにかくたくさんのサンプルが必要。 音声認識、判定するにあたり必要最低限のサンプル数だけ集めたのですが、 このサンプルが多ければ多いほど精度はあがります。 開発は最小限にしサンプル収集に多くの時間をかけたかったです。 多くのサンプルが必要であると分かりました。 ・とはいえ、やっぱりTeachableMachineは便利! 画像判定、ポーズ判定などがいくつかのサンプルを設定するだけでできる優れもの。 これが無料で使えるってGoogleさん太っ腹~。 今回の作成から学んだ知識と技術を活かして、本来作成したかった歌声判定もいつか作ってみたいと思います。 おまけ ネタ探しの参考URLをのせておきます。 ・公式(おさえておこう。) ・ジャニーズデビュー順(まとめてる人いっぱいいました。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【gRPC-Web】ネイティブアプリからgRPC-Webは使えるのか?!

はじめに 深夜にラーメン屋に行くと100%お腹を壊すことがわかりました。ありがとうございます。(最近の出来事) 壊れる繋がりでいうとネイティブアプリからgRPC-Webを呼んでもクラッシュしないか気になりましたので、書いていこうと思います。 gRPC-Webってjsじゃん、どうやって呼ぶの? ご安心ください。今回使用するのはReact Nativeなのでそのまま呼べちゃいます。 いざ検証 Envoy Proxyを建てる ここにとてもわかりやすい記事があるので参考にして下さい。 gRPC-Webのビルドを行う ここにわかりやすい素晴らしい記事があるので参考にして下さい。 gRPC Serverを用意する 今回は過去にこちらで紹介した僕の彼女(Botアプリ)をServerとして使用します。 https://qiita.com/taisei_otsuka/items/87adaf5f8ed19a8549c5 React Nativeのアプリを作る チャットアプリ作ってみました (iPhone エミュレーター) あれ...普通にgRPCが呼べる と、僕もそう思ってたのですがAndroidアプリを作っていた時に事件は起きました。 500エラーが返ってくる なんでだろうと調べていた時に公式のissuesを発見しました。 headerにcharset=utf-8がくっついている為とのことです。 The issue is fixed in 0.60 with 4a80776. RNの0.60以降は治ってるとの話なのですが、自分の環境では同じエラーになりました。 結論 iPhoneからgRPC-Webは使える、しかしAndroidで使えない。 なので、別BFFアプリを建てる、もしくはEnvoy Proxyを建ててgRPC-JSON transcoderでhttpからgRPCにリバースプロキシした方が安牌かなと思います。 あとがき Instagram・Facebook・Discord・Uber Eats・SkypeではReact Nativeが使われています。 今回作ったアプリも10分くらいで作れましたし、この記事を読んだきっかけでReact Nativeファンが増えたらと思ってます! 採用PR 大規模サイトので開発やマイクロサービス化・二次元コンテンツに興味がある、もしくはチャレンジしてみたいという方は是非一緒に働きましょう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cssのみ(HTML+javascript)でcookie-Clickerをつくる!pt.3

こんにちは! 今回もcssクッキークリッカーを書いていきます。 前回→ここをクリック! css-cookie-clicker→ここをクリック! 前回から変わったところ まず上にコメントバーを作りました。 コード・css main.css .c44{ width:630px; height:150px; position:absolute; left:416px; top:0px; background-color:#191970; border:double 10px #000; color:#fff; text-align:center; } .c45{ font-size:25px; } .c46{ width:600px; height:15px; position:absolute; left:434px; top:100px; background-color:#fff; border:solid 5px #000; } .c47{ font-size:25px; position:absolute; left:620px; top:60px; color:#fff; } .c48{ position: fixed; background: rgba(0, 0, 0, 0.5); width: 100%; height: 100%; top: 0; left: 0; z-index: 3; display:none; } .c49{ position:absolute; top:120px; left:720px; font-size:30px; color:#fff; } そして、更にダイアログを作りました→[c48] そして次に、総合クッキーレベルを作りました。 まだ仕組みは作っていませんが、どんどんクッキーを集めて経験値バーがうごいて レベルアップする仕組みを作っていきます。 そして、設定&遊び方とステータスとセーブにダイアログを表示させるようにしました。 そして、white-colickを購入できるようになりました。 前回作った、引き算の演算子を使って作りました。 そして、saveボタンとloadボタンを作りました。 コード・css main.css .c50{ width:80px; height:50px; line-height:50px; z-index:4; } .c50 a{ display:block; width:100%; height:100%; text-decoration: none; background:#0099FF; text-align:center; color:#FFFFFF; font-size:30px; font-weight:bold; border-radius:10px; -webkit-border-radius:10px; -moz-border-radius:10px; box-shadow:5px 5px 0px 0px #DEDEDE ; transition: all 0.4s ease; } .c50 a:hover{ background:#0099FF; color:#FFFC00; margin-left:5px; margin-top:5px; box-shadow:none; } .c51{ position:absolute; top:90px; left:520px; display:none; } .c52{ position:absolute; top:90px; left:800px; display:none; } 今回は、こんな感じのものを作っていきました。 このcookie-clickerは皆さんにも手伝ってもらいたいので、 cssのイラスト等のいいものができましたらコメントに書いてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

webpackの使い方

webpackとは webpackとは、複数のJavaScriptのモジュールをまとめる(バンドル)ことのできるモジュールバンドラのこと。これを利用することで、ファイルを分割した開発や依存関係を気にすることなく開発できるなどのメリットがある。 webpackの使い方 webpackのインストール webpackは、Node.jsのパッケージマネージャーであるnpmを使ってインストールすることができる。 $ npm install --save-dev webpack webpack-cli ここで、webpackを使用するためにはwebpackのコマンドラインインターフェースであるwebpack-cliも一緒にインストールしておく。 webpack.config.jsファイルの作成 webpackを使用するにあたって、webpack.config.jsファイルを作成することで、エントリポイントのファイル名や出力ファイル名などを設定することができる。 エントリーポイントと出力ファイル名、フォルダを指定する場合は、以下のように書ける。 const path = require("path"); module.exports = { // エントリーポイント entry: `./src/index.js`, // ファイルの出力設定 output: { // バンドルされた出力ファイル名 filename: "bundle.js", // 出力先ディレクトリ名とパス path: path.join(__dirname, "dist"), }, }; ここで、webpack.config.jsを設定しない場合は以下のデフォルト値が設定されている。 ■ entry: ./src/index.js ■ output: ./dist/main.js webpackの実行 webpackは、次のコマンドで実行できる。 $ npx webpack
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【javascript】Map, Set

Map, Set データを管理するための入れ物。 コレクションともいう ES6から採用された ObjectとMapの違い Object Map key 文字列 制約なし(数値、関数、オブジェクトなど) for..in ○ × for..of × ○ mapはEntriesという格納場所がありそこでデータを管理している。 const map = new Map(); //オブジェクトをkeyに設定できる。 const key = {} map.set(key, 'value'); console.log(map.get(key)); >>> value //関数をkeyに設定できる。 const key2 = function(){}; map.set(key2, 'value2'); console.log(map.get(key2)); >>> value2 // 数値もkeyに設定できる。 const key3 = 3; map.set(key3, 'value3'); console.log(map.get(key3)); >>> value3 //値の削除 map.delete(key3) console.log(map.get(key3)) >>> undefined //for..ofの確認 for(const [k, v] of map){ console.log(k, v) } >>> {}:'value' >>> ():'value2' ArrayとSetの違い Array Set 重複値 ○ × for..in ○ × for..of ○ ○ 添字[] ○ × const key = {} const key2 = function(){}; const s = new Set() //値の重複ができないことの確認 s.add(key); //同じ値をsに追加している。 s.add(key); //for...ofで確認 for(const k of s){ console.log(k) } >>> {} //一つしか出力されなかった。 //値の削除 s.delete(key2) console.log(s.key2) >>> undefined //値の存在確認(mapでも使える。) console.log(s.has(key2)) >>> false //添字を使えるようにsetをarrayに変換 const arry = Array.from(s) // arry = [...s]スプレッド構文でも良い。 console.log(arry[0])
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【javascript】for...ofの反復可能性

for...of イテレーターを持つオブジェクトの反復操作を行う。 ※イテレーター:反復操作を行う際に使用するオブジェクト 反復可能オブジェクト String Array map set arguments etc... case1 for...ofの実行時はprototypeのSymbol(Symbol.iterator)が使われることになる。 const arry = ['a', 'b', 'c']; for(let v of arry){ console.log(v) } >>> a >>> d >>> c case2 空の配列を用意するとundefinedが戻る。 for...ofはイテレータープロパティを用いるのでprototyepでメソッドを追加しても、戻り値には含まれない。 const arry = ['a', 'b', 'c']; arry[4] = 'e' for(let v of arry){ console.log(v) } //イテレータープロパティを用いるのでprototyepでメソッドを追加しても、戻り値には含まれない。 Object.prototype.method = function(){} //イテレーターを使用しているのでenumerableがfalseでも配列0番目の"a"も戻り値になる。 Object.defineProperty(arry, 0, { enumerable: false }) const b = Object.getOwnPropertyDescriptor(arry, 0); console.log(b) >>> {value: 'a', writable: true, enumerable: false, configurable: true} //配列は0が出発点となるので、3はundifinedとなる。 >>> a [0] >>> b [1] >>> c [2] >>> undefined [3] >>> e [4]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Sync Gateway機能解説:拡張属性(XATTRS)の利用

はじめに Sync Gatewayで拡張属性を使用する理由 XATTRSは、ドキュメントのルーティングとアクセス制御に使用されるデータをドキュメント内に安全に保持するために使用できます。保持された情報を、Sync関数内で利用することにより、データを使用してアクセス許可を駆動できます。このアプローチには、次の利点があります。 追加レベルのセキュリティを提供する。例えば、チャネルを追加し、ユーザーに対するドキュメントのアクセスコントロールを行う。 情報はメタデータに含まれているため、ドキュメントのコンテンツから分離される。 拡張属性の更新は、新しいリビジョンを作成しない。そのため、アクセス制御情報のみを変更し、ドキュメント全体をクライアントにプッシュする必要性がない。 Sync Gatewayは、この目的のために単一のユーザー定義可能な拡張属性user_xattr_keyを持ちます。 Couchbase Serverの拡張属性についての復習 Couchbase Serverでは、拡張属性(XATTR)を使って、開発者は、アプリケーション固有のメタデータを定義できます。このメタデータは、その存在を把握した上で、明示的にリクエスト、または変更を行おうとするアプリケーションにのみ表示されます。 たとえば、プログラミングフレームワークに固有のメタデータとして利用し、他のアプリケーションやフレームワーク、ないし同じフレームワークの別のバージョンに対して非表示にするということが考えられます。 拡張属性(XATTR)は、基本的に一般的なアプリケーションでの使用を目的としておらず、ライブラリーやフレームワークで利用することが想定されています。 拡張属性(XATTR)に保存されているデータには、通常のCouchbase Serverのデータへアクセスする方法では、簡単にアクセスできないようになっています。 Couchbase Server SDKは、サブドキュメントAPIの拡張機能によって拡張属性をサポートしていおり、拡張属性の定義、検索、編集、削除などを行うことができます。ただし、サブドキュメント操作を通常の属性ではなく拡張属性で実行するように指定するには、アプリケーションでxattrフラグをtrueに設定する必要があります。 Couchbase Serverに保存されているドキュメントの最大サイズは20MBであり、拡張属性(XATTR)は、ユーザー利用領域としてこのコンテンツサイズを消費します。 Sync Gatewayで拡張属性を利用する方法 構成 Sync Gatewayは、構成プロパティの一部として、ユーザー定義による拡張属性の名前user_xattr_keyを持ちます。 拡張属性(XATTR)は、値として、文字列、配列、オブジェクトなど、JSONとして有効な要素を取ることができます。 次の例では、Admin REST APIを使用して、データベースhotelsに、XATTR名「channelXattr」を指定しています。 curl -X PUT 'http://localhost:4985/hotels/_config' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data-raw '{ "user_xattr_key": "channelXattr" } }' ここで、「channelXattr」が、チャネルルーティング情報を保持するように指定された拡張属性の名前として設定されます。 設定 Couchbase Server SDK APIを使用して、XATTRの値を設定および維持できます。Sync Gateway REST APIを使用して設定することはできません。ドキュメントの作成時および更新時に、SDK APIを使用してxattrの値を設定します。 Couchbase Serverドキュメントのメタデータの例について、以下示します。 { "meta": { ① "id": "1000", "rev": "7-1680c88cbce700000000000002000006", "expiration": 0, "flags": 33554438, "type": "json" }, "xattrs": { ② "channelXattr": [ ③ "channel1", "channel3", "useradmin" ] } } ① システムメタデータ ② ユーザーメタデータとしての拡張属性 ③ ここで、channelXattrは、Sync関数に渡されるチャネルルーティング情報を保持する指定されたxattrの名前です。値は、ドキュメントの作成時および更新時に、SDK APIを使用して設定されたものです。 利用 Sync Gateway構成プロパティuser_xattr_keyで指定された拡張属性(XATTR)は、Sync関数の引数metaを使って、meta.xattrs.<拡張属性名>の形で、利用できます function (doc, oldDoc, meta) { ① if (meta.xattrs.channelXattr == "undefined") ② { console.log("no user_xattr_key defined") channel(null) } else { channel(meta.xattrs.channelXattr) ③ } // Further processing as required ../ ① sync関数の引数に、metaを含めます。 ② metaオブジェクトにアクセスして、対象の拡張属性がこのドキュメントに存在することを確認します。 ③ 拡張属性のコンテンツを使用し、チャネルを定義します。 関連情報
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

InDesign JavaScript XML 要素に文字を挿入もしくは要素を文字に変換

要素に文字を挿入もしくは要素を文字に変換するスクリプトは、これで良いのかな・・・? /* このスクリプトを利用して起こった不具合の責任は取れません。 ご了承下さい。 更新 2021/11/25 */ // アプリ指定 #target "indesign"; // スクリプト名 var scriptName = "要素に文字を挿入もしくは要素を文字に変換"; // 挿入対象の要素 var afterElementInsertTextAsContentElementArray = ["p"]; // 挿入文字 var afterElementInsertTextAsContentArray = ["\r"]; // 挿入文字の読み var afterElementInsertTextAsContentReadingArray = ["段落の終わり"]; // 変換対象の要素 var escapeSpecialCharacterElementArray = ["CR","LF"]; // 変換文字 var escapeSpecialCharacterArray = ["\r","\n"]; // 変換文字の読み var escapeSpecialCharacterReadingArray = ["段落の終わり","強制改行"]; // ダイアログのテキスト var daialogTextArray = []; /* 文字を入れる */ daialogTextArray.push("要素の後が「Storyの終わり」もしくは「段落の終わり」の場合は「段落の終わり」は挿入されません。" + "\r"); for(var i = 0; i < afterElementInsertTextAsContentElementArray.length; i++){ daialogTextArray.push("「" + afterElementInsertTextAsContentElementArray[i] +"」要素の後に「" +afterElementInsertTextAsContentReadingArray[i] +"」を挿入します。"); } daialogTextArray.push(""); for(var i = 0; i < escapeSpecialCharacterElementArray.length; i++){ daialogTextArray.push("「" + escapeSpecialCharacterElementArray[i] +"」要素を「" +escapeSpecialCharacterReadingArray[i] +"」に変換します。"); } /* 文字を入れる */ // ダイアログ var dialogueFlg = confirm(daialogTextArray.join("\r"),"", scriptName); // Noの場合 if(dialogueFlg == false){ // 終了 exit(); } // エラー処理 try { // glue code.jsxを取り込み $.evalFile(app.filePath + "/Scripts/XML Rules/glue code.jsx"); // エラーの場合 }catch(e){ // 警告 alert("「glue code.jsx」が見つかりませんでした。"); // 終了 exit(); } /* ルールセット */ var myRuleSet = []; for(var i = 0; i < afterElementInsertTextAsContentElementArray.length; i++){ myRuleSet.push(new afterElementInsertTextAsContent("//" + afterElementInsertTextAsContentElementArray[i], afterElementInsertTextAsContentArray[i])); } for(var i = 0; i < escapeSpecialCharacterElementArray.length; i++){ myRuleSet.push(new escapeSpecialCharacters("//" + escapeSpecialCharacterElementArray[i], escapeSpecialCharacterArray[i])); } /* ルールセット */ // スクリプトを実行 app.doScript(function(){ // 処理するxmlRule __processRuleSet(app.activeDocument.xmlElements.firstItem(),myRuleSet); // 一つのアンドゥ履歴にする }, ScriptLanguage.JAVASCRIPT,[], UndoModes.ENTIRE_SCRIPT, scriptName); /* スクリプトを実行 */ // 要素の後に文字を挿入するXmlRule function afterElementInsertTextAsContent(myXpath, myContents){ this.name = "afterElementInsertTextAsContent" ; this.xpath = myXpath; this.apply = function(myElement, myRuleProcessor){ // 要素に挿入 myElement.insertTextAsContent(myContents, XMLElementPosition.AFTER_ELEMENT); return true; } } // 要素を文字に変えるXmlRule function escapeSpecialCharacters(myXpath, myContents){ this.name = "escapeSpecialCharacters" ; this.xpath = myXpath; this.apply = function(myElement, myRuleProcessor){ // 要素の内容に入れる myElement.contents = myContents; // 子要素をスキップ __skipChildren(myRuleProcessor); // タグを外す myElement.untag(); return true; } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

InDesign JavaScript XML タグを制御文字に変換

タグを制御文字に変換するスクリプトは、これで良いのかな・・・? /* このスクリプトを利用して起こった不具合の責任は取れません。 ご了承下さい。 glue code.jsxのパスを指定して下さい。 更新 2021/11/25 */ // アプリ指定 #target "indesign"; #include "glue code.jsx"; // スクリプト名 var scriptName = "タグを制御文字に変換"; // スクリプトを実行 app.doScript(function(){ // glue code.jsxの __processRuleSet(app.activeDocument.xmlElements.firstItem(),[new afterElementInsertTextAsContent("//p", "\r"), new escapeSpecialCharacters("//CR","\r"), new escapeSpecialCharacters("//LF","\n")] ); // 一つのアンドゥ履歴にする }, ScriptLanguage.JAVASCRIPT,[], UndoModes.ENTIRE_SCRIPT, scriptName); /* スクリプトを実行 */ function afterElementInsertTextAsContent(myXpath, myContents){ this.name = "afterElementInsertTextAsContent" ; this.xpath = myXpath; this.apply = function(myElement, myRuleProcessor){ __processRuleSet(myElement,[new escapeSpecialCharacters("//CR","\r"), new escapeSpecialCharacters("//LF","\n")] ); myElement.insertTextAsContent(myContents, XMLElementPosition.AFTER_ELEMENT); myElement.select(); __skipChildren(myRuleProcessor); app.menuActions.itemByID(78637).invoke(); return true; } } function escapeSpecialCharacters(myXpath, myContents){ this.name = "escapeSpecialCharacters" ; this.xpath = myXpath; this.apply = function(myElement, myRuleProcessor){ myElement.contents = myContents; __skipChildren(myRuleProcessor); myElement.untag(); return true; } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

一緒に探そうNext 10 Baggar  機械学習で次のテンバガー探しに挑戦 #投資 #テンバガー #FIRE

テンバガー、それは夢 こんにちは、米国株を少しだけ齧っているtishiyamaです。 最近はFIREなんて言葉が流行っていて投資人口が増えてきていますね。 FIREの近道といえばテンバガー、テンバガーといれば夢か幻かなと思います。 テンバガー欲しさにペニー株に突っ込んだ人も数知れず、私もその中の一人です。 $○○○○絶対許さないからな。 (↑一応伏せておきます) 何言っているんだ、という人のための用語集 FIRE:Financial Independence, Retire Early、経済的に自立した状態で早期退職し、自由な時間を過ごすこと テンバガー:株価が10倍になった銘柄、なりそうな銘柄のこと。野球用語でバガーは塁打を意味し、一試合で10塁打(テンバガー)を記録するくらいの勢いで株価が急騰し、10倍まで跳ね上がる銘柄をテンバガーと呼ぶ。 ペニー株:いわゆる低位株。わずかな株価の上昇から大きなリターンが得られる可能性が魅力である反面、わずかな下落から損が拡大するという逆の現象のリスクも伴います。 Teachable Machine による機械学習を少し学んだのでそれを使ってNext 10 Baggarを探します。 私情と欲にまみれたこの企画、果たしてうまくいくのでしょうか。身銭を切っての挑戦します 完成品 ↑チャート図をもってこちらを試してみてください。 使い方 1.「ファイルを選択」を押して判定したいチャート図を選びます。 2.「判定」ボタンを押します。 3.結果が良ければBUY、悪ければSELL、簡単です ソースコード CODE PENで作成しています。便利すぎて手放せません。 See the Pen Next 10-Bagger by tishiyama (@tishiyama) on CodePen. 機械学習モデル チャート図から学習モデルを作成しています。 テンバガーを探すということで、 ・過去にテンバガーを達成した銘柄を探す。 ・その銘柄のチャート図を画像として取得してTeachable Machineに取り込む。 という流れとなります。 株式市場の情報を取得する グーグルスプレッドシートの関数に「GOOGLEFINANCE」というものがあることをご存じでしょうか? 私は今回初めて知った関数です。 この関数を使えば、スプレッドシート上で銘柄の情報が簡単に取得できるという優れものです。 価格やPERやEPSなど必要な情報は取得できて、更には過去の価格まで取得できます。 この関数をつかって、過去の価格と現在の価格を比較してテンバガーを達成している銘柄を対象として選定しました。結果50銘柄取得されました。 Ticker チャート図を取得する 選定した銘柄のチャート図を取得します。 一括で画像データを取得できればよかったのですが、チャート図で、期間指定のチャート図をまとめて取得する方法が思いつかなかったので手動での作業になりました。 チャート図をスクリーンショットを一つずつ取得しました。(しんどかった。。) チャート図のどの部分を取得するか決める テンバガーを達成済みの銘柄を取得するので、達成済みのチャートを取得しても手遅れになります。 テンバガーを達成する前のチャートと同じチャートを描いている銘柄=“Next 10 Baggar”と考えます。 5年でテンバガーを達成しているので、最初の3~4年のチャート図で機械学習させてみます。 この場合、厳密にはテンバガーじゃないのではとも思いますがそのあたりは目をつぶります。 対比側のチャートも選ぶ Teachable Machineはクラスが2個以上必要なので、 テンバガー銘柄の対抗として、5年で大幅に値崩れしてしまっている銘柄のチャートをもう一つのクラスとして作成しました。 実際に使ってみる 思いついた成長しそうな銘柄とインターネット上で次のテンバガーとして取り上げられているもので試してみます。 NASDAQ: GOOGL(Alphabet Inc Class A) テンバガーか?といわれると疑問ですが、流石のグーグルです。 NASDAQ: MSFT(マイクロソフト) あれ?グーグルがよくてマイクロソフトがダメなのはなんでだろう? ぱっとみチャートもあまり変わらないのに。。。 Google Chromeで実行したからかな?と思い、Edgeで実行してみましたが変わりませんでした。(当たり前) NASDAQ: ASML(ASMLホールディング) 半導体の世界サプライヤーです。 NASDAQ: MDB(Mongodb Inc) 事業内容:クラウド・データベースのようです。 NASDAQ: OKTA(オクタ) 事業内容:アイデンティティ・クラウドのようです。 他にもDOCS、SNOW、PLTR、DDOG、DOCU、SQ、CRWD、MRNA、TEAM、TTD、TWLOなど試してみましたが、 買えと言われるのはほとんど見つかりませんでした。 一見同じチャートにも見えるものでも結果が違ったりして、人間の目には見えない何かが見えているのでしょうか。 結論(FIREできそうか) 正直なところ、画像の選定方法、取得した画像、サンプルの数、いろんな要素がありますが、有効に動く気が全くしませんでした。 何となく画像により判定はされるものの、なんの根拠も確証もありません。 これは“占い”か“運試し”です。 買うか、売るか、トレードに悩んでいて、最後の一押しが欲しいときに何となくに使ってみる程度を推奨します。 実際に買ってみる とはいえ、身銭を切って挑戦、ということで実際に購入してみます。 少額なのでご安心ください。人生賭けていないです。 結果がわかるのは1年後でしょうか、また1年後に更新したいと思います。 Ticker price(21/11/25) price(xx/xx/xx) ASML 797.1 後日更新 MDB 503.1 後日更新 OKTA 214.5 後日更新 素材
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Metaのロゴによく似た錯視をMATLABで書いてみた

前段のポエム 最近Facebookの会社名がMetaに変わりましたよね。 それによって これからはGAFAじゃなくてGAMA? いやいやFAANG→MANGAだよ という議論が世界中で積算すると何十万回されたのではないでしょうか。 一方僕はこのロゴをみてこう思いました。 これ Dual Axis Illusionじゃね? Dual Axis Illusionって何よ 錯視界では超有名な錯視です。 毎年下記のWebページでその年の最優秀錯視コンテンストが行われているのですが、Dual Axis Illusionは2019年の最優秀錯視です。 似てはいますが厳密にはちょっと違いますね。 でもなんだか掴みどころがないような不思議な雰囲気は似てますよね(こじつけ) MATLABでこれ書けないか? まぁもちろん書けました。 解説 この錯視には6つ交点があります。 水平移動しているように見える3つの交点、垂直移動しているように見える4つの交点があり、その交点の動きに注目するとそれにつられれて図形全体の動きが変わっているように見えます。すごいですよね。さすがIlusion of the year です。 面白いのはDual Axis の名前の通り、Verticalの回転にみえたりHorizontalの回転に見えたり、はたまた各Axisで回転方向が変わったようにみえるのがすごいです。 しかしなぜ色々見え方が変わるんでしょうか。自分なりに考えてみました。 奥行きの認知について 人間は必ずしも両眼の視差だけで奥行きを認知してるわけではないです。 ある程度は単眼でも奥行きを認知できます。 今回の錯視は単純な線図だが3次元的な形状をもつオブジェクトにも見えなくもないです。 おそらく線の交点がいわゆる遠近法の収束点のように見えて奥行きを感じるのではと思います。 一方で線遠近法は逆の効果、すなわち手前に見えるような効果も持っています。 これもその道のプロが逆遠近法についての事例を報告しています。 投影法の混在を考慮した逆遠近法 - 情報学広場 錯視といえば立命館大学の北岡先生 超有名なThinky the Dragon コレは素人の勘ですが、おそらくこの奥行きを感じさせる交点を凸と認知するか凹と認知するかによって まずこの錯視の見え方が違ってくると思います。 加えて各交点がスムーズに移動して重なるような動きをしています。 重なってしまうと完全に情報が統合され どっちが凹でどっちが凸なのか判別不能になります。つまり、逆遠近法と遠近法が入れ替わるとでもいいましょうか。 その瞬間、いままで凸だと認識していた交点が凹に切り替わってしまうと、三次元オブジェクトの表と裏がぐるっと反転して認知されてしまうので 回転方向が変わったように見えるんだと思います。 この錯視は回転という運動認知の観点も含むのでオプティカルフローについての議論を含めると現象をよく理解できるかもしれません。 球が観察者視点からみて左方向に回転しているとき、表面のオプティカルフローは左に動き、裏面のオプティカルフローは右に動いているので、 仮に、遠近法と逆遠近法が入れ替わることで、オブジェクトの表と裏が入れ替わって見えてしまうと逆回転に見えるというのは筋が通りそうな気がします。 Wikipedia Optic Flow(英語のWikipediaかなり詳しいですね) MathWorksのOptical-Flowに関するページ この辺、錯視の専門家と議論してみたいものです。 それを応用したら何ができるか このような錯視の研究は、人間の脳が引き起こすエラーです。 一方でソフトウェアエンジニアの皆さんは日々コードを書いて、コンパイラが吐き出すエラーを見ながらバグを推測するなんてことを日常的に行っていると思います。 皆さん、錯視を人間が吐き出すバグと捉えると、どういうパターンでバグが発生するかを解析することで、人間の認知や脳の仕組みについて明らかにできると思いませんか? そのようなことを狙った学問が認知心理学だと思ってます。ちゃんと学会等でこのような錯視をもとにメカニズム解明を目的とした研究が多数あります。 逆遠近法を用いた錯覚の知覚条件の検証 (バーチャルリアリティ学会) ここらへんメカニズムの解明が進むと、自動車のADAS/AD(先進運転支援システム/自動運転)にも応用されるかもしれません。 例えばこちらのモービルアイにも単眼で距離を認識できる理由として遠近法にも触れた説明がされています。 (上記Webページから引用) ●カメラ1台でどうして車間距離が分かるのですか? ステレオカメラでなくても良い理由が分かりません。 両目で見るから距離が分かるというのは錯覚です。両目で立体で見えるのは視差(パララックス)による感覚です。両目の間隔は6cm程度ですから、数メートル以上の距離では距離の違いが分からなくなります。(昔の戦艦大和で使われていた測距儀は15.5m離した2>台の望遠レンズで三角測量して10km以上先の敵艦までの距離を測っていました。) ではカメラ1台でどうして車間距離が分かるのでしょうか。 道路の幅や車線は無限遠の地平線で一点(消点)に収束するという遠近法の原理を利用します。 前方のクルマのタイヤが地面に接する位置は、近くになるにつれて無限遠の1点(消点)より下にずれて見えます。消点からどれだけ下にずれるかをカメラのCMOSセンサーで常時観測しているので距離が刻々と分かるという訳です。 この方法で80~90m程度の前方車両までの距離測定がリアルタイムに可能になります。 しかし、人間はADAS/ADが使う認知システムなんかと比べると遥かにコンパクトで、 しかも両眼・単眼両方の奥行きを認知アルゴリズムを駆使し、状況によって適切な認知方法を使い分けるというのをリアルタイムで処理していて、しかもイメージプロセッサやGPU、パワーサプライユニットなんかが発生させるほど処理における熱を発生させないなんて 本当にすごいですよね。 完全に人間と同じような認知ができるシステムはまだまだ難しいのではないかと思います。 このコード読みたい? さて、この錯視スクリプト書いてたのですが当初はYoutubeの動画見ながら「これはリサージュ図形ににてるからX,Y軸で見ると正弦波波形に見えるな」などと考えてごちゃごちゃ書いていたのです。これを見てると周波数差が3対2のとき、X、Yの位相差を少しずつずらして書いていけばなんとなくそれっぽくなりそうだと思いました。 そんなことしてると、なんとこの錯視の作者さんがjavascriptでこの錯視を記述するコードを公開していたのを見つけました! こっちを見とけばよかった! 最終的にはこのコードを参考によりわかりやすくコメントを含めてMATLABコードにしてみました。 元々の作者さんがGPLv2で公開していたので私もGPLv2でGitHubにアップロードしました。 よろしければ色々いじって試してみてください。 以上です!ありがとうございました!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#OpenAI の Codex で JavaScript のプログラムを生成して p5.js Web Editor上で動かす(単純な四角形の描画)

以下のツイートに関連する、タイトル通りの話です。 #OpenAI の Codex を Codex JavaScript Sandbox で試した話。「display rect using p5.js」という文章を入力にして、Codex で JavaScript のプログラムを生成。その出力されたプログラムを #p5js Web Editor上で動かしたら、普通に動いてる! pic.twitter.com/YHlPA5Ow8J— you (@youtoy) November 24, 2021 OpenAI の Codex について OpenAI の Codex は、以下のような紹介のされ方をしていたりする技術です。 ●文章からプログラムを自動生成する「OpenAI Codex」β版APIが公開 「GitHub Copilot」のエンジン - ITmedia NEWS  https://www.itmedia.co.jp/news/articles/2108/11/news134.html  米AI研究企業のOpenAIは8月10日(現地時間)、英語などの文章からソースコードを自動生成するAIシステム「OpenAI Codex」のβ版APIの提供を始めた。米GitHubが6月に発表した、関数名やコメントからコードを自動補完する「GitHub Copilot」の基盤システムで、Pythonなど10以上のプログラミング言語に対応しているという。 そういえば、GitHub Copilotも使えるようになったけど、きちんと試せてない... 【GitHub Copilot】「もう来ないのでは?」と思っていたところに、テクニカルプレビューのお知らせメールが来た。 pic.twitter.com/8quZeyRuyS— you (@youtoy) October 27, 2021 利用方法 記事執筆時点ではプライベートベータで提供されていて、申し込みページから利用の申請(ウェイトリストへの登録)ができます。 申し込んである程度の日数が経過した後、以下のように利用可能になったというお知らせが来ました。 OpenAI Codex、かなり前に申し込んだつもりでいたけど未完だったっぽいことにちょっと前に気づき、申請をしてみたのだけど、それが早くも通った。 pic.twitter.com/eo04KM3KSF— you (@youtoy) November 24, 2021 簡単に試せる環境 Codex のページを見ていくと、Webページ上で試せる「Codex JavaScript Sandbox」というものがあったので、そちらでお試しをしました。 #OpenAI の Codex、「Codex JavaScript Sandbox」という、Webページ上で簡単に試せる仕組みがあったので、先ほど試した。 pic.twitter.com/vPF3zJ1Zz4— you (@youtoy) November 24, 2021 OpenAI の Codex でコードを生成してみる 入力した文章 とりあえず、ぱっと思いついた以下の文章を入力にしてみました。 「display rect using p5.js」 p5.js を使って四角形を描画、という非常に簡単な内容にはなっています。 生成されたコードを動かしてみる 出力として、p5.js を使った形のソースコードが出てきたので、p5.js Web Editor を使って動かしてみました(単純な処理なので、見て大丈夫そうだと分かったものの)。 実行結果は、以下のとおりです。 そういえば、表示させる位置とか、色とかは全くしていしていなかったですが、そのあたりも適当なものをまずは設定してくれたようでした。 あと、"global mode" でなく "instance mode" が使われたものができました。 別の文章で試す 今度は、「左から右へ動く円を描画する」という内容を試してみたのですが、「マウスカーソルについてくる円を描画する」というものができあがりました。 引き続き、 #OpenAI の Codex のお試し。今度は「Draw a circle that moves from left to right using p5.js」という文章にしてみたら、動くプログラムは生成されたけど、 #p5js の mouseX・mouseY を使ったプログラムが生成された。ちょっと意図したものと違うかな。— you (@youtoy) November 24, 2021 再度、同じ文章を入れてみたりしたら、今度は動く円を描画するものができたりました。 リロードして同じ文章を入れて再実行したら、今度は動く円が描画されるやつができた。 pic.twitter.com/7JFzjx7Qag— you (@youtoy) November 24, 2021 もう少し、「Codex JavaScript Sandbox」であれこれ触ってみようかと思います。 余談 Codex を利用した話の記事・ツイートについて 今回の記事を書くにあたり(また、その前に生成した結果をツイートするにあたり)、プライベートベータという状況のサービスでもあるので、情報を公開するのに関係する規約を見てみました。 そして「OpenAI Codex FAQs」という部分を見ていく中で、「Do the sharing and publication policies apply to OpenAI Codex?」という項目を見つけました。 (おそらく、もとは AI が生成した文章が危険な使われ方をしないように、という方向がメインのものっぽい内容でした) OpenAI の Codex、試した話(生成されたコードの内容等)を記事にしたり投稿したりできるんだっけ?という部分を確認したくて、OpenAI Codex FAQs を読んでる。そして「Do the sharing and publication policies apply to OpenAI Codex?」という部分を発見したところ。 https://t.co/ZgMBieB5hH— you (@youtoy) November 24, 2021 さらにその中で「Social media policy」や「Livestreaming and demonstrations policy」という部分があり、公開をして良い条件・対象・方法といった内容が規定されているようでした。 (「ポリシー関連の記載で、現時点での内容は見直されて変わることがある」、みたいな記載もあったので、あくまで記事執筆時点の内容での話です) もし試された内容を、SNS に投稿したり、関連する記事を書いたり等をする場合は、このあたりを良く見ておく必要がありそうでした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む