プログラミング素人のArduino

技術屋の末端。プログラミングは専門外。 電気回路も専門外です。 コードに間違いなど見つけられたら、気軽にコメントください。 VC#、ラズパイ始めました。

Twitterへの自動投稿

Twitter APIを利用して、定期的にTweetするものを作りました。
f:id:s51517765:20170622223753j:plain

以前の記事の発展。
s51517765.hatenadiary.jp

CoreTweetの基本機能はこの辺を参考に。
blog.ch3cooh.jp

テキストファイルからStreamreaderで読み込んで、ランダムにTweetします。

private void timer1_Tick でタイマー設定。
(プログラミング初心者にありがちな失敗は Thread.Sleepメソッドを使ってしまうこと。Windowsのグルグルが出てきて何もできなくなってしまいます。)
private void AutoTweet() がTweetの本体。
private void buttonPause_Click が自動投稿の停止。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CoreTweet;
using System.Diagnostics;
using System.IO;
using CoreTweet.Streaming;

namespace twitter
{
    public partial class Form1 : Form
    { 
       public Boolean AutoTweet_bool = false;
       public int Set;    //Next Tweet time
       public int interval;     //Tweet Interval

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {             
     
            var tokens = Tokens.Create("******", "******", A_Token, A_TokenSecret);        

 	//Auto Tweet Interval
            comboBoxInterval.Items.Add("15");
            comboBoxInterval.Items.Add("30");
            comboBoxInterval.Items.Add("59");
            comboBoxInterval.Text = "59";
        }

        private void button_AutoTweet_Click(object sender, EventArgs e)
        {
            interval = int.Parse(comboBoxInterval.Text);
            button_AutoTweet.Enabled = false;
            buttonPause.Enabled = true;
            AutoTweet_bool = true;
    
            if (interval > 59)
            {
                interval = 59;
                comboBoxInterval.Text = "59";
            }

            DateTime Now = DateTime.Now;
            timer1.Start();                 // タイマー起動
            Set = Now.Minute + interval;

            if (Set > 59)
            {
                Set = Set - 60;
            }

            AutoTweet(); //初回Tweet
        }

        private void timer1_Tick(object sender, EventArgs e)   //タイマー
        {
            if (AutoTweet_bool == true)
            {
                DateTime Now = DateTime.Now;
                if (Now.Minute == Set)
                {
                    Set = Now.Minute + interval;
           if (Set > 59)
                 {
                    Set = Set - 60;
                 }
                   
                        AutoTweet();
                }
            }
        }

       private void AutoTweet()
        {
            int ListCount=0;
    
                string AutoTweetText = "";
                System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\Users\***\List.txt", System.Text.Encoding.UTF8);                //ファイルを絶対参照で指定したいときは先頭に@を使う
                int LineCount = 1;
            button_AutoTweet.Enabled = false;
            while (sr.Peek() >= 0)
            {
                //一行ずつ読み込む
                AutoTweetText = sr.ReadLine();
                ListCount++;
       
            }
            sr.Close();

            System.Random r = new System.Random();
            int rand = r.Next(1,ListCount);  //LineCount
  
               System.IO.StreamReader sr2 = new System.IO.StreamReader(@"C:\Users\***\List.txt", System.Text.Encoding.UTF8);

            while (sr2.Peek() >= 0)
                {
                    //一行ずつ読み込む
                    AutoTweetText = sr2.ReadLine();
                    LineCount++;
                    if (LineCount == rand)
                    {
                        break;
                    }
                }
                //閉じる
                sr2.Close();
       
           try
             {
                    var tokens = Tokens.Create("******", "******", A_Token, A_TokenSecret);
                if (checkBoxDebug.Checked == false)
                {
                    tokens.Statuses.Update(status => AutoTweetText); //tweet
                }
                else
                {
                    MessageBox.Show(AutoTweetText);
                }
                    DateTime dt = DateTime.Now;
                    textBoxStatus.AppendText(dt.ToString("HH:mm:ss") +" "+AutoTweetText.Substring(0,17) +"… Complete!" + Environment.NewLine);
             }

           catch
            {
                    DateTime dt = DateTime.Now;
                    textBoxStatus.AppendText(dt.ToString("HH:mm:ss") + "Auto Tweet Error!" + Environment.NewLine);
            }
        }

