☆☆ 新着記事 ☆☆

2020年5月28日木曜日

複数のfetch関数を使って、複数のプロミスを取得する - Promise.all()



Promise.all takes an array of promises (it technically can be any iterable, but is usually an array) and returns a new promise.


let promise = Promise.all([...promises...]);

下記の例では、fetchesのアレイが全て満たされるまで、.then()以下の処理は待機している。


function getMultipleURLs() {

  let array = new Array;
  var fetches = [];

  for (let i = 49; i <51; i++)
    fetches.push(
      fetch("https://coronavirus-tracker-api.herokuapp.com/v2/locations/"+i)
      .then(res => {return res.json(); })
      .then(function(data){

            array.push(data.location.timelines.confirmed.timeline);
            console.log(data.location.timelines.confirmed.timeline); //Output1:
          }
      )
      .catch(status, err => {return console.log(status, err);})
    );
  }
  Promise.all(fetches).then(function() {
    console.log (Object.keys(array[0]).length);
  });
  }


#Output1
{2020-01-22T00:00:00Z: 1, 2020-01-23T00:00:00Z: 9, 2020-01-24T00:00:00Z: 15, 2020-01-25T00:00:00Z: 39, 2020-01-26T00:00:00Z: 60, …}
{2020-01-22T00:00:00Z: 14, 2020-01-23T00:00:00Z: 22, 2020-01-24T00:00:00Z: 36, 2020-01-25T00:00:00Z: 41, 2020-01-26T00:00:00Z: 68, …}
#Output2
127

(参考)

Promise API

https://javascript.info/promise-api

How to use fetch within a for-loop, wait for results and then console.log it


**実際にコードを使ってみた。
他の国は、国別に感染者数、死亡者数がまとまっているけど、中国だけは省ごとに複数のAPIがあるので、全部Fetchして、取得したValueを合算しなければいけなかった、という県です。


function getCN() {
  let array = new Array;
  let array_death = new Array;
  let update = new Array;
  var fetches = [];
  for (let i = 49; i <82; i++) {
    fetches.push(
      fetch("https://coronavirus-tracker-api.herokuapp.com/v2/locations/"+i)
      .then(res => {return res.json(); })
      .then(function(data){ 
            array.push(data.location.timelines.confirmed.timeline);
array_death.push(data.location.timelines.deaths.timeline);
update = data.location.last_updated;
          })
      .catch(status, err => {return console.log(status, err);})
    );
  }//fetchのfor Loopの終り
 
  Promise.all(fetches).then(function() {
  //////////New Patients///////////////
all_values=[]
for( let i=0; i< Object.keys(array).length; i++){
all_values.push(Object.values(array[i]))
}

var latest_patients_sum = 0
var yesterday_patients_sum = 0
var two_days_ago_patients_sum =0
var seven_days_ago_patients_sum=0
var two_weeks_ago_patients_sum=0
for(let i =0; i < all_values.length; i++){
//Today's patients sum
latest_len = all_values[i].length-1
latest_patients_sum +=  parseInt(all_values[i][latest_len])
//yesterday's patients sum
yesterday_patients_sum +=  parseInt(all_values[i][latest_len-1])
//Two days ago's patients sum
two_days_ago_patients_sum +=  parseInt(all_values[i][latest_len-2])
//seven_days_ago's patients sum
seven_days_ago_patients_sum +=  parseInt(all_values[i][latest_len-7])
//two_weeks_ago's patients sum
two_weeks_ago_patients_sum +=  parseInt(all_values[i][latest_len-14])
};

document.getElementById('countryName').innerHTML = "China";
let population = 1392730000;
document.getElementById('population').innerHTML = population.toLocaleString('en');

document.getElementById('update').innerHTML = update.substr(0, 10);

document.getElementById('cases').innerHTML = latest_patients_sum.toLocaleString('en');
document.getElementById('cases_per100KCapita').innerHTML = ((Number(latest_patients_sum)/Number(population))*100000).toLocaleString('en',{minimumFractionDigits: 2, maximumFractionDigits: 2});

let today_new_patients =latest_patients_sum - yesterday_patients_sum;
document.getElementById('new_patients').innerHTML = today_new_patients.toLocaleString('en');

let yesterday_new_patients = yesterday_patients_sum - two_days_ago_patients_sum;
document.getElementById('yesterday_new_patients').innerHTML =yesterday_new_patients.toLocaleString('en');
let oneWeek_new_patients = latest_patients_sum - seven_days_ago_patients_sum;
document.getElementById('oneWeek_new_patients').innerHTML =oneWeek_new_patients.toLocaleString('en');
let twoWeeks_new_patients = seven_days_ago_patients_sum - two_weeks_ago_patients_sum;
document.getElementById('twoWeeks_new_patients').innerHTML =twoWeeks_new_patients.toLocaleString('en');

  //////////New deaths///////////////
all_values_death=[]
for( let i=0; i< Object.keys(array_death).length; i++){
all_values_death.push(Object.values(array_death[i]))
}

var latest_deaths_sum = 0
var yesterday_deaths_sum = 0
var two_days_ago_deaths_sum =0
var seven_days_ago_deaths_sum=0
var two_weeks_ago_deaths_sum=0
for(let i =0; i < all_values_death.length; i++){
//Today's deaths sum
latest_len = all_values_death[i].length-1
latest_deaths_sum +=  parseInt(all_values_death[i][latest_len])
//yesterday's deaths sum
yesterday_deaths_sum +=  parseInt(all_values_death[i][latest_len-1])
//Two days ago's deaths sum
two_days_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-2])
//seven_days_ago's deaths sum
seven_days_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-7])
//two_weeks_ago's deaths sum
two_weeks_ago_deaths_sum +=  parseInt(all_values_death[i][latest_len-14])
};

