75才からのモバイルアプリ作成

MIT App Inventor 2 を使ったアプリ作成

MIT App Inventor 2で遊ぶ (Weather App New 3)

2024-10-30 07:46:47 | 日記

前回は、データ取得に特に問題ないことを確認。何度もOpenWeatherMapのデータを利用しているが、ちょっとした勘違いなどによりデータの確認がなかなかできないこともある。

今回は、この取得データの一部(年月日、曜日、天候、天候のアイコン)をListViewを利用してリスト形式で表示。

他に取得できるデータとしては、当該都市の緯度・経度、国コード、人口、日の出・日の入時刻、最高気温、最低気温、体感温度(日中、夜、夕方、朝)、気圧、湿度、降水量、風速等々。今までに作成したアプリで使用したものもあり。ブロック・コード的には、今回表示するデータとほぼ同じようなブロック・コードを作成していくことになる。

今回のアプリ Weather App New では、主に日本語と英語の2か国語による表示をいろいろ試すのが目的の一つ。以前にも紹介したことがあるが、OpenWeatherMapのサイトによれば、49ヶ国語に対応しているとのこと。要するに、晴れ、曇り、雨等のお天気情報が49か国語で取得できるということ。ある日の東京のお天気を、日本語、アラビア語、ロシア語、ズールー語(南アフリカ)で検索すると以下の通り。(何の意味もないが。。。)

"weather": [{"id": 804,"main": "Clouds","description": "厚い雲","icon": "04d"}],

"weather": [{"id": 804,"main": "Clouds","description": "غيوم قاتمة","icon": "04d"}],

"weather": [{"id": 804,"main": "Clouds","description": "пасмурно","icon": "04d"}],

"weather": [{"id": 804,"main": "Clouds","description": "liguqubele","icon": "04d"}],

 

アプリ実行のビデオ:

スクリーン・デザイン:

左図:初期画面で、都市別ボタンをタップしデータを取得

右図:都市名を入力してデータを取得(左上端の拡大鏡アイコンの代わりに  アイコンが表示される。)

                             

ブロック・コード:

重複もあり少し長くなるが、前回までの復習も兼ねて。。。

1. 言語の切り替え(英語と日本語)

 選択された言語を格納する変数langの設定:

                           

 言語を切り替えるタイミングとしては、第一にアプリを立ち上げた時と第二に言語切り替えボタンをタップした時がある。

 アプリを立ち上げた時:

                        

 切り替えボタンchnageLangButton「English <= => 日本語」をタップした時:

                         

 いずれも関数selectLangが実行される。ダイアログ・ボックスが表示され、「日本語」または「英語」のいずれかの選択を促す。

                         

 日本語のボタンがタップされれば、変数langに "ja" がセットされ、リスト「titleLabel」のindex 2、

 すなわち「新お天気アプリ」がタイトルにセットされる。また、「English」が選択されたら、同index 1

 である「Weather App New」がタイトルにセットされる。

 同様に、対象都市名が表示されるLabelの見出しも、リスト「cityNameLabel」よりindexに応じラベルが選択、表示される。

                         

                         

                         