        private void buttonPause_Click(object sender, EventArgs e)
        {
            buttonPause.Enabled = false;
            button_AutoTweet.Enabled = true;
            AutoTweet_bool = false;
        }
    }
}

Arduino nano互換 格安中華Bord(HiLetgo)

Amazonで格安Arduino互換品を購入。

送料込みで330円。
中国からの発送のため2週間ぐらいは掛かりますが。

f:id:s51517765:20170603130915j:plain

ピンヘッダは自分ではんだ付けする必要があります。
オスピンが付属していますが、他のオス-オスのジャンパワイヤが使いたいこともあり、本家Arduinoのようにメスのヘッダピンをつけました。

これで、Arduino IDEで接続を試みるも書き込みができません。
Amazonoのレビューを参考に下を参照し、CH340のドライバをインストールします。
Arduino NANO 互換品(CH340チップ使用)のデバイスドライバー | ネクストステップ サポートBlog

これで、書き込みができるようになりました。

ようするに、本家とはチップが異なるためそのドライバを追加しなければならないということです。


HiLetgo Mini USB Nano V3.0 ATmega328P CH340G 5V 16M マイクロコントローラーボード Arduinoと互換

Arduino(nano)と同じようにAnalog I/Oの機能があるはずなのだが、何か設定が必要なのだろうか?
analog出力がdigital出力のようになっている。
PWMを設定すると150ぐらいでHIGHとLOWが切り替わる。
AnalogReadは機能しているようだ。

C#でウェブスクレイピング

今回はウェブスクレイピングをやってみます。
↓の続きになります。
s51517765.hatenadiary.jp

ウェブスクレイピングとして、Webの情報を取得する基本的な構文は↓を参考にしました。
www.casleyconsulting.co.jp

Visual Studio上でクラスファイルを追加して、ウェブスクレイピングのコードを作成します。
f:id:s51517765:20170505154304j:plain

これは、URLを指定するとそのページのHTMLをstring型の文字列として取得します。
この内容は、あまり深く考えずにこういう一つのメソッドとして理解しておけばとりあえずいいと思います。

        public string Gethtml(string url)
        {
            // 指定されたURLに対してのRequestを作成します。
            var req = (HttpWebRequest)WebRequest.Create(url);     //using System.Net;

            // html取得文字列
            string html;

            // 指定したURLに対してReqestを投げてResponseを取得します。
            using (var res = (HttpWebResponse)req.GetResponse())
            using (var resSt = res.GetResponseStream())
            // 取得した文字列をUTF8でエンコードします。
            using (var sr = new StreamReader(resSt, Encoding.UTF8))     //using System.IO;
            {
                // HTMLを取得する。
                html = sr.ReadToEnd();
            }

            return html;
        }

このとき、System.NetとSystem.IOを使いますので、以下をファイルの先頭に追加しておきます。

using System.Net;
using System.IO;

つぎに、同じクラスファイル上にキーワードを抽出するプログラムを作成します。
引数としては先ほどのメソッドで取得したHTMLとキーワードを指定します。
考え方としては、Keywordを含む文を<P></P>で囲まれる部分で区切り取得します。
f:id:s51517765:20170506121935j:plain

①まずHTML全体の中からKeywordをさがす。html.IndexOf(Keyword)構文でhtmlのなかでKeywordの位置を探します。
Substring(start,Length)構文で、start =0(最初)から前記Keyword位置までを取得。
②前記Keywordよりまえの部分の中から後ろからさがして<p>を探す。
ここでは、Keywordから前へひとつづつ文字を追加して<p>をさがし、見つかったらこれがほしいKeywordより前の部分になります。