document.getElementById('deaths').innerHTML = latest_deaths_sum.toLocaleString('en');
document.getElementById('deaths_per100KCapita').innerHTML = ((Number(latest_deaths_sum)/Number(population))*100000).toLocaleString('en',{minimumFractionDigits: 2, maximumFractionDigits: 2});

let today_new_deaths =latest_deaths_sum - yesterday_deaths_sum;
document.getElementById('new_deaths').innerHTML = today_new_deaths.toLocaleString('en');
console.log(today_new_deaths)
let yesterday_new_deaths = yesterday_deaths_sum - two_days_ago_deaths_sum;
document.getElementById('yesterday_new_deaths').innerHTML =yesterday_new_deaths.toLocaleString('en');
let oneWeek_new_deaths = latest_deaths_sum - seven_days_ago_deaths_sum;
document.getElementById('oneWeek_new_deaths').innerHTML =oneWeek_new_deaths.toLocaleString('en');
let twoWeeks_new_deaths = seven_days_ago_deaths_sum - two_weeks_ago_deaths_sum;
document.getElementById('twoWeeks_new_deaths').innerHTML =twoWeeks_new_deaths.toLocaleString('en');

document.getElementById('percent').innerHTML = ((latest_deaths_sum/latest_patients_sum)*100).toLocaleString("en", {minimumFractionDigits: 2, maximumFractionDigits: 2}) + "%";

  }); //Promise.allのfunctionと.thenの終り

  }


**メモ 最初に作成:Promise.all()を使わないと、順番が守られないのでダメだったコード

num_patientsをfor loopを実行した後で、
 console.log("Loop外の書き込みたい"+num_patients)
  document.getElementById("countryCode").innerHTML = num_patients;
を実行したいが、実際にはfor loopの前に実行されて 0 が返る。

for (var i =49 ; i<= 50; i++){
alert(i)
var num_patients = []
url = 'https://coronavirus-tracker-api.herokuapp.com/v2/locations/'+i
fetch(url)
.then(function(resp) { return resp.json() })
.then(function(data) {
///Get Timeline Length
let latest_timeline_len = Object.keys(data.location.timelines.confirmed.timeline).length;
alert("長さ"+latest_timeline_len)
///New Patients Object
let latest_patients = data.location.timelines.confirmed.timeline
/// List of Patients Object Value
let list_num_patients = []
for( var item in  latest_patients ) {
list_num_patients.push(latest_patients[item]);
}
let confirmedCases =  list_num_patients[latest_timeline_len-1];

num_patients.push(confirmedCases)
console.log(i+ "回目:" + num_patients)

}) // 1つのfetchを処理する2つめの .then()の終了
 .catch(status, err => {return console.log(status, err);})
}// getCNの fetch()を繰り返す回数の End of For Loop
 console.log("Loop外の書き込みたい"+num_patients)
  document.getElementById("countryCode").innerHTML = num_patients;
  });

JavaScript関数のまとめ記事 -return, call back


参考)Pythonの関数はこちら

Python 関数 引数と戻り値,変数の引き渡しを中心に




1. 書式 (return value)


function 関数名(仮引数1, 仮引数2){
  //色々な処理
 return 関数の返り値;
}

返り値はFunctionの実行の結果を返す。他のFunctionで呼び出した時に便利。

例)return値を呼び出した関数で使用する。

function setup(){
var km =
milesToKm(26.3);
console.log(km)
var km2 =
milesToKm(100);
console.log(km2)
}

function
milesToKm(miles){
var km = miles*1.6
return km;
}

setup()
setup関数が呼び出しされると、26.3をmilesToKm関数の引数とした処理が行われる。
milesToKm関数では、 miles*1.6 の結果をkmという変数に代入する処理がなされると努同時に、この関数のreturn値としてkmを返す、という処理がなされている。

milesToKm()内の引数 milesは、milesToKm()に与えられた引数を、同funtionの中ではmilesという名前で使います。という宣言。 今回は1.6倍している。

return statementがないと、Line console.log(km)がundefinedというエラーになる。
milesToKm()内で引数を与えないと、NaNというreturnになる。

このような使い方もできる。

function multiply(a){
  var b = a*3;
  return b;
  }
 document.write(multiply(5));

この場合もreturn statementがないと、undefinedが返る。



参考)return値を使用しないでvalueを別の関数に渡す。

function validate(){
   var x = 2;
   document.write(x + '\n'); //output: 2
   add(x)   //add()をCall
   console.log(x); //output: 2
   }

 function add(a){
  var y = 2;
  var z = a+y;
  document.write(z); //output: 3
  }

validate()



2. Call Back 関数
コールバック関数とは、ある関数の引数として利用されている関数。 関数を引数として利用している関数を高階関数という
イベントハンドラ―の
buton.addEventListener("click", function(){})などが代表例。

書式)
function 高階関数(コールバック関数){
 コールバック関数();
}

例)
const sandwich =["Tuna","Beef", "Egg"]
sandwich.forEach(function(item){
 console.log(item)
}); 

//output:
Tuna
Beef
Egg

2020年5月25日月曜日

Pythohn 文字列の配列 join(), split(), slice() , strip()メソッド


'間に挿入する文字列'.join([連結したい文字列のリスト])


l = ['aaa', 'bbb', 'ccc']

s = ''.join(l)
print(s)
# aaabbbccc

s = ','.join(l)
print(s)
# aaa,bbb,ccc

s = '-'.join(l)
print(s)
# aaa-bbb-ccc

s = '\n'.join(l)
print(s)
# aaa
# bbb
# ccc


