Paiza『コードモンスター大図鑑 プログラミングでゲットだぜ!』やってみた
「【PR】コドモンレポートキャンペーン」としてこの記事を執筆しています. ゲームはこちら https://paiza.jp/entry/code_monster_ub paiza.jp
対象
Paizaがよく(?)提供してくれているゲーム形式でプログラミングを勉強しようというコンテンツの新作. PaizaスキルチェックでC~Fということでやや易しめ,初心者向けといった感じだろうか.

また,使用できる言語は,PHP,Ruby,Java,Python,C,C#,JavaScript,C++,Kotlinに対応.また,Coming soonの文字もあることから,今後対応言語も追加されるのかもしれない(?).

ゲーム性
ストーリーは某有名アニメを彷彿とさせる.

プログラミングの課題をクリアすることがゲームが進行する. ゲームではコドモン(コードモンスタ-)を集めることをめざしており,スマホゲームのようなガチャもある.(ゲーム内で獲得できるコインやダイヤが必要)

プログラミング言語を擬人化したキャラクターもいる様です.(なぜかC++ちゃんがたくさんでた)

学習について
まだあまり進めていませんが,最初の方はかなり初歩的な内容です.
- 四則演算
- 文字列の表示や連結
プログラミングの内容についてゲーム内で学習はできないようですが,ゲーム内で示された課題にそったpaizaラーニングのコンテンツにすぐとべるようになっており,難しい課題が出たらそちらで学習してきてからゲームに戻ってくるような動線になっています.

なお,paizaラーニングの全ての講座を受講するにはチケットを使用するか,有料会員にならないといけませんが,今ならキャンペーンで全講座が無料で利用できる様です.

コーディング画面について
paizaで何かしらのコードを書いたことがある人にはおなじみの画面構成かと思います.
ただ,コンソールがないので,提出以前に,自分のコードの結果を確認する方法がありません.(おそらくないと思っています.)
誤ったコードを提出するとダメージを受けたり,一発で正解を出し続けることでコンボがつながったりするので,そのあたりはゲーム性の担保のためにあえてそのようにしていると思っています.

さいごに
まだ少し遊んでみただけですが,次の様な方におすすめできるかと思います.
- 初学者でpaizaラーニングだけではなかなか学習のモチベ-ションがわかない方
- paizaラーニング等で基礎的な学習は終わったが,次に何をして良いかわからない方
- 新しい言語を勉強したので腕試ししたい方,問題集のようなものが欲しい方
- ガチャとか好きな方
if と for だけでがんばるヒューリスティックコンテスト(AHC033参加記)
トヨタ自動車プログラミングコンテスト2024#5(AtCoder Heuristic Contest 033)に参加しました. 筆者はヒューリスティックコンテストに取り組むのが5回目です(真面目に参加するのは初めて).アルゴの方には以前から参加しています(茶色).
今回のコンテストで水パフォがとれたので参加記を書くことにしました.

https://atcoder.jp/users/masumasumath/history/share/ahc033
この記事を読んでほしいひと
- ヒューリスティックコンテストに出てみたいけど取り組み方がわからないひと(初心者の方)
伝えたいこと
- ヒューリスティックコンテストは楽しい(つらい)
必要なプログラミングのスキル
- if文
- 二重for文(盤面の管理)
- 焼きなましやビームサーチは不要!(強くなるには必要だと思いますが,よく知りません)
参加記
基本的な方針
- 完全なルールベースでの実装
つまり,if でゴリ押ししようということです.このときはこうする,あのときはこう,というのを if 文で実装するだけです. なぜなら,焼きなましやビームサーチといったヒューリスティックコンテストの典型的な手法を実装したことがないからです.
問題概要
ヒューリスティックコンテストは問題文が長いことが多いです.はじめから全てを理解しようとせずになんとなく読みました.
- 5台のクレーンを使って,コンテナを搬出する
- 大クレーン1台と小クレーン4台がある
- 大クレーンの方ができることが多いっぽい
- クレーンがぶつかるような移動はできない
- コンテナを搬出する適切な順番がある
- 5
5のマス目がある
- 得点はなんだか複雑だけど,できるだけ短いターンで,適切な場所から搬出すればいいんだな
- 得点は低い方がよい
このあたりでビジュアライザを見ます.兎にも角にもビジュアライザです.(コンテスト中もコーディング画面とヴィジュアライザを常に行ったり来たりしていました.)
そのあと,入力や制約を確認してとりあえず提出,ACします.
得点
少ししてから,得点も真面目に読みました.