for (int n = 1; n <= buf_buf_mae.Length; n++)
            {
                buf_mae = buf_buf_mae.Substring((buf_buf_mae.Length) - n, n);

③~⑤後ろは同様に</p>を探します。
これを足し合わせるとKeywordを含む文が取得できます。

string getWord = buf_mae + buf_ushiro;

これをまとめると、Keywordの取得メソッド

        public string GetKeyword(string html, string Keyword)
        {
        header = "<p"
        footer = "</p"

            // html文字列内からKeywordをさがしその位置を返す
            int keywordStart = html.IndexOf(Keyword);

            string buf_buf_mae = html.Substring(0, keywordStart);
            string buf_mae = "";
            for (int n = 1; n <= buf_buf_mae.Length; n++)
            {
                buf_mae = buf_buf_mae.Substring((buf_buf_mae.Length) - n, n);
                if (buf_mae.IndexOf(header) > 0)
                {  //後ろからさがして見つかったら
                    break;
                }
                if (n > 5000)
                {
                    MessageBox.Show("Header get Error.");
                    break;
                }
            }

            string buf_ushiro = html.Substring(keywordStart); //indexOfから後ろを取得第2引数省略
            int nagasa_u = buf_ushiro.IndexOf(footer);
            buf_ushiro = html.Substring(keywordStart, nagasa_u + 4); //start位置,対象文字列長さ

            string getWord = buf_mae + buf_ushiro;
            return getWord;

        }

次にForm1にHTMLのボタンクリックイベントを作成します。

     private void buttonGethtml_Click(object sender, EventArgs e)
        {
            ViewBoxBackColorSet();

            if (checkBoxWriteOut.Checked == false && checkBoxPreview.Checked == false)
            {
                MessageBox.Show("Select output");
            }
            else
            {
                DateTime dt = DateTime.Now;
                string date = dt.ToString("yyyy_MM_dd_HH_mm_ss");
                try
                {
                    textBoxPreview.AppendText(dt.ToString("HH:mm:ss" + Environment.NewLine));

                    var scr = new Scraping();  //クラスScrapingを使うためにインスタンス作成
                    string url = textBoxURL.Text;
                    string html = scr.Gethtml(url);

                      Keyword = comboBoxKeyword.Text;
                    
                    string getWord;
                    getWord = scr.GetKeyword(html, Keyword);
                    if (checkBoxPreview.Checked == true)
                    {
                        textBoxPreview.AppendText(getWord + Environment.NewLine);
                    }
                    if (checkBoxWriteOut.Checked == true)
                    {
                        using (StreamWriter writer = new StreamWriter("H_" + date + ".txt", true))
                        {
                            writer.Write(getWord);
                        }
                    }

                }
                catch
                {
                    MessageBox.Show("Check URL");
                }
                ViewBoxBackColorReset();
            }
        }

このへんがオブジェクト指向(クラス設計)っぽいところ。
クラスを使うためにインスタンスの宣言をして、入力(ここではURL)と出力(ここではHTML)(および、HTMLとKeywordとWord)だけが見えている状態になります。

 var scr = new Scraping();  //クラスScrapingを使うためにインスタンス作成
 string url = textBoxURL.Text;
 string html = scr.Gethtml(url);

 string getWord;
 getWord = scr.GetKeyword(html, Keyword);

これで、必要部分は取得できましたが、HTMLのタグが不要です。
f:id:s51517765:20170506123724j:plain

  public string deleteTag(string getWord)
        {
            int buf_int = -1;
            int buf_int2;
            string tukau1, tukau2;
            string buf_1;
            string deleteTag_getword;

            for (int n = 1; n < 80; n++)
            {
                buf_int = getWord.IndexOf("<");
                if (buf_int < 0)
                {
                    break;
                }

                tukau1 = getWord.Substring(0, buf_int);
                buf_1 = getWord.Substring(buf_int + 1);
                buf_int2 = buf_1.IndexOf(">");
                tukau2 = buf_1.Substring(buf_int2 + 1);

                getWord = tukau1 + tukau2;
              
            }
            deleteTag_getword = getWord;
                 return deleteTag_getword;
        }

このように<>で囲まれた部分をHTML Tagとみなして削除するメソッドを入れると、すっきりします。
タグのスタート<を探し、これ以前の文字列を取得し、<の次の文字から>を探しこれをタグとみなして捨てる。>の次の文字から同じようにタグを探し、文字列を取得し最初に取得したタグの外とつなげて…という風にしていきます。
forの構文の繰り返し数は適当にいれていますが、タグが見つからなくなったら、IndexOf = -1となるので、こうなったらBreak;で終了。

bufはbufferの略であまり綺麗とは言えないがよく使われる一時的な変数のことです。

f:id:s51517765:20170506125852j:plain

※HTMLのタグは「半角<>」を使いますが、ブログ上で半角<>を使うタグとみなされて表示されないので、全角<>を使っています。

C#でTwitterにつぶやく

このページを参考にC#からTwitterにつぶやいてみたいと思います。
blog.clock-up.jp

パッケージマネージャーコンソールから、ライブラリを導入します。
パッケージマネージャーコンソールは下の図のように開きます。
f:id:s51517765:20170507134201j:plain
すると、↓のようなコンソールが開くので、
f:id:s51517765:20170507134301j:plain

Install-Package CoreTweet

と入力します。

次にAPIキーを入手します。
twiiterアカウントに電話番号の登録が必要になります。
apps.twitter.com

ライブラリの登録をして、

using CoreTweet;
using System.Diagnostics;

ボタンクリックイベントを作ります。
最終的にはPincode入力用のFormを作りますが、今は簡易的にMessageBoxを出して、
その間に、Twiiterの認証画面を通過して、直接プログラムを書き換えてPincodeを通しています。
なんか、あらかじめブラウザでTwiiterにLogInしていないと、通らない???

 private void button1_Click(object sender, EventArgs e)
        {
            var session = OAuth.Authorize("*********", "*********");
                          //("入手した api_key", "入手した api_secret");
            Process.Start(session.AuthorizeUri.AbsoluteUri);

            MessageBoxShow("Get Pincode.");  //ここでPincodeの入力待ち

            var pincode"123234545676";   //ここを書き換える

            //トークン取得
            var tokens = OAuth.GetTokens(session, pincode);

            try
            {
                tokens.Statuses.Update(status => "hogehoge");
            }
            catch 
            {
                MessageBox.Show("Error");
            }

        }

で、APIは通ったようでプログラムはErrorがないのにタイムラインにつぶやきが更新されないのはなぜ???

<5/9更新>
APIAccess LevelがReadになっていて、Write権限がなかったため、書き込みができなかったらしい。
Read and writeに設定したはずだが、画面上ではRead and writeと出ていても、Read Onlyになっていることがあるようだ。
一度 Read, Write and Access direct messagesに変更して保存し、Read and writeに戻したら有効になった。
f:id:s51517765:20170509213451j:plain
<5/25更新>
APIが通っても一度しかTweetが成功しないことが続いた。数時間経過後に再びTweetができるのだが、どうやら同じ内容を連続してTweetしようとすると、Twitter側から弾かれるらしい。

「人工知能は人間を超えるか」を読んで

人工知能(Artificial Intelligence; AI)、ディープラーニング機械学習といった言葉が話題だ。
世の中すべてが人工知能に置き換えられるような勢いだ。
そうなってしまったら、人間の価値はどこにあるのだろうか?

この本は比較的わかりやすい例を用いて数式がほとんど出てくることなく、人工知能の過去と未来についてわかりやすく書かれている。

機械学習とは人工知能に知能を授ける方法のひとつで、ディープラーニング機械学習の一つである。
またニューラルネットワーク機械学習のための方法のひとつである。
f:id:s51517765:20170505113319p:plain

人工知能、機械学習、ディープラーニングの違いとは | NVIDIA



人口知能はまだ完成していない。
それどころかできてさえいない、というのが専門家の認識らしい。

そういわれると、「人口知能すでにあるよね」と思う人も多いかと思う。
人工知能の定義にもよるが、目指すべき人工知能とは

「サンプルとなるデータをもとに自らルールや知識を学習するもの」であるからだ。

人工知能という言葉自体は1960年代からあるが、「単純なプログラムを人工知能と呼んでいるだけのもの」、「入力と出力の組み合わせの数が極端に多いもの」、これらが人口知能と呼ばれているからである。
たとえば前者は、スイッチが押されたら過熱を始め、一定時間が経過したら、温度を下げて…といったことを行う炊飯器のようなもの、後者はAlphaGo(アルファ碁)のようなもの。
AlphaGoは言ってみれば無数の手をGPUによって力任せにシミュレーションし、勝つ確率が最も高い手を見つけ出しているに過ぎない。

機械翻訳がここ数年飛躍的に進歩して英語を勉強する必要のない日もそう遠くないと思い始めているのだが、今あるものはロジックを知ってしまうと、これも人工知能といえるものではないし、もう少しかかりそうに思える。

人工知能が ”躓いている” 課題が「抽象化」である。
「特徴」を抽出することであるが、目が二つあって耳が三角で髭があるのが「猫」だよ、ということを習得すれば、三毛猫もアメリカンショートヘアも「猫」であるという概念が形成されるが、これまでコンピューターは1番目のドットが茶で二番目のドットが黒で3番目の…が「猫」だと学習していたのでは、黒猫は猫と認識することはできない。

人工知能が普及したころには、なくなる職業、なくならない職業というのはよく言われるが、情報の価値がインフレ化していくのではないかと思う。今と同じような考え方では当然通用しなくなるが、アナログな仕事は無くならないとも思う。

C# でテキストファイルスクレイピング

ウェブスクレイピングという言葉がありますが、これはウェブ(特定のHP上)から必要な情報を取り出すものです。
www.fascinatedwithtofu.com

仕事(電子機器開発)上で機械の動作ログがテキストで出てくるのですが、これを解析するのに通常はExcelのマクロで行っています。
機能としては十分なことが可能なのですが、実行速度が遅い。

ここで、これをC#で作ってみようと思いました。
StreamReaderをつかえばできそうなことは容易に想像がつきます。
結果的にはExcel VBAより高速に抽出が完了します。
また、VBAの場合はファイルの読み込み中に他のExcelでの作業ができませんが(できなくもないけど)C#で作れば、Excelのプロセスが使われるわけではないのでExcelの作業を止めることもありません。

UIとしては↓のようなものを作成し、「Target / URL」ボックスは今後作るウェブスクレイピング向け。
Kyewordに目的のIndexを入れて「File」クリックで実行します。
f:id:s51517765:20170430122815j:plain

<命名ルール>
デザイナーは敢えて公開しませんが、
ボタンクリックイベントは
「ボタン名_Click」 →ex) private void FileOpen_Click …
チェックボックスの状態はチェックボックスのDefaolt名がcheckBox(Number)だと思うので、checkBoxという名前を残して、
「checkBox名称」 → ex) checkBoxPreview
コンボボックスなら「comboBox名称」→ ex) comboBoxKeyword
というようにつけていくと後々わかりやすいのではないかと思います。
もっといい方法(きちんとした命名ルール)があるかもしれなくて、自作の方法ですが。