(使用例)

各県別の数字をリスト形式でまとめておいて、結果を一気にプリントする時などに使える。

for i in range(0,5):
    today_num=length-(47-i)
    yesterday_num=length-(47*2-i)
    twoDaysAgo_num =length-(47*3-i)
    sevenDaysAgo_num =length-(47*7-i)

    ##新規人数
    today_People = int(data[today_num]["People "])
    yesterday_People  =int(data[yesterday_num]["People "])
    twoDaysAgo_People  = int(data[twoDaysAgo_num]["People "])
    sevenDaysAgo_People  = int(data[sevenDaysAgo_num]["People "])

    today_new_People  = today_People  - yesterday_People
    yesterday_new_People = yesterday_People - twoDaysAgo_People
    sevenDays_new_People  = today_People -  sevenDaysAgo_People

    comment_loop.append( "\n"+ data[today_num]["prefectureNameJ"] + "\n"+"新規人数: "+ str(today_new_People ) +"人" + "(前日: " + str(yesterday_new_People ) +"人)\n1週間計: " + str(sevenDays_new_People ) +"人")

text = ''.join(comment_loop)
print(text)

#output
5月23日24時現在
埼玉県
新規人数: 1人(前日: 1人)
1週間計: 11人
千葉県
新規人数: 0人(前日: 0人)
1週間計: 6人
東京都
新規人数: 2人(前日: 3人)
1週間計: 36人
神奈川県
新規人数: 0人(前日: 7人)
1週間計: 71人


'文字列を分割する' .split([分割したい文字列のリスト])
splitメソッドは、文字列型(String)オブジェクトを分割する

mystr = 'Hello world! This is a sample'
res = mystr.split(' ') // 空白で分割
print(res) // ['Hello', 'world!', 'This', 'is', 'a', 'sample']

改行(\n)やタブ(\t)を表示させないようにするには、引数を指定しない。
res1 = mystr.split()


res = url.split('/') // スラッシュで分割


' Pythonのシーケンスの一部分を取り出す操作' .slice([開始, 終了, 増分])
https://note.nkmk.me/python-slice-usage/



'前後の文字を削除する '.strip (削除したい文字)

Strip method
data = ["abc","bda","aabbcc","Eca","EcaD"]

for i in data:
    print(i)
    a = i.strip('a''c')
    print(a)

abc (前後は削除可)
b

bda(後は削除可)
bd

aabbcc(最前、最後尾の文字に連続していれば削除可)
bb

Eca(最前、最後尾の文字に連続していれば削除可)
E

EcaD(最前、最後尾の文字に連続していないので削除不可)
EcaD

例)
data = ["(-0.23%)","(+0.52%)","(-0.13%)","(+0.41%)"]


for i in data:
    print(i)
    a = float(i.strip('(  '' %'' )')) # %と「」を除いたStringにしてfloatで少数に。
    if a > 0:
        print('plus')
    else:
        print('negative') #マイナスの判断も可。

2020年5月23日土曜日

PythonでJSONを扱ってみる -テキスト・ロカールファイル・API


JSONとは:
KeyとValueのペア(連想配列、オブジェクト)

例)

let item = {
"id":1,
"name":"N95 Mask",  //文字列は必ず” ” で表記
"available": ["Tokyo", "Osaka"],
"time":{ "quick":"in 3hrs","normal":"in 24hrs", "best effort": "3 days"},
"order":{"Basic":{"hospital":"100 Yen", "retailer":"200 Yen", "consumer":"300Yen"}}
}


{ }で区切るとオブジェクトを表す。
[  ]は配列を表す

各Valueには、ドットでアクセス
console.log(item.available) #  ["Tokyo", "Osaka"]
console.log(item.available[0]) #Tokyo
console.log(item.time) #{quick: "in 3hrs", normal: "in 24hrs", best effort: "3 days"}
console.log(item.time.quick) # in 3hrs
console.log(item.order.basic) #{hospital: "100 Yen"}
console.log(item.order.basic.hospital) #100 Yen

sample jason dataset

people_string='''
{
    "people":[
        {"name":"Wayne Rigsby",
         "phone":"123-456-789",
         "emails":["wayne@cbi.com", "wayne2@cbi.com"],
         "has_license":true},
        {"name":"Patric Jane",
         "phone":"987-654-321",
         "emails":null,
         "has_license":false}
              ]
    }'''


*JSONファイルを辞書として読み込み
json.load()

*辞書をJSON文字列として整形して出力
json.dumps()
区切り文字を指定: 引数separators
デフォルトではキーと値の間が:、要素間が,で区切られる。
print(json.dumps(d, separators=(',', ':')))

インデントを指定: 引数indent
print(json.dumps(d, indent=4))
キーでソート: 引数sort_keys
print(json.dumps(od, sort_keys=True))

Unicodeエスケープ指定: 引数ensure_ascii
print(json.dumps(od, ensure_ascii=False))


*Javascript ObjectをJSONに変換するJS
JSON.stringify(item)

*JSONをJavascript Objectに変換するJS
JSON.perse(item)

1.  jsonフォーマットのテキストデータをjson objectに変換する

import json /// <-標準ライブラリ・インストール不要
data=json.loads(people_string)