簡単に解説しておきます.

- M3:搬出されなかったコンテナの数
- M2:間違った出口から搬出したコンテナの数
- M1:順番を間違えて搬出した場合のコンテナの数(表現は正確ではありません)
- M0:ターン数
M3やM2は簡単にゼロにできそうです.
最初の提出
5つのクレーン全てに対して文字列「PRRRRQLLLLPRRRRQLLLLPRRRRQLLLLPRRRRQLLLLPRRRRQ」を固定で出力するコードをかきました.
(とにかく搬出していく)

この提出をすることで,入力の受け取り,出力の確認等を行えます.これで安心して考察ができるのでおすすめです.
また,この解法ではM3はゼロになっていますが,搬出口は間違っていることがあるので,M2はゼロではありません.
得点:10,007,200
2回目の提出
少し考えて,コードを次の方針で修正しました.
- クレーン同士がぶつかってはいけないので,大クレーンだけ使う
- できるだけ順番通りにコンテナを搬出する
もう少し具体的にいうと
- 各クレーンは自分の行でコンテナを4つ横に並べる(PRRRQLLLPRRQLLPRQLを固定出力, 一番右の列は開けてあるので,各行1コンテナ(合計5個)のコンテナは盤面にない)
- その後,小さいクレーンは爆破
- 大きいクレーンだけを使ってコンテナを0から順番に搬出する(最初に並べた20個のコンテナからチェックする,搬出すべきコンテナが盤面にないときはそのコンテナはとばして次のコンテナを搬出する)
- 余ったコンテナをすべて搬出する(搬出口は正しくない,実装ミス)


この段階で次のような変数を定義しています.
- 盤面を管理するための5
5の2次元リスト B[N][N] (マス(i,j)にコンテナがない場合は-1,コンテナがある場合はその番号)
- クレーンがコンテナを持っているかどうかを管理する変数 KEEP(-1は持っていない,持っている場合はコンテナ番号)
- クレーンの移動先の座標を管理する変数y,x(目標とするコンテナがある座標,搬出口の座標)
- クレーンの現在の座標を管理する変数 C (リストを値に持つ)
- クレーンの現在の座標と移動先の座標の差を管理する変数,my,mx
また,主な機能として次のようなものを実装しています.
- コンテナは {0,5,10,15,20} -> {1,6,11,16,21} -> {2,7,12,17,22} -> {3,8,13,18,23} -> {4,9,14,19,24}の順に搬出する.搬出したいコンテナが盤面にない場合はその番号は飛ばす.(まず{ }内のコンテナをチェックし,そのなかになければ次の { } に進むという感じ)
- 盤面を探索して,搬出すべきコンテナがどこにあるか調べる(搬出口はコンテナ番号から決まる)
- 0列目のコンテナを動かしたときに,まだ搬入されていないコンテナがあればそれを盤面に追加する
得点:823,242 (1回目の得点:10,007,200)
3回目の提出
2回目の提出を次の観点で改善
- すべて(各行で5番目に搬入されるコンテナも)順番通りに搬出する(ただし,0,5,10,15,20 の5つすべてが5番目に搬入される場合は,1個だけあきらめる)
- その他の方針は2回目の提出と同じ