<機能>
・テキストまたはそれに準ずるファイルを読み込むことができる。
・Keywordが含まれている「行」を抽出しTextファイルに出力する。
・Previewボックスに出すこともできる。
・上記2つの出力先はチェックボックスで切り替え可能。
・上記チェックボックスがいずれもチェックされていないときはErrorをだす。
・読み込み中は読み込みが実行中であることを示す。(今回はPreviewボックスのグレーアウトと、ボタンの無効化)
・Previewボックスには読み込みが続けて行われても、区別できるようにする(今回は読み込み開始時刻をいれる)
・使用許諾に了承しない人には使わせない

<ロジック設計>
プログラムを実行するにはそのプログラムが正しく動作する条件が必要です。
まず捜索するKeywordが必要です。これがないときは基本的にはErrorです。
しかし、「Blank」というのもありといえばあり。
出力条件はそのプログラムの実行結果の出力なので、これがないとなにも意味を成しません。
この条件判断はなくてもErrorが出るわけではありませんが、その他のErrorがあるのか、本当に動作した結果何も出力がないのか、の判断がつかないのは困るので入れておくほうがいいと考えられます。
f:id:s51517765:20170430132003j:plain

<実行結果>
テスト用の題材としてはWikipediaのあるページのHTMLソースをテキストに保存したものを使いました。
例えば、"<h" をKeywordにすると、<h1、<h2、<h3…などの含まれた行だけを取り出すことができます。
f:id:s51517765:20170430182103j:plain

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Collections;