print(people_string)だとテキストとしてそのままprintされる
{
    "people":[
        {"name":"Wayne Rigsby",
         "phone":"123-456-789", .....

print(data)だと以下のようなリスト型のjsonフォーマットに変換されていることが確認できる。
    }
{'people': [{'name': 'Wayne Rigsby', 'phone': '123-456-789', 'emails': ['wayne@cbi.com', 'wayne2@cbi.com'], 'has_license': True}, {'name': 'Patric Jane', 'phone': '987-654-321', 'emails': None, 'has_license': False}]}

*リスト型なのでfor loopで取り出せる
for person in data['people']: /// キーで指定
    print(person) ///output1
  print(person['name'])///output2

///output1
{'name': 'Wayne Rigsby', 'phone': '123-456-789', 'emails': ['wayne@cbi.com', 'wayne2@cbi.com'], 'has_license': True}
{'name': 'Patric Jane', 'phone': '987-654-321', 'emails': None, 'has_license': False}

///output2
Wayne Rigsby
Patric Jane

*キーを指定して削除もできる
for person in data['people']:
    del person['phone']
    print(person)

{'name': 'Wayne Rigsby', 'emails': ['wayne@cbi.com', 'wayne2@cbi.com'], 'has_license': True}
{'name': 'Patric Jane', 'emails': None, 'has_license': False}

#辞書型の取り扱いは


2. Pythonオブジェクトをjsonフォーマットのテキストをに変換す


data=json.loads(people_string)
new_string =json.dumps(data)
print(new_string)
{"people": [{"name": "Wayne Rigsby", "phone": "123-456-789", "emails": ["wayne@cbi.com", "wayne2@cbi.com"], "has_license": "true"}, {"name": "Patric Jane", "phone": "987-654-321", "emails": "null", "has_license": "false"}]}

new_string =json.dumps(data, indent=2,sort_keys=True) ///読みやすいようにするオプション
{
  "people": [
    {
      "emails": [
        "wayne@cbi.com",
        "wayne2@cbi.com"
      ],
      "has_license": "true",
      "name": "Wayne Rigsby",
      "phone": "123-456-789"
    },
    {
      "emails": "null",
      "has_license": "false",
      "name": "Patric Jane",
      "phone": "987-654-321"
    }
  ]
}


3.  ローカルのJSONファイルを扱う


jsonファイルはこちら
https://raw.githubusercontent.com/CoreyMSchafer/code_snippets/master/Python-JSON/states.json

{
  "states": [
    {
      "name": "Alabama",
      "abbreviation": "AL",
      "area_codes": ["205", "251", "256", "334", "938"]
    },
    {
      "name": "Alaska",
      "abbreviation": "AK",
      "area_codes": ["907"]
    },....
 ]
}

これをローカルフォルダに置いておく。

(読み込む)
import json

**Python Objectとして開く
with open('states.json') as f:
    data = json.load(f)  /// 先述のjson.loadsと混同しない


for state in data['states']:
    print(state['name'],state['abbreviation'])
Alabama AL
Alaska AK
Arizona AZ......


(新しいJSONファイルとして保存)
with open('states.json') as f:
    data = json.load(f)

for state in data['states']:
    del (state['area_codes'])

with open('new_states.json', w) as f:
     json.dump(data, f, indent=2)


4.  APIで取得されるJSONデータを扱う

(ここで使われているyahoo APIは、現在は利用できない)

import json
from urllib.request import urlopen

with urlopen("https://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json") as response:
    source = response.read()

print(source) ///この段階ではタグ情報も一杯。


data = json.loads(source)

# print(json.dumps(data, indent=2))///これで可読な形式に。本当に便利

usd_rates = dict()

"""
APIのJSONは
{
 "list":{
   "meta":{
     "type":"resource-list",
     "start":"0",
     "count"="188"
  },
 "resources":[
   {
     "resource":{
           "classname": "Quote",
           "fields": {
                "name":"USD/KW\RW",
                "price" : "1095.34997"      ...
               }
       }.................

]
と続いていく
////

print(len(data['list'][ "resources"]))
#188

usd_rates = dict()
for item in data['list']['resources']:
    name = item['resource']['fields']['name']
    price = item['resource']['fields']['price']
    usd_rates[name] = price
    usd_name[name] = price   ///nameをキー値、priceをvalueにした辞書作成


print(50 * float(usd_rates['USD/EUR'])) ///50ドルをEURにしてみる。文字列なのでフロートに



こんな例も
#!/usr/bin/env python
try:
    # For Python 3.0 and later
    from urllib.request import urlopen
except ImportError:
    # Fall back to Python 2's urllib2
    from urllib2 import urlopen

import json

def get_jsonparsed_data(url):
    response = urlopen(url)
    data = response.read().decode("utf-8")
    json_data = json.loads(data)
 
   
    return  print(json.dumps(json_data, indent=3))

url = ("https://financialmodelingprep.com/api/v3/stock/gainers?demo")
print(get_jsonparsed_data(url))


2020年5月22日金曜日

CRON設定の際に気を付けること  ファイルディレクトリと複数コマンド


1. Fileの参照ディレクトリ
2. 複数コマンドを1文で記述する



1. Fileの参照ディレクトリ

結論から言うと、CRONで実行するアプリの中にファイル参照があれば、それは全て絶対パスで記述する、という事。
相対パスは /root フォルダになっています。

例えば、CSVファイルをJSONに変換する簡単なPython アプリがあったとします。

記述は
**JSON_CONV.py
import csv
import json
new_data=[]
with open("sample.csv",'r') as f: #,encoding='utf-8_sig'
     reader = csv.DictReader(f)
     for line in reader:
         new_data.append(line)
with open('sample.json', 'w') as f:
    json.dump(new_data, f)

この記述は、コマンドラインからアプリを実行する場合、sample.csvとアプリファイルが同一フォルダ内にあれば、動きます。

これをCRON経由で実行すると、参照は rootユーザでログインしていれば、./rootフォルダ 。各ユーザ権限でログインしていれば、./home配下の各ユーザディレクトリになります。

絶対パスで記述しましょう。

2. 複数コマンドを1文で記述する

コマンド1 || コマンド2
コマンド1が異常終了ならコマンド2を実行
$> ls hello.txt || echo "Hello!" > hello.txt
hello.txtが存在しなければ、文字列"Hello!"をhello.txtに出力して生成.

コマンド1 && コマンド2
$> ls hello.txt && rm -f hello.txt
hello.txtが存在したら、hello.txtを削除.

"[ 条件式 ]"の利用
$> [ -f hello.txt ] || echo "Hello!" > hello.txt
$> [ -f hello.txt ] && rm -f hello.txt
[ -f hello.txt ] は "hello.txtがファイルである"->真. ファイルでない/存在しない->偽.
シェルスクリプト 基本サイトで検索

コマンド1; コマンド2
$> ls hello.txt; cp hello.txt yeah.txt
hello.txtの有無を確認し、その結果に関わらずhello.txtのコピーをyeah.txtとして生成する。hello.txtがない場合、それにも関わらずコピーしようとするので後者cpコマンドはエラー.

コマンド1 | コマンド2
コマンド1の出力をコマンド2の入力として実行
$> ps aux | grep ntpd
プロセス一覧リストを出力して、そのうち"ntpd"が含まれる行を出力.

2020年5月21日木曜日

CSVからJSONに変換してみる


Pythonで。

sample.csv


yearmonthdatenameMathChemistryHistory
202031Charlie506070
202031Ben525966
202031Jeniffer908575
202042Charlie607080
202042Ben576471
202042Jeniffer858070
202053Charlie708090
202053Ben626976
202053Jeniffer797464

Step1. CSVファイルの読み込み。

import csv
with open("sample.csv",'r',encoding='utf-8_sig') as f:
    reader = csv.DictReader(f)
    for line in reader:
        print(line)
//Output
OrderedDict([('year', '2020'), ('month', '3'), ('date', '1'), ('name', 'Charlie'), ('Math', '50'), ('Chemistry', '60'), ('History', '70')])
OrderedDict([('year', '2020'), ('month', '3'), ('date', '1'), ('name', 'Ben'), ('Math', '52'), ('Chemistry', '59'), ('History', '66')])
OrderedDict([('year', '2020'), ('month', '3'), ('date', '1'), ('name', 'Jeniffer'), ('Math', '90'), ('Chemistry', '85'), ('History', '75')])
OrderedDict([('year', '2020'), ('month', '4'), ('date', '2'), ('name', 'Charlie'), ('Math', '60'), ('Chemistry', '70'), ('History', '80')])
OrderedDict([('year', '2020'), ('month', '4'), ('date', '2'), ('name', 'Ben'), ('Math', '57'), ('Chemistry', '64'), ('History', '71')])................

*1行目にヘッダーがなく自分で指定したい場合
keys = ('column1', 'column2', 'column3')
with open('sample.csv', 'r') as f:
    for line in csv.DictReader(f, keys):
で、指定できる。

Step2. リストに格納

import csv
new_score=[]
with open("sample.csv",'r') as f:
     reader = csv.DictReader(f)
    
     for line in reader:
         new_score.append(line)

Step3: JSONファイルとして書き出し

import csv
import json
new_score=[]
with open("sample.csv",'r',encoding='utf-8_sig') as f:
     reader = csv.DictReader(f)
     for line in reader:
         new_score.append(line)
with open('sample.json', 'w') as f:
    json.dump(new_score, f)



2020年5月19日火曜日

Blogger WidgetをMobileに表示させる方法


Step1.テーマ->モバイルテーマの選択でカスタマイズを選択し保存




Step2.テーマ->HTMLの編集->ウィジェットへの移動から、モバイル表示の可否を設定したいウィジェットにとぶ。


Step3.テーマ->HTMLの編集->ウィジェットへの移動から、モバイル表示の可否を設定したいウィジェットに移動。

ウィジェットの記述は、以下ののように 'id' と 'タイトル' が書かれているので特定できる。

(例)
  <b:widget id='BlogArchive1' locked='false' title='ブログ アーカイブ' type='BlogArchive'>

locked ='false' の後に、Mobile='yes'  や Mobile='only' を 加える

<b:widget id='BlogArchive1' locked='false' Mobile='yes'  title='ブログ アーカイブ' type='BlogArchive'>

以上


(参考)
https://newblogadviser.blogspot.com/2017/05/show-blogger-widgets-in-mobile-view.html

2020年5月16日土曜日

JavaScriptでapiをFetchしてみる(1)

https://www.youtube.com/watch?v=Oive66jrwBs


◇ Step1 : ローカルのテキストファイルからFetchする

◇ Step2: JSONファイルからFetchする

◇ Step3: APIからFetchする

◇ 参考:最終版全体



*JSONファイルを読み込む為のfetch関数は、httpのやりとりが必要になります。
*この作業はgetElementByIdを使っていて、httpのやりとりが必要になります。
サーバー環境で試験されるか、ローカルであればXAMPなどの仮想サーバー環境を構築しておく必要があります。
https://www.granfairs.com/blog/staff/apache-vhost-2017
自分はXAMPで。 フォルダは
C:\xampp\htdocs
で。



◆  Step1 : ローカルのテキストファイルからFetchする


*fetch()はAPIで、利用するにはサーバー環境が必要です。ローカルPCにjsonファイルを置いて  fetch('users.json')としても機能しません。fetchでresponse.json()関数を呼び出すことで、レスポンスのデータを自動でJavaScriptオブジェクトに変換してくれます。

(基本構文)
fetch('http://example.com/sample.json')
 .then(response => response.json())
 .then(data => console.log(data));

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch


(ボタンの設置)

   <button id="getText"> Get Text </button>
   <button  id="getUsers"> Get JSON </button>
   <button  id="getPosts"> Get API DATA </button>


(イベント・リスナーの設置)
 <script>
    document.getElementById('getText').addEventListener('click', getText);
    document.getElementById('getUsers').addEventListener('click', getUsers);
    document.getElementById('getPosts').addEventListener('click', getPosts);
    document.getElementById('addPost').addEventListener('submit', addPost);
 </script>

document.getElementById('getText').addEventListener('click', getText);



(スクリプトの作成)
getText : ボタンがクリックされた時に挙動するFunction

*手順1 : Consoleに表示させてイベントリスナーの挙動確認

function getText(){
 console.log(123);
    }


*手順2 : Textファイルから文字をFetchする(プロミスの処理まで)

function getText(){
  fetch('sample.txt')
    .then( function(res){
    console.log(res);
       })
 }

 1)   fetch('  ')
      fetch( )の引数には取得するファイル名、又はURL
      今回はsample.text ファイル

 2) . then( )
     fetch( ) 関数はプロミス(プレースフォルダーのようなもの)を返す。
    このプロミス(レスポンス)をどう処理するかを指定する。
   fetch( ).then() と1行で記述することも可能。
   レスポンスを処理する関数は、function(res) という名前(resはresponseの略)で表現されるのが一般的。

 .then( function(res){
    console.log(res);
       })
  

PromiseのValue(テキスト形式)の取得
 .then( function(res){
    console.log( res.text( ) );
       })


PromiseのValue(json形式)の取得
 .then( function(res){
    console.log( res.json( ) );
       })

*text()やjson()は、レスポンス・オブジェクトをテキスト・オブジェクトやJSONオブジェクトに変更するmixin

PromiseのValue(テキスト形式)のデータ取得
 .then( function(res){
  return res.text() ;
  })
 .then( function(data){
     console.log(data) ;
  })

又は
(Arrow Functionを使った書き方)
   function getText(){
  fetch('sample.txt')
  .then((res) => res.text( ))
  .then((data) => console.log(data))
  }

同じ結果。
(jsonは)
fetch("./sample.json")
.then(function(resp){
return resp.json()})
.then(function(data){
console.log(data)});
又は
fetch("./sample.json")
.then(results => results.json())
.then(console.log);




 3) 上記の結果をHTMLに表示
クリックボタン
   <button id="getText"> Get Text </button>
直下に
<div id="output"></div>

 function getText(){
 fetch('sample.txt')
  .then((res) => res.text())
  .then((data) => {
     document.getElementById('output').innerHTML = data;
 })
 }

 Step2: JSONファイルからFetchする

(イベント・リスナーの設置)
 <script>
    document.getElementById('getText').addEventListener('click', getText);
    document.getElementById('getUsers').addEventListener('click', getUsers);
    document.getElementById('getPosts').addEventListener('click', getPosts);
    document.getElementById('addPost').addEventListener('submit', addPost);
 </script>

 document.getElementById('getUsers').addEventListener('click', getUsers);

*手順 : JSON形式のデータをFetchする(読み込み処理まで)

 function getUsers(){
 fetch('users.json')
  .then((res) => res.json())
  .then((data) => {
    let output = '<h2>Users</h2>';   <!-- 変数 -->
     console.log(data) ;
 })
 }



*手順 : JSON形式のデータをFetchする(読み込み処理まで)

   function getUsers(){
      fetch('users.json')
      .then((res) => res.json())
      .then((data) => {
        let output = '<h2 class="mb-4">Users</h2>';
        data.forEach( function(user){
          output += ` <!-- イテレーション バックチック キーボードでは、Shiftキー + @ ボタン-->
            <ul class="list-group mb-3">
              <li>ID: ${user.id}</li>  <!--変数を使う時には ${} サイン-->
              <li>Name: ${user.name}</li>
              <li>Email: ${user.email}</li>
            </ul>
          `;<!-- バックチックのend-->
        });
        document.getElementById('output').innerHTML = output;
      })
    }
(他のLoopのさせ方)
https://youtu.be/FN_ffvw_ksE?t=690




 Step3: APIからFetchする


  function getPosts(){
      fetch('https://jsonplaceholder.typicode.com/posts')
      .then((res) => res.json())
      .then((data) => {
        let output = '<h2>Posts</h2>';
        data.forEach(function(post){
          output += `
            <div>
              <h3>${post.title}</h3>
              <p>${post.body}</p>
            </div>
          `;
        });

        document.getElementById('output').innerHTML = output;
      })
    }


おまけ: APIを使ってデータをポストする


  <form id="addPost">
    <input type="text" id="title"  placeholder="Title">
     <textarea id="body" placeholder="Body"></textarea>
    <input type="submit" value="Submit">
 </form>

document.getElementById('addPost').addEventListener('submit', addPost);

<script>
   function addPost(e){
      e.preventDefault(); <!--実際にPostしないように-->

      let title = document.getElementById('title').value;
      let body = document.getElementById('body').value;

      fetch('https://jsonplaceholder.typicode.com/posts', {
        method:'POST',
        headers: {
          'Accept': 'application/json, text/plain, */*',
          'Content-type':'application/json'
        },
        body:JSON.stringify({title:title, body:body}) <!-- Stringに
      })
      .then((res) => res.json())
      .then((data) => console.log(data))
    }
</script>



◇ 参考:最終版全体

<html: index.html>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Fetch API Sandbox</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
</head>

<body>
  <div class="container">
    <h1 class="display-4 mb-4">Fetch API Sandbox</h1>
    <div class="d-flex">
      <button class="btn btn-primary mr-4" id="getText">Get Text</button>
      <button class="btn btn-success mr-4" id="getUsers">Get JSON</button>
      <button class="btn btn-warning mr-4" id="getPosts">Get API DATA</button>
    </div>
    <hr>
    <div id="output"></div>
    <form id="addPost">
      <div class="form-group">
        <input type="text" id="title" class="form-control" placeholder="Title">
      </div>
      <div class="form-group">
        <textarea id="body" class="form-control" placeholder="Body"></textarea>
      </div>
      <input type="submit" class="btn btn-secondary" value="Submit">
    </form>
  </div>

  <script>
    document.getElementById('getText').addEventListener('click', getText);
    document.getElementById('getUsers').addEventListener('click', getUsers);
    document.getElementById('getPosts').addEventListener('click', getPosts);
    document.getElementById('addPost').addEventListener('submit', addPost);

    function getText(){
      // fetch('sample.txt')
      // .then(function(res){
      //   return res.text();
      // })
      // .then(function(data){
      //   console.log(data);
      // });
      fetch('sample.txt')
      .then((res) => res.text())
      .then((data) => {
        document.getElementById('output').innerHTML = data;
      })
      .catch((err) => console.log(err)) <!-- errorをコンソール表示 -->
    }

    function getUsers(){
      fetch('users.json')
      .then((res) => res.json())
      .then((data) => {
        let output = '<h2 class="mb-4">Users</h2>';
        data.forEach(function(user){
          output += `
            <ul class="list-group mb-3">
              <li class="list-group-item">ID: ${user.id}</li>
              <li class="list-group-item">Name: ${user.name}</li>
              <li class="list-group-item">Email: ${user.email}</li>
            </ul>
          `;
        });
        document.getElementById('output').innerHTML = output;
      })
    }

    function getPosts(){
      fetch('https://jsonplaceholder.typicode.com/posts')
      .then((res) => res.json())
      .then((data) => {
        let output = '<h2 class="mb-4">Posts</h2>';
        data.forEach(function(post){
          output += `
            <div class="card card-body mb-3">
              <h3>${post.title}</h3>
              <p>${post.body}</p>
            </div>
          `;
        });
        document.getElementById('output').innerHTML = output;
      })
    }
    function addPost(e){
      e.preventDefault();
      let title = document.getElementById('title').value;
      let body = document.getElementById('body').value;
      fetch('https://jsonplaceholder.typicode.com/posts', {
        method:'POST',
        headers: {
          'Accept': 'application/json, text/plain, */*',
          'Content-type':'application/json'
        },
        body:JSON.stringify({title:title, body:body})
      })
      .then((res) => res.json())
      .then((data) => console.log(data))
    }
  </script>
</body>
</html>


<textファイル:sample.text>

I am a sample text file

<JSONファイル:users.json>

[
  {
    "id":1,
    "name":"Rick",
    "email":"rick@gmail.com"
  },
  {
    "id":2,
    "name":"Glenn",
    "email":"glenn@gmail.com"
  },
  {
    "id":3,
    "name":"Negan",
    "email":"negan@gmail.com"
  }
]


さん
https://www.youtube.com/watch?v=Oive66jrwBs

JavaScriptでapiをfetchしてみる(2)

https://www.youtube.com/watch?v=YgsVNIMgGZk

Step1. apiでFetch してみる。

<html>
<!DOCTYPE html>
<html>
<head>
<title>COVID Tracker</title>

<link rel="shortcut icon" href="corona.jpeg">
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="styles.css">
<script type="text/javascript" src="app1.js"></script>

</head>
<body>
<h1 class="title">COVID-19 Tracker</h1>
<h2 class="subtitle">The latest statistics regarding the "Corona Virus".</h2>
<div class="data-container">
<div class="stats-container">
<h4>Cases</h4>
<h1 id="cases"></h1>
<h4>Deaths</h4>
<h1 id="deaths"></h1>
<h4>% of Deaths</h4>
<h1 id="percent"></h1>
</div>
<div class="location-container">
<h4>Country</h4>
<h1 id="country">Japan</h1>
<h4>Population</h4>
<h1 id="population"></h1>
<h4>Last Updated</h4>
<h1 id="update"></h1>
</div>
</div>
<h1 class="footer">Information provided by <a href="https://systems.jhu.edu/research/public-health/ncov/">Johns Hopkins University</a></h1>
</body>
</html>

app.js (consoleに表示)

window.onload = function() {
getCovidStats();
}

function getCovidStats() {
fetch('https://coronavirus-tracker-api.herokuapp.com/v2/locations/139')
.then(function(resp) { return resp.json() })
.then(function(data) {
console.log(data);
})

.catch(function() {
console.log("error");
})
}

apiは
https://github.com/ExpDev07/coronavirus-tracker-api
All endpoints are located at coronavirus-tracker-api.herokuapp.com/v2/ and are accessible via https. For instance: you can get data per location by using this URL: https://coronavirus-tracker-api.herokuapp.com/v2/locations



'https://coronavirus-tracker-api.herokuapp.com/v2/locations/139'
で取得できるJSONデータ



app.js (完成版)

window.onload = function() {
 getCovidStats();
}
function getCovidStats() {
 fetch('https://coronavirus-tracker-api.herokuapp.com/v2/locations/139')
 .then(function(resp) { return resp.json() })
 .then(function(data) {
  let population = data.location.country_population;
  let update = data.location.last_updated;
  let confirmedCases = data.location.latest.confirmed;
  let deaths = data.location.latest.deaths;
  document.getElementById('population').innerHTML = population.toLocaleString('en');
  document.getElementById('update').innerHTML = update.substr(0, 10);
  document.getElementById('cases').innerHTML = confirmedCases.toLocaleString('en');
  document.getElementById('deaths').innerHTML = deaths.toLocaleString('en');
  document.getElementById('percent').innerHTML = ((Number(deaths)/Number(confirmedCases))*100).toLocaleString("en", {minimumFractionDigits: 2, maximumFractionDigits: 2}) + "%";


 })
 .catch(function() {
  console.log("error");
 })
 setTimeout(getCovidStats, 43200000) // update every 12 hours
}

 
 
setTimeout(getCovidStats, 43200000) // update every 12 hours
Windows.onloadでロードする都度、getCovidStats();をCallする設定にしたが、
このsetTimeout(関数名, ミリセコンド)は、最後の実行から指定したミリセコンドの間はCallされない。
 

2020年5月13日水曜日

SQLiteのコマンドラインから操作する。

SQLiteの操作方法はいくつかる。この投稿はSQLiteについているコマンドラインからの操作。
Python経由でSQliteを操作する場合、こちらの記事。

Sqlite3 の’SQL文’を使ってみる。


Windowsの場合、SQLite3.exeをダブルクリックするか、Toolをインストールする。
https://www.dbonline.jp/sqlite/

これらのコマンドツールが使用可能となる。
https://www.sqlitetutorial.net/sqlite-commands/


1) LINUX上で
[root@ueczshc7 admin]# sqlite3 msg.db <dbの存在するDIRでデータベースを指定して>

(別のDirectoryの場合、directoryを指定しても良い)
[root@ueczshc7 ~]# sqlite3 /var/xxxx/xxxx/xxxx/msg.db

SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables <dbに存在するdbテーブルの表示>
tw_msg  user


sqlite> .schema <dbに存在するテーブルのレコード表示>
CREATE TABLE user (
        id INTEGER NOT NULL,
        username VARCHAR(20) NOT NULL,
        email VARCHAR(120) NOT NULL,
        image_file VARCHAR(20) NOT NULL,
        password VARCHAR(60) NOT NULL,
        PRIMARY KEY (id),
        UNIQUE (username),
        UNIQUE (email)
);
CREATE TABLE tw_msg (
        id INTEGER NOT NULL,
        time VARCHAR(6),
        message VARCHAR(140),
        hashtag VARCHAR(140),
        url VARCHAR(140),
        length INTEGER,
        PRIMARY KEY (id),
        UNIQUE (id)
);


<dbに存在するテーブルの削除>
sqlite> .tables
hiyoko_msg   hiyokos_msg  tw_msg user
sqlite> drop table hiyokos_msg;
sqlite> .tables
hiyoko_msg  tw_msg  user


<テーブルに格納されたデータの確認>
sqlite> .mode column
sqlite> SELECT * FROM hiyoko_msg;
2           02:58       NY州が3月7日に都市封鎖をして既に2ヶ月以上。緩和に消極的 な知事やメディアに怒りが向かう。
プラカード: "コロナは無くならない。でも収入は確実になくなる。"
2ヶ月も封鎖が続けばこうなる。              https://twitter.com/KevinVesey/status/1261001977598808065  98


sqlite> .quit <終了>


2. Windowsで
sqlite3.exeを探してダブルクリック
シェルが立ち上がるので
.sqlite> .open c:\work\ex1.db

で、DBに接続させるらしいが自分のインストールしたsqlite3では .open コマンドはサポートされていないので諦める。

参考)

sqlite> .help
.backup ?DB? FILE      Backup DB (default "main") to FILE
.bail ON|OFF           Stop after hitting an error.  Default OFF
.databases             List names and files of attached databases
.dump ?TABLE? ...      Dump the database in an SQL text format
                         If TABLE specified, only dump tables matching
                         LIKE pattern TABLE.
.echo ON|OFF           Turn command echo on or off
.exit                  Exit this program
.explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.
                         With no args, it turns EXPLAIN on.
.header(s) ON|OFF      Turn display of headers on or off
.help                  Show this message
.import FILE TABLE     Import data from FILE into TABLE
.indices ?TABLE?       Show names of all indices
                         If TABLE specified, only show indices for tables
                         matching LIKE pattern TABLE.
.load FILE ?ENTRY?     Load an extension library
.log FILE|off          Turn logging on or off.  FILE can be stderr/stdout
.mode MODE ?TABLE?     Set output mode where MODE is one of:
                         csv      Comma-separated values
                         column   Left-aligned columns.  (See .width)
                         html     HTML <table> code
                         insert   SQL insert statements for TABLE
                         line     One value per line
                         list     Values delimited by .separator string
                         tabs     Tab-separated values
                         tcl      TCL list elements
.nullvalue STRING      Use STRING in place of NULL values
.output FILENAME       Send output to FILENAME
.output stdout         Send output to the screen
.print STRING...       Print literal STRING
.prompt MAIN CONTINUE  Replace the standard prompts
.quit                  Exit this program
.read FILENAME         Execute SQL in FILENAME
.restore ?DB? FILE     Restore content of DB (default "main") from FILE
.schema ?TABLE?        Show the CREATE statements
                         If TABLE specified, only show tables matching
                         LIKE pattern TABLE.
.separator STRING      Change separator used by output mode and .import
.show                  Show the current values for various settings
.stats ON|OFF          Turn stats on or off
.tables ?TABLE?        List names of tables
                         If TABLE specified, only list tables matching
                         LIKE pattern TABLE.
.timeout MS            Try opening locked tables for MS milliseconds
.trace FILE|off        Output each SQL statement as it is run
.vfsname ?AUX?         Print the name of the VFS stack
.width NUM1 NUM2 ...   Set column widths for "column" mode
.timer ON|OFF          Turn the CPU timer measurement on or off