PeaceJetのブログ

金融系の社内エンジニアをやりながら、マーケティングやプランナーなども

【Python3】URLかどうかを調べるスクリプト

URLかどうかを調べる

Python3で、正常にアクセスできるURLであるかどうかを調べるスクリプトを書いてみました。
フォームから受け取ったURLが正常なものかを判断する際の材料として、使っています。

※追加のモジュールとしてUrllib、reが必要になります。

#!/usr/bin/env python
# -*- coding: utf-8 -*- 

import re
import urllib.request as urllib

# URLをチェックする関数
def checkURL(url):

    if re.match(r"^https?:\/\/", url):
        try:
            response = urllib.urlopen(url)
            response.close()
            return True
        except urllib.HTTPError as e:
            print ("見つかりませんでした。:  " + url)
            return "HTTPError <<Code: " + str(e.code) + ">>"
        except urllib.URLError as e:
            print ("見つかりませんでした。:  " + url)
            return "URLError <<Reason: " + str(e.reason) + ">>"
    else:
        return "URLではありません。"

url = "(対象となるURLを入力してくださいね)"
result = checkURL(url)

if result == True:
    print ("アクセスOK")
else:
    print (result)

お役に立てれば幸いです。

【Googleスプレッドシート】完全一致した行の重複を削除する方法

行自体の重複を削除する方法

f:id:PeaceJet:20170826160539p:plain
※例によって個人情報の生成は疑似個人情報データ生成サービスを使用させていただきました。

Googleスプレッドシートで、データを管理している方は多いかと思いますが。
上記のように重複している行自体を削除したいという需要は結構あるのではないかと考えています。

しかし、なかなかネットで探してもセルの重複削除自体は出てくるのですが・・・
行そのものが完全一致したものの重複を除く方法がありませんでした。

そこで、「Google Apps script duplicate delete」などと検索したところgoogleの開発者向けドキュメントサイトで見つかりましたので紹介します。

解説

  1. 使用されているセルをgetDataRangeで配列に格納(2次元配列)
  2. 配列から一つずつ取り出し、それをdata.joinして文字列とします。
  3. newDataという新しい配列を用意し、newDataの配列要素をjoinして文字列とし、data.joinと比較します。
  4. データがなければ配列に追加し、あればスルーするという動作を繰り返すことで、ユニークなデータを保持します。
  5. 最後に、シート自体をクリアして貼り付けます。
function removeDuplicates() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var data = sheet.getDataRange().getValues();
  //配列比較用
  var newData = new Array();
  for(i in data){
    //2次元配列の要素(配列)をrowに代入
    var row = data[i];
    var duplicate = false;
    for(j in newData){
      if(row.join() == newData[j].join()){
        //重複していた場合、true
        duplicate = true;
      }
    }
    //もしも、newDataの中にデータがなければ(duplicate=false)なら、rowを追加。
    if(!duplicate){
      newData.push(row);
    }
  }
  sheet.clearContents();
  sheet.getRange(1, 1, newData.length, newData[0].length).setValues(newData);
}

感想

対象のデータ(配列)をjoinして文字列にし、比較するというアイデアは自分になかったので新鮮でした。

参考:
Tutorial: Removing Duplicate Rows in a Spreadsheet  |  Apps Script  |  Google Developers

Nature Remo 発売延期

楽しみに待っていたNatureRemoでしたが、機器の不具合が発覚したため発売を延期するとの連絡をいただきました。

nature.global

中途半端な製品を世に出せないという思い、共感いたします。

一旦、返金となるようですが、また発売日が決まったら申し込もうと思います。

【TensorFlow】TensorBoardでAttributeError

AttributeError: module 'tensorflow.python.training.training' has no attribute 'SummaryWriter'

上記のようなエラーが出た場合、'tensorflow.python.training.training'には 'SummaryWriter'属性は存在しません。
このように言われています。

ドキュメントを見てみると、2016年後半に機能がなくなっており、別のモジュールから呼び出さなければならないそうです。

import tensorflow as tf
sess = tf.Session()
tw = tf.train.SummaryWriter("log", graph=sess.graph)

上記を、下記のように変更してみましょう。
するとうまく行くはずです。

import tensorflow as tf
sess = tf.Session()
tw = tf.summary.FileWriter("log", graph=sess.graph)

【Raspberry Pi】Raspberry Pi 3 Model BでCaptivePortalする方法

Raspberry PiでCaptivePortal

仕事でWi-Fiに接続したら何らかのコンテンツを表示することができないか?と考えて、いろいろ調べてみるとキャプティブポータル(CaptivePortal)が使えるのではないかと考えました。

そこで、今回はRaspberry PiWi-Fi機能を利用して、DHCPサーバーからIPアドレスをもらうときにスプラッシュ画面が表示されるようにしてみたいと思います。