namespace mojiretsu
{
    public partial class Form1 : System.Windows.Forms.Form
    {

        private void Form1_Load(object sender, EventArgs e)
        {

            Boolean UserSet = false;
            var listKeyword = "";
            try
            {
                StreamReader srKeyword = new StreamReader("ListKeyword.txt");
                while ((listKeyword = srKeyword.ReadLine()) != null)      // ストリームの末尾まで繰り返す
                {
                    if (listKeyword != "123456789012")
                    {
                        comboBoxKeyword.Items.Add(listKeyword);
                    }
                    else
                    {
                        UserSet = true;
                    }
                }
            }
            catch
            {
                MessageBox.Show("Keyword List is not found, and make it.");
                using (System.IO.FileStream hStream = System.IO.File.Create("ListKeyword.txt"))
                {
                    // 作成時に返される FileStream を利用して閉じる
                    if (hStream != null)
                    {
                        hStream.Close();
                    }
                }
            }

            if (UserSet == false)
            {
                if (MessageBox.Show("The producer does not compensate for any damage using this software.", "License confirmation", MessageBoxButtons.OKCancel) != DialogResult.OK)
                {
                    MessageBox.Show("Not agree and can not use this.");
                    Close();
                }
            }
        }

        String Keyword;

        public Form1()
        {
            InitializeComponent();
        }