この解法では,次の機能を追加しています.
- まだ搬入されていないコンテナを搬出しないといけない場合は,0列目にあるコンテナを空いているマスによける
得点:14,364 (2回目の得点:823,242) (1回目の得点:10,007,200)
この提出で水パフォをとることができました.
その後
空きマスができたら,左の方にあるコンテナを右に詰めていくということを小クレーン1台だけ使って実装しようと思いましたが,バグらせてしまいました. 単純なルールにして実装してみれば良かったのかもしれません(盤面全体ではなく,特定の列だけ監視するとか)
また時間ができたら改良して遊んでみたいなと思っています.
ChatGPTではじめてのPyAutoGUI(Google Map データ移行)
やりたいことと前提条件
- 以前所属していた組織のGoogle アカウントをずっと使っていたが,それが停止されるということで,新しいアカウントにデータ移行したい.
- 移行するデータはGoogle Mapのお気に入りリスト(スターではなく,ハート)
- 移行するデータは約1000件(手動では無理)
使った技術
- PythonのPyAutoGUI
失敗したこと
PyAutoGUIについて
Google Map のAPI を使ったデータのインポートエクスポートは,どうやらできないことが判明したので(後述),お気に入りリストに登録されている店舗を新しいアカウントの Google Map上でお気に入りリストにコツコツ登録するしかないという結論に到達した. そのため,そのコツコツ登録する部分をPyAutoGUI で自動化することにしました.
環境構築
- MacBook Air (M1)
- Python 3.11.4 (Anaconda)
を使用しました.
PyAutoGUIのインストール(ChatGPT,BingAI頼み)
せっかくなので流行りのChatGPTとBingAIに聞きながらやってみることにしました.
pipが使えませんといったら,手動インストールの手順を教えてくれたので,condaは使えることをお伝えしました.
pyautoguiのインストール1 condaを使ってインストールして,サンプルプログラムを実行するとエラーが出たので,エラーメッセージをそのままChatGPTに投げました.(本当はもっと長いです.一部だけ掲載しています)
condaの使いかた すると,親切にエラーの内容と解決法を教えてくれました.
インストール時のエラー つづき
エラーの解決法 すると,(案の定)エラーは解決しなかったので,次の方法として教えてもらったWebページを見に行きましたが,404NotFoundでした. ChatGPTはここで手詰まりです.
エラーの解決法の続き
そこで,GPT4が使えると噂のBingAIにも同じエラーメッセージを貼り付けて,解決法を聞いてみることにしました.

コーディング
無事パッケージのインストールが終わったので,目的のプログラムを作成していきますが,PyAutoGUIパッケージの使い方がさっぱりわからないので,これも教えてもらうことにしました.

import pyautogui # 画面サイズを取得 screenWidth, screenHeight = pyautogui.size() # マウスカーソルの現在位置を取得 currentMouseX, currentMouseY = pyautogui.position() # マウスカーソルをx座標100、y座標150に移動 pyautogui.moveTo(100, 150) # 現在位置でクリック pyautogui.click() # x座標200、y座標220でクリック pyautogui.click(200, 220) # マウスカーソルを10ピクセル下に移動 pyautogui.move(None, 10) # ダブルクリック pyautogui.doubleClick() # マウスカーソルをx座標500、y座標500に2秒かけて移動 pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad) # 'Hello world!'と入力(各キーの間隔は0.25秒) pyautogui.write('Hello world!', interval=0.25) # Escキーを押す pyautogui.press('esc') # Shiftキーを押し続ける pyautogui.keyDown('shift') # 左キーを6回押す pyautogui.write(['left', 'left', 'left', 'left', 'left', 'left']) # Shiftキーを離す pyautogui.keyUp('shift') # Ctrl + c のホットキーを押す pyautogui.hotkey('ctrl', 'c')
これがわかったら大体やりたいことはできそうなので,次のようなコードを書いて無事完了です.
import pyautogui import pyperclip import csv #お気に入りの店舗の情報が保存されているcsvファイル読み込み stores = [] with open('favorites_stores.csv', 'r', encoding='utf-8') as f: for row in csv.reader(f): stores.append(row[2]) #spotlight の座標 1231 12 #spotlightを起動 pyautogui.click(1231, 12) pyautogui.click() pyautogui.PAUSE = 1 #1秒待ちを入れる pyautogui.click() pyautogui.sleep(0.2) #spotlightからgoogle chromeを起動 pyautogui.write('google chrome', interval=0.05) pyautogui.press('return') #アドレスバーに移動 #画面の真ん中あたりをクリックして,chromeをアクティブにする pyautogui.moveTo(622,413) pyautogui.click(622,413) for s in stores: #アドレスバーの内容を削除 pyautogui.hotkey("command", "l") pyautogui.press('backspace') #リストのurlをクリップボードに格納 pyperclip.copy(s) pyautogui.hotkey("command","v") pyautogui.press('return') pyautogui.PAUSE = 1 #保存アイコンをクリック pyautogui.moveTo(217,551) pyautogui.click(217,551) #お気に入りリストに追加 pyautogui.moveTo(220,590) pyautogui.click(220,590) #読み込み待ち pyautogui.PAUSE = 3 #秒待つ
最後に注意点をいくつか記載します.
- 実際の画面遷移を伴うので,画面読み込み等のために適宜PAUSEを入れています.
- google chrome上のクリックしたい場所は事前にpuautogui.positionで取得しておきます.
- ウインドウが表示される場所によってクリックしたい座標が変わるので,クリックしたい座標を取得したらアプリケーションを閉じたりせずにプログラムを実行してしまいましょう.
- 1000件くらいで,おそらく3-4時間程度かかりました(寝るまえに実行して,朝起きたら終わってました)
GASでGoogleスライド内のテキストデータを取得する
たくさんのGoogleスライドからテキストデータだけを抜き出してスプレッドシート上の一覧にするGASを作ったのでここに公開します.
背景
- 研修講師として,参加者にGoogleスライドの雛形を配布(講師と共有設定されている)
- その研修において,参加者がGoogleスライドに書き込みを行う
- 研修実施後に,参加者がGoogleスライドにどのようなことを書き込みしているか確認したい
という状況において,書き込み内容を一覧化するGASコードを書きました.
イメージ