注意

知識不足のため、iPhoneで接続したときにCaptivePortal画面が出てきません。
ただ、パソコンでは画面が出てくることを確認しています。
誰か、解決策を知っている方がいらっしゃいましたら、コメントいただけるとうれしいです。

環境

  • Raspberry Pi 3 Model B & Rasbian Jessie With Pixelで構築しています。

アップデート

ファームウェアを更新します。
$ sudo rpi-update
再起動します。
$ sudo reboot
最新状態にアップデートします。
$ sudo apt-get update
$ sudo apt-get upgrade

IPアドレス

IPアドレスを固定します。

$ sudo nano /etc/network/interfaces
以下のように書き換えます。
auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0

iface wlan0 inet static
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

#allow-hotplug wlan1
#iface wlan1 inet manual
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
Raspbian Jessie では、/etc/dhcpcd.confの一番下に追記します。
$ sudo nano /etc/dhcpcd.conf
interface wlan0
static ip_address=10.0.0.1
static routers=192.168.1.1
static domain_name_servers=10.0.0.1

AP

hostapdをインストールします。
$ sudo apt-get install hostapd
hostapd.confファイルを作成します。
$ sudo nano /etc/hostapd/hostapd.conf
interface=wlan0
ssid=Free Wifi
country_code=JP
ieee80211d=1
hw_mode=g
channel=11
auth_algs=1
wmm_enabled=0
hostapd設定を変更します。
$ sudo nano /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"
WPASupplicantを退避

WPASupplicantファイルが読み込まれないようにします。

$ sudo mv /usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service ~/

DNSMASQ

DNSDHCPサーバーを設置します。
$ sudo apt-get install dnsmasq
dnsmasqの設定を変更します。
$ sudo nano /etc/dnsmasq.conf
一番下に追記します。
log-facility=/var/log/dnsmasq.log
address=/#/10.0.0.1
interface=wlan0
dhcp-range=10.0.0.10,10.0.0.254,10m
no-resolv
log-queries
$ sudo update-rc.d dnsmasq defaults

iptables

$ sudo nano /etc/iptables/rules.v4
$ sudo iptables -A INPUT -i wlan0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$ sudo iptables -A INPUT -i wlan0 -p tcp --dport 80 -j ACCEPT
$ sudo iptables -A INPUT -i wlan0 -p udp --dport 53 -j ACCEPT
$ sudo iptables -A INPUT -i wlan0 -p udp --dport 67:68 -j ACCEPT
$ sudo iptables -A INPUT -i wlan0 -j DROP
$ sudo iptables-restore < /etc/iptables/rules.v4
iptablesにルールが追加されているかを確認します。
$ sudo iptables --list

Nginxのインストー

$ mkdir nginx-1.8.0
$ cd nginx-1.8.0
$ wget http://nginx.org/download/nginx-1.8.0.tar.gz
$ tar -zxvf nginx-1.8.0.tar.gz
$ cd nginx-1.8.0
$ sudo apt-get install curl build-essential libpcre3-dev libpcre++-dev zlib1g-dev libcurl4-openssl-dev libssl-dev
$ ./configure
$ make
$ sudo make install
$ sudo apt-get install php5-fpm
$ cd ~
$ sudo nano /usr/local/nginx/conf/nginx.conf

以下のように書き換えます。

#user nobody;
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    root /usr/local/nginx/html;
    index index.php index.html index.htm;

    server {

        listen 80;
        server_name localhost;

        error_page 404 http://10.0.0.1/index.html;

        location http://captive.apple.com/hotspot-detect.html {
               rewrite ^(.*)$ http://10.0.0.1/index.html last;
        }

        if ( $http_user_agent ~* (CaptiveNetworkSupport) ) { 
            return 302 http://10.0.0.1/index.html; 
        }

        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
        }

    }
}

PHPパーミッションを変更します。

$ sudo nano /etc/php5/fpm/pool.d/www.conf
listen.owner = www-data
listen.group = www-data
listen.mode = 0666

自動起動設定

$ sudo nano /etc/rc.local

exit 0手前に追記

$ sudo /usr/local/nginx/sbin/nginx

OSの調整
syslogにavahiのwarning出てるのでサービス停止

$ sudo service avahi-daemon stop
$ sudo update-rc.d -f avahi-daemon remove
kernel lacks cgroups or memory controller not avaiable, not starting cgroups [warn]
$ sudo nano /boot/cmdline.txt

変更箇所

rootfstype=ext4 elevator=deadline <span style="color:red">cgroup_enable=memory</span> rootwait

動作の確認
電源OFF

$ sudo shutdown -h now

パソコンで接続した場合には、自動的にブラウザが表示されてNginxのウェルカムページが表示されるはずです。

iPhoneではならず・・・。