        private void FileOpen_Click(object sender, EventArgs e)
               {
            if (textBoxURL.Text == "")
            {
                if (keywordCheck() == true)
                {
                    if (writeOutCheck() == true)
                    {

                        FileOpen();
                    }
                 }
   
            }
            else   //URLがあったら
            {



            }
        }
  
        private void buttonGethtml_Click(object sender, EventArgs e)
        {  //作成中
         }

        public Boolean keywordCheck()
        {
            Keyword = comboBoxKeyword.Text;

            if (Keyword == "")
            {
                if (MessageBox.Show("Kyeword is Blank is OK ?", "Notice", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    return true;
                }
                return false;
            }
            else
            {
                return true;
            }

        }

        public bool writeOutCheck()
        {
            if (checkBoxWriteOut.Checked == false && checkBoxPreview.Checked == false)
            {
                MessageBox.Show("Select output");
                return false;
            }
            else
            {
                return true;
            }
        }

        public void FileOpen()
        {

                DateTime dt = DateTime.Now;
                string date = dt.ToString("yyyy_MM_dd_HH_mm_ss");

                OpenFileDialog ofd = new OpenFileDialog();

                if (ofd.ShowDialog() == DialogResult.OK)

                {

                    ViewBoxBackColorSet();
                    textBoxPreview.AppendText(dt.ToString("HH:mm:ss" + Environment.NewLine));

                    //   string[] StrArryData = new string[3]; // 1行分のデータを格納する作業オブジェクト
                    using (var sr = new StreamReader(ofd.FileName))  //型はVariant
                    {
                        int lineCount = 0;
                        if (checkBoxWriteOut.Checked == true)
                        {
                            using (StreamWriter writer = new StreamWriter(date + ".txt", true))
                            {  //インデックス
                                writer.Write("Souce File Name = " + ofd.FileName + Environment.NewLine);
                                writer.Write("Keyword = " + Keyword + Environment.NewLine + "" + Environment.NewLine);
                                writer.Write("======================= " + Environment.NewLine + Environment.NewLine + Environment.NewLine);
                            }
                        }
                        var line = "";
                        while ((line = sr.ReadLine()) != null)      // ストリームの末尾まで繰り返す
                        {
                            int index_check = line.IndexOf(Keyword); //含まれてないときは"-1"
                            if (index_check > -1)
                            {
                                lineCount++;

                                if (checkBoxPreview.Checked == true)
                                {
                                    textBoxPreview.AppendText(line + Environment.NewLine); //追記モード
                                }
                                if (checkBoxWriteOut.Checked == true)
                                {
                                    using (StreamWriter writer = new StreamWriter(date + ".txt", true))
                                    {
                                        writer.Write(line);
                                        writer.Write(Environment.NewLine);
                                    }
                                }
                            }
                        }
                        labelLineCount.Text = lineCount.ToString();
                        ViewBoxBackColorReset();
                    }
                }
          }


        private void buttonClear_Click(object sender, EventArgs e)
        {
            textBoxPreview.ResetText();
            comboBoxKeyword.ResetText();
            textBoxPreview.ResetText();
            labelLineCount.Text = "0";
            textBoxURL.ResetText();
        }

        private void buttonKeywordOpen_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("notepad.exe", @"""ListKeyword.txt""");
        }