2. 検索対象都市をボタンで選択、あるいは都市名を入力し指定する

 対象都市名を格納する変数 targetCity を設定。

                       

 都市名を表示したボタンで対象都市を選択する。

 (赤白点線部分)

 タップされたボタンに表示されている都市名が、リスト cityNameListEN(選択言語が英語の場合)あるいは

 リスト cityNameListJP(選択言語が日本語の場合)の中のどのindex番号にあたるのかを取得。

 再度、cityNameListENの中で同index番号の英語の都市名を変数targetCityにセットする。

 こんなまわりくどいやり方をするのは、APIに対しGETリクエストをする際、検索対象都市名は英語である必要があるため。

 そして、関数fetchDataを実行。

                       

                       

                       

 関数fetchDataはAPI指定のURLに対しGETリクエストを行う。 

                       

 レスポンス・コードとして200が返されたら、リクエストが成功。デコードして変数JSONDataに格納。

 そして、取得したデータからお天気、お天気アイコンのファイル名、日付の必要なデータを以下の関数を実行して抽出していく。

      makeWeatherDescriptionList (晴、曇りなどのお天気データ)

      makeWeatherIconList(お天気アイコンのファイル名)

      getUnixTime(日付)

 200以外の場合は、データ取得に失敗した旨をポップアップにて知らせる。

 また、データの個数もcomponent "length of list" を使って取得し、変数lengthOfDataにセットしておく。

 (もちろん、データの個数は1週間分なので7個とわかっており確定しているが。。。)

                   

                     

                     

 具体的な都市名をインプットして検索対象都市を指定する。

  左上端にあるsearchImageButtonをタップすると  アイコンが に変わる。

 =>それと同時に都市名を冠していた4つのボタンは非表示に。

 =>その代わりに、都市名入力TextBoxと「Fetch Data」ボタンが表示される。

 4つのボタンはHorizontalArrangement2に、TextBoxと「Fetch Data」はVerticalArrangement1にそれぞれ格納されている。

 このHorizontalArrangement2とVerticalArrangement1の表示、非表示を行うため、まず変数selectButtonStatusを設定。

 searchImageButtonをタップするたびに、このselectButtonStatusに格納されている真偽値を変更しArrangementの

 表示、非表示並びにsearchImageButtonのアイコン・イメージ( または )を交互に表示する。

 ちなみに、 のファイル名は maginifyingGlassTrans2.png、 はbackToButtonTrans.png。

                     

                     

 検索対象都市名を入力して「Fetch Data」ボタンをタップすると関数fetchData(ボタンのタップ時と同じ関数)が実行される。

 また、プログレス・スピナー(CircularProgress1)が表示され、データを取得中であることをユーザーに知らせる。

                     

3. 取得したJSONデータより必要なデータを抽出し、データの項目ごとにリスト形式にまとめる。

 お天気のデータ(晴れ、曇り、雨など)を抽出しリスト形式にまとめる

 データを格納する変数weatherDescriptionListを設定。

 JSONDataの中を、list => weather => description とキーを辿っていけばお天気データを取得できる。

 7日分なので、component "for each ~"を使って7回(lengthOdData)反復すれば1週間分のデータを抽出できる。

 お天気アイコンのファイル名を抽出し、リスト形式にまとめる。

 後で、ファイル名とファイルが保存されているURL、拡張子を連結する。

 ファイル名を格納する変数weatherIconListを設定。 

 JSONDataの中を、list => weather => icon とキーを辿っていけばアイコンのファイル名を取得できる。

 日付はUnix Timeで提供されているの取得したUnix time形式を通常の年月日の形式に整える。

 年月日形式の日付のリストを格納する変数dateを設定。

 Unix Timeおよび年月日に変換後の日付を格納する変数unixTimeを設定。(変数名がちょっと紛らわしい)

 変数unixTimeの値をリスト形式で格納する変数unixTimeListを設定。

 Unix Timeから曜日を算出するため用に使うUnix Timeのリストを格納する変数tempDayOfWeekListを設定。

 取得した曜日の番号を格納する変数DayOfWeekを設定。

 曜日の番号をリスト形式で格納する変数dayOfWeekListを設定。

 関数getUniTime:Unix Timeを抽出し、年月日に変換の上、変数dateにリスト形式で格納する。

         また、曜日の番号を取得しdayOfWeekListに格納しておく。(赤白点線内)

     省略した「modulo of floor select list...」を展開すると以下の通りとなる。

     この算出式については、「MIT App Inventorで遊ぶ (New Weather App 4 曜日の表示2)」を参照。

                     

 関数getDate:Unix Timeより年、月、日を取り出す。

 MIT App Inventor 2では、Unix Timeはミリ秒単位、一方、OpenWeatherMapでは秒単位。

 このため、取得したUnix Timeを1000倍する必要あり。componetにも単位は "millis" と表示されている。

 今回、コーディング途中で1000倍するのを忘れたため、年月日の値を取り出せず時間がかかってしまった。 

 項目ごとに抽出したデータ(リスト形式)を統合して一つのリスト形式のデータを作る

 ListView用に作成した統合されたデータを格納する変数dataForListViewを設定。

 関数makeDataForListView:

 ListView用のcomponent "CreateElement" を使って、リストの各行に表示するデータを作成する。

 リストの各行は、mainText、detailText、imageNameの要素に分けられている。

 mainText =>"変数dataに保存してある日付(年月日)" + "(" + "曜日" + ")"

        曜日については、decodeListJpまたはdecodeListEnより言語("lang")に応じた

        日本語あるいは英語表記の曜日を使用。

 detailText=>変数weather DescriptionListに格納してあるお天気データ

 imageName=>https://openweathermap.org/wn/ +変数weatherIconListに格納されているファイル名 + "@2x.png"

 変数dataForListViewに格納されたデータをListViewに表示し、プログレス・スピナーを非表示とする。(赤黄点線部分)

                                            **********************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (Weather App New 2)