コード
function main(){ // フォルダの指定 const folderId= 'Goolgeスライドが格納されているフォルダのID'; //フォルダ内のすべてのファイルを取得 const folder = DriveApp.getFolderById(folderId); //ファイルタイプを指定(MINEタイプ) const filetype = "application/vnd.google-apps.presentation"; //スライドを指定 const files = folder.getFilesByType(filetype); //抜き出したテキストデータを転記するためのスプレッドシートを指定 var sss = SpreadsheetApp.openById('スプレッドシートのID').getSheetByName("シート1"); //何行目のデータか //スプレッドシートに書き込む行数 let rowCnt = 1; //各ファイル(スライド)ごとにテキストデータを抜き出す while(files.hasNext()){ let file = files.next(); let fileURL = file.getUrl(); // ファイルURL var presentation = SlidesApp.openByUrl(fileURL); var slides = presentation.getSlides(); //slidesの1枚目(インデックス0)を指定する //getpageElements()でページ要素のリストを取得 var elements = slides[0].getPageElements(); //テキストデータが格納されているオブジェクトごとに列をわけてスプレッドシートに書き込む var colCnt = 0; //各スライドのオブジェクトの数だけ繰り返す for(let i = 0; i < elements.length; i++){ //オブジェクトがグループ化されている場合は,直接テキストデータが抜き出せない if (elements[i].getPageElementType() == SlidesApp.PageElementType.GROUP){ //getChildrenでグループ化されているオブジェクトの中身のオブジェクトを取り出す var children = elements[i].asGroup().getChildren(); for (let j = 0; j < children.length; j++){ var tmpTxt = children[j].asShape().getText().asString(); var tmpCell = sss.getRange(rowCnt, i+1+colCnt); tmpCell.setValue(tmpTxt); colCnt++; } //ページエレメントタイプがSHAPEの場合はテキストデータを直接抜き出せる }else if(elements[i].getPageElementType() == SlidesApp.PageElementType.SHAPE){ var tmpTxt = elements[i].asShape().getText().asString(); var tmpCell = sss.getRange(rowCnt, i+1+colCnt); tmpCell.setValue(tmpTxt); colCnt++; } } rowCnt++; } }
Javascriptがあまりわかっていないので,varとletの使い分けがおかしいかもしれません.
自分がいいねしたツイートの一覧を取得してGoogle Spread Sheetに出力する
動機
ツイッターをやっていて気になったツイートには,備忘録の意味をこめて,いいね!をすることが良くあるのですが,結局見返さないままになってしまっていました.そこで,Twitter APIを利用して,自分が過去にいいね!したツイートの一覧を取得してみました.
使ったもの
- Twitter API
- GAS ( Google Apps Script )
作ったもの
基本的な動き
1.自分のUserIDを指定する 2.指定したUserIDが過去にいいね!したツイートの一覧を取得する 3.取得したツイート一覧をGoogle SpreadSheet に表示する
検索部分のコード
var userId = "user id を指定"; //@からはじまるusernameではなく,ただの数字の羅列 var url = "https://api.twitter.com/2/users/" + userId + "/liked_tweets"; //URLの末尾にliked_tweetsと指定することで,いいね!したツイートが取得できるようだ //検索の設定 var options = { "method": "get", "headers": { "User-Agent": "v2LikedTweetsJS", //これもこのまま書いておけばOK "authorization": "Bearer BearerTokenと呼ばれるものをここに書く", }, }; //取得した結果をJSON形式に変換 var response = JSON.parse(UrlFetchApp.fetch(url, options));
基本的にはこんな感じである.あまりわかっていないが動いているのでヨシ!とする.BearerTokenについては,Twitter APIの使用申請をすればわかる(もらえる).
user id について
自分がいいね!したツイートを取得したいので,自分のTwitter アカウントのuser idを指定する.調べ方は,ツイッターを開いてページソースから「id_str」の文字列を検索するとidが出てくる.
url について
上記のコードに記載したのが基本形である.ここにさらにオプションを付け加えたい場合は次のようにする.
var url = "https://api.twitter.com/2/users/" + userId + "/liked_tweets" + "?tweet.fields=author_id" + "&max_results=30";
検索オプションを1つだけつける場合は,末尾に?を付けてから,オプションtweet.fields=author_idなどをつける.2つ以上つける場合は&で連結する.
ちなみに,tweet.fields=author_idは,いいね!したツイートをしたユーザーのIDを取得しており,max_results=30は1回の検索で30件までしか取得しないというオプションである.
詳細はこちら
取得結果をSpreadSheetに出力する
//検索結果を出力するスプレッドシート const folderId = "**************"; //SpreadSheetが格納されているフォルダーのid const spreadSheetId = "**************";//結果を出力するSpreadSheetのid const sheet = SpreadsheetApp.openById(spreadSheetId); const ss = sheet.getSheetByName("シート1") //シートも名前で指定しておく(シートに対してでないと,getRangeが使えない) var nRow = 1; var col_author = 1; var col_text = 2; dat = response.data; for (let i = 0; i < dat.length; i++){ //レスポンスから値を取得 author_id = dat[i]["author_id"]; text = dat[i]["text"]; //スプレッドシートに値をセット ss.getRange(nRow,col_author).setValue(author_id); ss.getRange(nRow,col_text).setValue(text); nRow++; }
おまけ
基本的には上述したような感じでOKだが,過去にいいね!したツイートがたくさんある場合は,一度には取得できない(おそらく一度に100件までしかツイートを取得できない).そのような場合には,responseにnext_tokenと呼ばれるものがついてくる.それが検索結果についてきた場合は,それを使用して,再度リクエストを投げれば良い.その際にURLを次のように変更する.
var url = "https://api.twitter.com/2/users/" + userId + "/liked_tweets" + "?tweet.fields=author_id" + "&max_results=30"+"&pagination_token=" + nexttoken;
末尾のnexttokenにresponseから取得したnext_tokenの値を格納している.また,オプションで指定するときはpagenation_tokenであることにも注意が必要(これに気づかずしばらくはまった).
おわりに
Webまわりのことは全く詳しくなく,いろいろ調べながら,まぁ動けばいいやというくらいの感じで作業しました.用語等にも誤りがあるかもしれませんし,この機能を使えばもっと簡単に実現できるというようなこともありそうです.例えばTweepyというサービス(ライブラリ?)がよく使われているようでした(何も知らない).
今後やりたいこと
いいね!したツイートを取得したら,そのツイートをだれがしたのか知りたいですよね(idではなく,名前が知りたい).ただ,一緒に取ってくる方法がわかりません.ツイートの取得とは別にuseridを指定すれば取得できるのですが,ツイートごとにその作業が必要なので,APIの呼び出し回数制限にひっかかってしまいます.
統計検定2級に合格しました
はじめに
職場で無料チケットがもらえたので統計検定2級を受験しました。結果は合格でした。
せっかくなので,合格までにやったことを整理することにします。(ただし,問題については言及できません)
勉強したこと
概要をつかむ
最初にこの本を読みました。読むだけなので1日でさっとやりました。厳密ではない部分もありますが,全体を俯瞰するのには良かったと思います。
https://www.amazon.co.jp/完全独習-統計学入門-小島-寛之/dp/4478820090www.amazon.co.jp
また,次のYouTube動画を参考にしました。
かなり正確で信頼を置いていますが,統計検定2級向けというわけではありません。
真面目に勉強する
次にこの本を一通り学習しました。
https://www.amazon.co.jp/入門統計解析-倉田-博史/dp/4883841405/ref=sr_1_1?__mk_ja_JP=カタカナ&crid=1PA60BEMF7KNQ&keywords=入門統計解析&qid=1644669058&s=books&sprefix=入門統計解析%2Cstripbooks%2C235&sr=1-1www.amazon.co.jp
大学初年度程度の教科書という位置付けのようです。数学の書籍としてはかなり読みやすい部類に入るのではないでしょうか。個人的にはかなりおすすめします。
通読して,各章末の問題もほぼ解きました。この一冊で統計検定2級の範囲はほぼ全て網羅できています。
過去問を解く
公式の過去問集を2〜3周しました。
https://www.amazon.co.jp/日本統計学会公式認定-統計検定-2級-公式問題集-2017〜2019年/dp/4788925524/ref=sr_1_3?__mk_ja_JP=カタカナ&crid=U0OBAVCLW2AV&keywords=統計検定2級&qid=1644669724&s=books&sprefix=統計検定2級%2Cstripbooks%2C282&sr=1-3www.amazon.co.jp
もう一つ新しいものもありますがどちらでも良いでしょう。
復習する
toketarou.com たまにこれ間違ってないか?と思う箇所もありましたが,概ね問題ないと思います。
過去問をやってわからなかったところを調べるのに使っていました。(受かることだけを目標にするなら,この動画とWebサイト,過去問で十分かもしれません。)
勉強の方針
合格することが目標ではなかったので,理解することに重きをおいたつもりです。
具体例を挙げます。 標本比率の区間推定と言われたら
が思い浮かぶ人もいると思います。(過去問の解説などでは、この式が公式的に書いてあることも多いと思います)
これをが十分大のとき
は
で近似できることから,
となり,
が成り立つ。これを標準化して,
という導出ができるようにしていました。
勉強以外の注意点
私が受験したのはCBT形式でした。 パソコン教室に行って,パソコンで受験しました。
受験してみて感じたことを挙げます。
- PC画面では問題が読みにくい
いつも本でやっていたので,目の前にあるディスプレイに問題が表示されていたというのがやりにくかったです。また,本と違って問題文に書き込んだりできないのも普段と違う点でした。
- 計算用紙について
本番で使用できる計算用紙はA4用紙2枚分のラミネートフィルムみたいなものでした。スペースが不足した場合は交換してもらえます。ただ,交換なので1枚回収されて,1枚もらえるという感じでした。
私は普段から,余白多め,文字大き目のスタイルなので,結局4枚目まで用紙を使用しました。 ペンも会場で渡されるものを使わないといけません。
- 試験時間
緊張もあったのかもしれませんが,過去問を解いていたときは時間はかなり余裕だったと思うのですが,本番では時間ぎりぎり足りませんでした。 時間をきちんとはかって練習しておくのも大事かもしれません。
おわりに
このような資格試験は10年近く前に受けた情報処理試験以来でした。久しぶりでしたが,ちゃんと受かって良かったです。
これでやっと別のことに取り組めます。