        public void ViewBoxBackColorSet()
        {
            textBoxPreview.BackColor = Color.FromArgb(0xdd, 0xdd, 0xdd);
            buttonGethtml.Enabled = false;
            buttonFileOpen.Enabled = false;
            buttonClear.Enabled = false;
            buttonKeywordOpen.Enabled = false;
        }
        public void ViewBoxBackColorReset()
        {
            textBoxPreview.BackColor = Color.White;
            buttonGethtml.Enabled = true;
            buttonFileOpen.Enabled = true;
            buttonClear.Enabled = true;
            buttonKeywordOpen.Enabled = true;
        }

        }

    }

}

C# で配列の要素を並べ替える

要素の中身を最近使ったものから順番に並べ替える。

private void Form1_Load でファイルのなかみを読み込み、ComboBoxにInput。
CombBoxとはTextBoxに複数の要素をDropDownListから選べるもの。
f:id:s51517765:20170429112231j:plain

Listの中身はStreamReaderでよみこむ。
StreamReaderは必ず、srKeyword.Close() で開放しておく。
そうしないと、今度書き込むときにErrorがでる。

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) でアイテムが選択されたときに実行される。
要素の配列をひとつづつずらす。

            for (int n = 7 - 1; n >0 ; n--)
            {
                array_ex[n + 1] = array_ex[n]; //ひとつづつ配列のようそをずらして最新のものを[1]に入れる
              }

最後にファイルに書き込み記録。
ここでは、追記をfalseにして上書きする。
trueでは追記になって、実行されるたびに無駄に要素がふえてしまう。

StreamWriter sw = new StreamWriter("list.txt"<span style="color: #d32f2f">,false</span>, System.Text.Encoding.GetEncoding("shift_jis"))

本当は、重複要素のCheckとかしたい。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;    //ファイルIO


namespace narabekae
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
         }

        string[] array_ex = new string[12];
        string[] array_temp = new string[12]; 

        private void Form1_Load(object sender, EventArgs e)
        {     //アプリ起動時に実行される
            int n = 1;
            var listKeyword = "";
            comboBox1.Items.Clear();  //コンボボックスの初期化
            StreamReader srKeyword = new StreamReader("list.txt");
            while ((listKeyword = srKeyword.ReadLine()) != null)
            {                                   
                if (listKeyword == null || listKeyword == "")  //要素の空欄はskip
                { }
                else { 
                    array_ex[n] = listKeyword;
                    comboBox1.Items.Add(listKeyword);
                    n++;
                }
              }
            srKeyword.Close(); //streamを閉じる
        }

        private void button1_Click(object sender, EventArgs e)
        {
               //要素を6つまで表示、必須ではない
                label1.Text = array_ex[1].ToString();
                label2.Text = array_ex[2].ToString();
                label3.Text = array_ex[3].ToString();
                label4.Text = array_ex[4].ToString();
                label5.Text = array_ex[5].ToString();
                label6.Text = array_ex[6].ToString();
            
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {            //コンボボックスからItemが選択されたとき
            //値を取得
           string getItem = comboBox1.SelectedItem.ToString();
            label7.Text = getItem.ToString();
    
            for (int n = 7 - 1; n >0 ; n--)
            {
                array_ex[n + 1] = array_ex[n]; //ひとつづつ配列のようそをずらして最新のものを[1]に入れる
              }

            array_ex[1] = getItem;
            label1.Text = array_ex[1].ToString();
            label2.Text = array_ex[2].ToString();
            label3.Text = array_ex[3].ToString();
            label4.Text = array_ex[4].ToString();
            label5.Text = array_ex[5].ToString();
            label6.Text = array_ex[6].ToString();

            StreamWriter sw = new StreamWriter("list.txt",false, System.Text.Encoding.GetEncoding("shift_jis"));
            foreach (string eee in array_ex )
            {  //ファイルを更新
          
                sw.Write(eee + System.Environment.NewLine);
            }
            
            sw.Close(); //streamを閉じる
        }
     }
}