MIT App Inventor 2で遊ぶ (Weather App New 1)

 


MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 4)

2024-10-24 11:47:54 | 日記

表示するデータの項目として受賞者の生誕地、または団体の所在地を追加した。

受賞が個人の場合は、Birthplaceのデータを抽出すればよい。しかし、団体の場合は、2つのキーをチェックする必要がある。(当方が誤解しているのかもしれないが。。。)

2024年平和賞を受賞した日本被団協の場合は、以下のJSONデータの通り、キーを辿っていくとfounded => place => locationString => en ではなく、nobelPrizes => residences (index 1) => locationString => en に所在地のデータがある。設立場所(founded)は不明で、現在の所在地のみがわかっているからこのようなデータの内容となっているのだろうか?

一方、2022年に平和賞を受賞したCenter for Civil Liberties の場合は、founded => place => locationString => en にデータがあり、residences というキー自体がない。

上が前回までのListView、下が今回、生誕地と所在地を追加したListView

アプリ実行のビデオ:

スクリーン・デザイン:

前回より変更なし。

ブロック・コード:

生誕地または所在地のデータを処理している部分のみ。

関数makeListData:ListViewに表示する各項目のデータを取得したデータより抽出。

団体のlocationString(所在地)については、関数selectOrgPlace(赤黄点線部分)により別途抽出。

関数selectOrgPlace:

画像が不鮮明でわかりにくいが、

デコードされたJSONデータを laureates => founded => place => locationString => en のように辿って、もし en キーの値が空白であれば、同じJSONデータを laureates => nobelPrizes => residences => locationString => en のように辿って所在地データを抽出する。

関数makeDataForListView:

上記赤白点線部分を拡大すると以下の通り。birthPlace(個人の場合は生誕地、団体は所在地)のデータ表示の際に、受賞対象が団体の場合は、Location : 、個人の場合は、 Birthplace : を見出しとしてつける。

                   

 

                                                    ***********************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 3)

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 2)

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 1)

 

(参考資料)

日本被団協のJSONデータ(デコード前):