おそらく、CaptivePortalチェックした場合にSuccessが返ってきてしまっているのではないかと考えています。
Nginx上で制御しているので、このあたりをもっと改善できればといろいろいじったのですが・・・。
結果は変わらず・・・。


DHCPサーバーからIPアドレスが得られているのがわかります。

※ 以下の記事を参考にさせていただきました。
野良Wi-Fiでコンテンツ配信2 - ディーズガレージ wiki
Raspberry Pi 2 (Raspbian: jessie) でIPアドレスを固定する - Qiita
Ubuntuでiptablesの設定をiptables-persistentで永続化する
Raspbian(jessie)の固定IPアドレス設定方法

【VBA】Excelマクロを使って年代を調べよう!【連想配列】

Excelマクロを使って年代を調べよう!

久しぶりに、VBAを書くような気がします。
会社勤めをしている人は、分かって頂けると思いますが。
どうしてもExcelが身近なツールとなり、仕事を下支えする存在になっています。

最近では、MarketoとかSalesforce、kintoneとか巷で話題の最新のツールを使う機会があれども、
ローカルでの管理はExcelに頼っているという実情もあるかと思います。

ローカルとリモート。
パソコンの知識とITリテラシー

埋まらない社内SEと運用者のミゾ・・・。

f:id:PeaceJet:20170712102026p:plain

上記のように、A列に年齢データがあるとします。
簡単に、年代と人数を調べたいなと思って、以下のコードを書きました。

10代~90代までを連想配列に入れる方法で、動作します。

※注意※ 「ツール」→「参照設定」→「Microsoft Scripting Runtime」を有効にして下さい。

外部のライブラリを使用しないように、Collectionとかを使って実装してみたのですが。
Keyが上手く取れなかったので、結局、Scripting RuntimeからDictionaryを使うことにしました。

途中で、すごい勢いで初期化しておりますが、これをしないと結果が空欄になってしまうので仕方ないかと。

Public Sub SearchAge()

    Dim aWs As Worksheet: Set aWs = ThisWorkbook.ActiveSheet
    Dim Tenth, Twentyth, Thirtyth, Fourtyth, Fiftyth, Sixtyth, Seventyth, Eightyth, Ninetyth As Long

    Dim Age As Object: Set Age = New Scripting.Dictionary
    
    Tenth = 0
    Twentyth = 0
    Thirtyth = 0
    Fourtyth = 0
    Fiftyth = 0
    Sixtyth = 0
    Seventyth = 0
    Eightyth = 0
    Ninetyth = 0
    
    For i = 2 To aWs.Range("A65535").End(xlUp).Row
        
        Select Case aWs.Range("A" & i).Value
            
            Case 10 To 19
                Tenth = Tenth + 1
            Case 20 To 29
                Twentyth = Twentyth + 1
            Case 30 To 39
                Thirtyth = Thirtyth + 1
            Case 40 To 49
                Fourtyth = Fourtyth + 1
            Case 50 To 59
                Fiftyth = Fiftyth + 1
            Case 60 To 69
                Sixtyth = Sixtyth + 1
            Case 70 To 79
                Seventyth = Seventyth + 1
            Case 80 To 89
                Eightyth = Eightyth + 1
            Case 90 To 99
                Ninetyth = Ninetyth + 1

        End Select
    
    Next i
    
        Age.Add Key:="10代", Item:=Tenth
        Age.Add Key:="20代", Item:=Twentyth
        Age.Add Key:="30代", Item:=Thirtyth
        Age.Add Key:="40代", Item:=Fourtyth
        Age.Add Key:="50代", Item:=Fiftyth
        Age.Add Key:="60代", Item:=Sixtyth
        Age.Add Key:="70代", Item:=Seventyth
        Age.Add Key:="80代", Item:=Eightyth
        Age.Add Key:="90代", Item:=Ninetyth
        
    Dim Key As Variant: Key = Age.Keys
    
    aWs.Range("B" & 1) = "年代"
    aWs.Range("C" & 1) = "人数"
    
    For k = 1 To 9
    
         aWs.Range("B" & k + 1) = Key(k - 1)
         aWs.Range("C" & k + 1) = Age(k & "0代")
    
    Next k
    
'        Debug.Print Age("10代")
'        Debug.Print Age("20代")
'        Debug.Print Age("30代")
'        Debug.Print Age("40代")
'        Debug.Print Age("50代")
'        Debug.Print Age("60代")
'        Debug.Print Age("70代")
'        Debug.Print Age("80代")
'        Debug.Print Age("90代")

End Sub

Amazonプライムデーに犬っころが出品される

今日から、Amazonプライムデーらしいですね。

何を買おうかなぁ~何かあるかなぁ~などと思いホームページを見てみたら犬が出品されていました。

どうやったら、購入ボタンまで到達できますか?

f:id:PeaceJet:20170710192824p:plain