{
   "laureates":[
      {
         "id":"1043",
         "orgName":{
            "en":"Nihon Hidankyo",
            "no":"Nihon Hidankyo",
            "se":"Nihon Hidankyo"
         },
         "nativeName":"Nihon Hidankyo",
         "fileName":"nihon-hidankyo",
         "founded":{
            "date":"1956-08-10",
            "place":{
               "locationString":{
                  "en":"",
                  "no":"",
                  "se":""
               }
            }
         },
         "wikipedia":{
            "slug":"Japan_Confederation_of_A-_and_H-Bomb_Sufferers_Organizations",
            "english":"https://en.wikipedia.org/wiki/Japan_Confederation_of_A-_and_H-Bomb_Sufferers_Organizations"
         },
         "wikidata":{
            "id":"Q1989908",
            "url":"https://www.wikidata.org/wiki/Q1989908"
         },
         "sameAs":[
            "https://www.wikidata.org/wiki/Q1989908",
            "https://en.wikipedia.org/wiki/Japan_Confederation_of_A-_and_H-Bomb_Sufferers_Organizations"
         ],
         "links":[
            {
               "rel":"laureate",
               "href":"https://api.nobelprize.org/2/laureate/1043",
               "action":"GET",
               "types":"application/json"
            },
            {
               "rel":"external",
               "href":"https://www.nobelprize.org/laureate/1043",
               "title":" - Facts",
               "action":"GET",
               "types":"text/html",
               "class":[
                  "laureate facts"
               ]
            }
         ],
         "nobelPrizes":[
            {
               "awardYear":"2024",
               "category":{
                  "en":"Peace",
                  "no":"Fred",
                  "se":"Fred"
               },
               "categoryFullName":{
                  "en":"The Nobel Peace Prize",
                  "no":"Nobels fredspris",
                  "se":"Nobels fredspris"
               },
               "sortOrder":"1",
               "portion":"1",
               "dateAwarded":"2024-10-11",
               "prizeStatus":"received",
               "motivation":{
                  "en":"for its efforts to achieve a world free of nuclear weapons and for demonstrating through witness testimony that nuclear weapons must never be used again",
                  "no":"for sin innsats for en atomvåpenfri verden og for å vitne om hvorfor atomvåpen aldri må brukes igjen"
               },
               "prizeAmount":11000000,
               "prizeAmountAdjusted":11000000,
               "residences":[
                  {
                     "city":{
                        "en":"Tokyo",
                        "no":"Tokyo",
                        "se":"Tokyo"
                     },
                     "country":{
                        "en":"Japan",
                        "no":"Japan",
                        "se":"Japan"
                     },
                     "cityNow":{
                        "en":"Tokyo",
                        "no":"Tokyo",
                        "se":"Tokyo"
                     },
                     "countryNow":{
                        "en":"Japan",
                        "no":"Japan",
                        "se":"Japan"
                     },
                     "continent":{
                        "en":"Asia"
                     },
                     "locationString":{
                        "en":"Tokyo, Japan",
                        "no":"Tokyo, Japan",
                        "se":"Tokyo, Japan"
                     }
                  }
               ],

*********************** 以下省略 ***********************

Center for Civil Liberties のJSONデータ(デコード前):

{
   "laureates":[

      {
         "id":"1020",
         "orgName":{
            "en":"Center for Civil Liberties",
            "no":"Senteret for sivile rettigheter",
            "se":"Center for Civil Liberties"
         },
         "nativeName":"Center for Civil Liberties",
         "fileName":"center-for-civil-liberties",
         "founded":{
            "date":"2007-00-00",
            "place":{
               "city":{
                  "en":"Kyiv",
                  "no":"Kyiv",
                  "se":"Kiev"
               },
               "country":{
                  "en":"Ukraine",
                  "no":"Ukraina",
                  "se":"Ukraina",
                  "sameAs":"https://www.wikidata.org/wiki/Q212"
               },
               "cityNow":{
                  "en":"Kyiv",
                  "no":"Kyiv",
                  "se":"Kiev",
                  "sameAs":[
                     "https://www.wikidata.org/wiki/Q1899",
                     "https://www.wikipedia.org/wiki/Kyiv"
                  ]
               },
               "countryNow":{
                  "en":"Ukraine",
                  "no":"Ukraina",
                  "se":"Ukraina",
                  "sameAs":[
                     "https://www.wikidata.org/wiki/Q212"
                  ]
               },
               "continent":{
                  "en":"Europe",
                  "no":"Europa",
                  "se":"Europa"
               },
               "locationString":{
                  "en":"Kyiv, Ukraine",
                  "no":"Kyiv, Ukraina",
                  "se":"Kiev, Ukraina"
               }
            }
         },
         "wikipedia":{
            "slug":"The_Center_for_Civil_Liberties",
            "english":"https://en.wikipedia.org/wiki/The_Center_for_Civil_Liberties"
         },
         "wikidata":{
            "id":"Q114452906",
            "url":"https://www.wikidata.org/wiki/Q114452906"
         },
         "sameAs":[
            "https://www.wikidata.org/wiki/Q114452906",
            "https://en.wikipedia.org/wiki/The_Center_for_Civil_Liberties"
         ],
         "links":[
            {
               "rel":"laureate",
               "href":"https://api.nobelprize.org/2/laureate/1020",
               "action":"GET",
               "types":"application/json"
            },
            {
               "rel":"external",
               "href":"https://www.nobelprize.org/laureate/1020",
               "title":" - Facts",
               "action":"GET",
               "types":"text/html",
               "class":[
                  "laureate facts"
               ]
            }
         ],
         "nobelPrizes":[
            {
               "awardYear":"2022",
               "category":{
                  "en":"Peace",
                  "no":"Fred",
                  "se":"Fred"
               },
               "categoryFullName":{
                  "en":"The Nobel Peace Prize",
                  "no":"Nobels fredspris",
                  "se":"Nobels fredspris"
               },
               "sortOrder":"3",
               "portion":"1/3",
               "dateAwarded":"2022-10-07",
               "prizeStatus":"received",
               "motivation":{
                  "en":"The Peace Prize laureates represent civil society in their home countries. They have for many years promoted the right to criticise power and protect the fundamental rights of citizens. They have made an outstanding effort to document war crimes, human right abuses and the abuse of power. Together they demonstrate the significance of civil society for peace and democracy.",
                  "no":"Prisvinnerne representerer sivilsamfunnet i sine hjemland. De har i mange år stått opp for retten til maktkritikk og grunnleggende rettigheter for borgerne. De har gjort en enestående innsats for å dokumentere krigsforbrytelser, brudd på menneskerettigheter og maktmisbruk. Til sammen viser de sivilsamfunnets betydning for fred og demokrati."
               },
               "prizeAmount":10000000,
               "prizeAmountAdjusted":10000000,

    ************************ 次のキーは"residences" ではなく "links" ************************
               "links":[
                  {

*********************** 以下省略 ***********************

 


MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 3)

2024-10-20 08:18:58 | 日記

受賞者(団体/組織)の名称(または名称の一部)を入力して、情報を検索できる画面を追加。

以下のnameパラメーターに個人又は団体の名称のフル、又は一部をインプットし検索すれば該当の受賞者(団体)のデータを返してくれる。

     https://api.nobelprize.org/2.1/laureates?name=

例えば、

                https://api.nobelprize.org/2.1/laureates?name=nuclear

で検索すれば、2017年に平和賞を受賞した有名な "International Campaign to Abolish Nuclear Weapons" (ICAN)と1985年に同じく平和賞を受賞した "International Physicians for the Prevention of Nuclear War" 2件の平和賞受賞団体のデータを取得できる。

個人でも団体でも同じパラメーター(name)で検索できるのは便利。

もし、インプットした名前(フル又は一部)に合致したデータがない場合は(例えば"sakabe"で検索した場合)、以下の通り、metaデータのcountの値を0で返してくる。ブロック・コードではこれを利用して合致するデータがない場合の処理を行っている。

                                     

アプリ実行のビデオ:

スクリーン・デザイン:

左のメイン画面の下部にアイコン・ボタンを配置。赤黄点線で囲んだアイコンをタップすると検索画面へ遷移。そのほかのアイコンは装飾目的で配置しており、今のところ何ら機能を実装していない。

右画面が検索画面。

                                           

ブロック・コード:

取得したJSONデータの加工、整形、表示等は、前回、前々回と同様なので省略。

合致するデータがなかった場合の処理を中心に見てみる。

1. 変数targetURL:APIのURL

2. searchButtonをタップした際に、検索する名前がsearchNameTextBoxにインプットされていれば、API URLに対しGETリクエストを行い処理を実施する。もし、インプットなしにsearchButtonがタップされた場合は、名前のインプットを促すウインドウがポップアップする。

なお、GETリクエストを出す前に、念のため、変数の初期化を行う関数resetAllを実行しておく。

3. 取得したJSONデータの処理。

取得したJSONデータをデコードし、変数JSONに格納。=> "meta" データに含まれる  "count" の値が 0 であるかどうかをチェック(赤黄点線内)

     => 0 でなければ、関係する関数を実行しデータの処理を続けListViewに表示する

     => 0 の場合は、合致するデータがない旨をポップアップウインドウに表示する(赤白点線内)

 

                                                    ***********************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 2)

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 1)

 


MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 2)

2024-10-16 07:20:31 | 日記

先日、2024年のノーベル平和賞が、日本被団協に授与されましたので、早速アプリ「Nobel Prize Laureates 1」で「平和賞」、「2024」で検索してみると、(アプリの対象年度に2024を追加)

                                                       

上記の通り団体の名前が表示されない。

一方、1974年の平和賞を検索すると、佐藤栄作氏とショーン・マクブライド氏の情報が表示された。

                                                       

データベースより取得したJSONデータを見てみると、対象が団体と個人の場合でキーの名前が異なっていることが判明。

平和賞は、団体に対しても授与されるが、団体が受賞した場合は、fullNameの代わりにorgNameがキーとなっていることがわかった。

                                         

また、受賞年度によっては、同じ分野の受賞対象が個人と団体双方が含まれていることもある。

アプリ実行のビデオ:

スクリーンデザイン:

以下の通り、前回と変更点なし。

                                                           

                                                  

ブロック・コード:

変更、追加部分のみ。

1. 変数laureateTypeを新規に設定。受賞の対象が団体(organization)か個人(person)を識別する。

2. 取得したJSONデータより、laureateID, fullName(団体の場合は、orgName), birthDate(団体の場合は、設立年のデータを持っている founded), category(受賞分野), awardYear(受賞年), motivation(功績), websummaryURL(受賞者/団体に関するデータをもつウエッブサイトのURL)を取り出す。

上記データは、laureate(受賞個人又は団体)ごとにJSONデータより一つのかたまりとして取り出すが、この際、fullName, birthDateについては、このかたまりの項目のキーに「orgName」が含まれているかどうかをチェックして、含まれている場合は、fullNameではなくorgNameのデータを、birthDateではなくfoundedのデータを、fullNameListとbirthDateListに追加していくこととした。(下図の赤黄点線部分)

拡大すると以下の通り。

                       

他の項目については、対象が個人、団体に関係なくキーの名前が同じなのでチェックの必要はなし。

                              ************* 以下続くが、省略。***************

3. 各項目のデータのlistから、若干体裁を整えてListViewに表示するデータを作成することとなるが、個人が生まれた年月日には「Born on」を、団体の設立年には「Founded on」をそれぞれのデータの前に表示するようにした。

この際、変数laureateTyepを利用し、対象が団体(organization)か個人(person)、どちらなのかをチェックし、「Born on」「Founded on」のいずれを表示すべきかを決めるようにした。

上記赤黄点線内を拡大表示すると以下の通り。

           

4. なお、個人と団体が同じ分野で受賞した時の例として、以下のURLをクリックすれば2022年の平和賞のJSONデータで確認することができる。(参考まで)

      https://api.nobelprize.org/2.1/laureates?nobelPrizeYear=2022&nobelPrizeCategory=pea

言うまでもないことだが、raw dataとして取得することとなり、このままでは見にくかもしれないので、JSON Formatter & Validator などの変換サイトにcopy & pasteをするか、Chromeのextension "JSON Formatter" などを利用すると見やすくなる。

                                                    ***********************************************************

今回判明した今後の課題:

前回は、「birthPlace」(生誕地)のデータも表示したが、今回は省いた。団体の場合は、個人の「birthPlace」(生誕地)に対応するのが「所在地」となる。この団体の所在地については、複数のキーが存在しており、受賞団体によって、使用されるキーが異なるようで、この対応について次回以降検討予定。対処方法が見つかればアプリに反映し、生誕地又は所在地を追加したい。

                                                    ***********************************************************

前回までのブログ:

MIT App Inventor 2で遊ぶ (Nobel Prize Laureates 1)