Rubyで作業

初めてのRuby

初めてのRuby

# ex8-15から続き
# coding:utf-8

=begin
class Hoge
  p @@class_variable
end
p @@class_variable
=end

class Duration
  DAYS_OF_WEEK = 7
  p DAYS_OF_WEEK
  def print_days_of_week
    p DAYS_OF_WEEK
  end
end

p Duration::DAYS_OF_WEEK
duration = Duration.new
duration.print_days_of_week

class Yapoo
  def public_method; end
  private
  def internal_use; end
  def public_api
    return internal_use
  end
  public :public_api
end

yapoo = Yapoo.new
yapoo.public_api
# yapoo.internal_use

message = "Hello"
def message.build_greeting(target)
  "#{self}, #{target}."
end
p message.build_greeting("world")

CENTRAL_REPOSITORY = Object.new
def CENTRAL_REPOSITORY.register(target)
  @registered_objects = @registered_objects || []
  unless @registered_objects.include? target
    @registered_objects << target
  end
  p @registered_objects
end
def CENTRAL_REPOSITORY.unregister(target)
  @registered_objects ||= []
  @registered_objects.delete(target)
  p @registered_objects
end

CENTRAL_REPOSITORY.register(1)
CENTRAL_REPOSITORY.register(2)
CENTRAL_REPOSITORY.unregister(1)

class Duration
  attr_accessor :from,:from2
  def initialize from,from2
    @from = from
    @from2 = from2
  end
  def self.a_week_from(from)
    return self.new(from,from+7*24*60*60)
  end
end

p Duration.a_week_from(Time.now)
d = Duration.a_week_from(Time.now)
p d.from,d.from2

class Duration2
  attr_accessor :from,:from2
  def initialize from,from2
    @from = from
    @from2 = from2
  end
  class << self
    def a_week_from(from)
      return self.new(from,from+7*24*60*60)
    end
  end
end

p Duration2.a_week_from(Time.now)
d = Duration2.a_week_from(Time.now)
p d.from,d.from2

p 1 < 2
p "an" > "and"

NodeJSで作業

// getfav.js
var BBS_USER = "JS-TESTER";
var BBS_PASS = "ipCU12ySxI";

var casper = require('casper').create();
casper.start();

casper.open("http://uta.pw/sakusibbs/users.php?action=login");

casper.then(function() {
    this.fill("form", {
        username_mmlbbs6: BBS_USER,
        password_mmlbbs6: BBS_PASS
    }, true);
});

casper.then(function() {
    var getLink = function () {
        var q = document.querySelector('#header_menu_linkbar a');
        return q.href;
    };
    var mypage_url = this.evaluate(getLink);
    this.echo("mypage url=" + mypage_url);
    this.open(mypage_url);
});

casper.then(function() {
    var pickupFav = function () {
        var res = [];
        var q = document.querySelectorAll('#favlist li > a');
        for (var i = 0; i < q.length; i++) {
            var text = q[i].textContent;
            var href = q[i].href;
            res.push(text);
        }
        return res;
    };
    var res = this.evaluate(pickupFav);
    this.echo("--- favlist ---");
    for (var i = 0; i < res.length; i++) {
        this.echo("- " + res[i]);
    }
});

casper.run();

// setfavall.js
var BBS_USER = "JS-TESTER";
var BBS_PASS = "ipCU12ySxI";

var DEFAULT_USER_ID = 1;
var target_user_id = DEFAULT_USER_ID;

var casper = require('casper').create();
var utils = require('utils');

var args = casper.cli.args;

if(args.length >= 1) {
    target_user_id = parseInt(args[0]);
    if(target_user_id == 0) target_user_id = DEFAULT_USER_ID;
}

casper.echo("target_user_id=" + target_user_id);
casper.start();

casper.open("http://uta.pw/sakusibbs/users.php?action=login");
casper.then(function() {
    this.fill("form", {
        username_mmlbbs6: BBS_USER,
        password_mmlbbs6: BBS_PASS
    }, true);
});

casper.thenOpen("http://uta.pw/sakusibbs/users.php?user_id=" + target_user_id);

casper.then(function () {
    var getList = function() {
        var links = [];
        var list = document.querySelectorAll("ul#mmlist a");
        for(var i = 0; i < list.length; i++) {
            var a = list[i];
            if(a.href.indexOf('post.php') > 0) {
                links.push(a.href);
            }
        }
        return links;
    };

    var links = this.evaluate(getList);
    utils.dump(links);
    casper.each(links, function(self, link) {
        self.thenOpen(link, function () {
            if(this.exists('#fav_add_btn')) {
                this.mouseEvent('click', '#fav_add_btn');
                this.echo('- click:' + link);
            } else {
                this.echo('- already:' + link);
            }
        });
    });
});

casper.then(function() {
    this.echo('ok');
});
casper.run();

C言語で作業

語りかける中学数学という問題集をやってると、オライリーのゲーム3D数学という本を読みたくなってきました。暇があるときにちょいちょい読みますか。

// q5-1
#include <stdio.h>

char *weekstr(int wd)
{
  char *wptr[] = {
    "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
  };
  return (wd >= 0 && wd < 7) ? wptr[wd] : NULL;
}

int main(void)
{
  int n;
  int retry;

  puts("曜日を表す英単語を表示します。");
  do {
    printf("0-日曜日/1-月曜日/.../6-土曜日 : ");
    scanf("%d", &n);
    if(n >= 0 && n < 7)
      printf("英語では%sです。\n", weekstr(n));
    printf("もう一度? 0-いいえ/1-はい : ");
    scanf("%d", &retry);
  } while(retry == 1);

  return 0;
}

// q5-2
#include <stdio.h>

int main(int argc, char **argv)
{
  int i = 0;
  argv++;
  while(argc-- > 1)
    printf("argv[%d] = \"%s\"\n", i++, *argv++);
  return 0;
}

// q5-3
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  double sum = 0;
  argv++;
  while(argc-- > 1)
    sum += atof(*argv++);
  printf("%f\n", sum);
  return 0;
}

NodeJSで作業

写経してると色々見落としがちな箇所がちらほら…。やっぱり試さないと身につかないですね。勉強のやり方を思い出してきてなんとかやれるようになってきました。バリバリやるのはまだ無理かな…。

一応気になったので、全部実行できるようにしておきました。使えないのもあったので修正しました。というわけで休憩…。

// kawase.js
var API = "http://api.aoikujira.com/kawase/get.php?code=USD&format=json";
var request = require('request');
var fs = require('fs');

request(API, function(err, response, body) {
    if(err || response.statusCode != 200) {
        console.log("ERROR", err); return;
    }
    var r = JSON.parse(body);
    var jpy = r["JPY"];
    var t = new Date();
    var fname = "USD_JPY_" + t.getFullYear() + "-" + (t.getMonth() + 1) +
        "-" + t.getDay() + ".txt";
    var text = "1usd=" + jpy + "jpy";
    console.log(text);
    fs.writeFileSync(fname, text);
});

// getTitle.js
var TARGET_URL = "http://kujirahand.com";
var casper = require('casper').create();

casper.start(TARGET_URL, function() {
    this.echo(casper.getTitle());
});

casper.run();

// screenshot.js
var casper = require('casper').create();

casper.start();

casper.open('http://google.co.jp');

casper.then(function() {
    casper.capture("screenshot.png");
});

casper.run();

// flickrShot.js
var casper = require('casper').create();
var args = casper.cli.args;
var argsStr = args.join('');

casper.start();

casper.viewport(1024,800);

casper.open('https://www.flickr.com/search/?text=' + argsStr);

casper.then(function(){
    this.capture('flickr-cat.png',{
        top:0, left:0, width:1024, height:800
    });
});

casper.run();

// iphoneShot.js
var TARGET_URL = "http://google.co.jp";
var casper = require('casper').create();

casper.start();

casper.userAgent('Mozilla /5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B5110e Safari/601.1');
casper.viewport(750, 1334);
casper.open(TARGET_URL);

casper.then(function() {
    this.capture('screenshot.png');
});

casper.run();

C言語で作業

例題4-7に関しては文字の入れ替えがうまくいかないと思って悩んでおりましたが、よくよく考えると、char型の配列が初期化されていない領域で文字列操作をしていたのが原因でした。最初からchar型の配列を添え字付きで初期化してメモリを割り当てないとセグメンテーションフォールトになるみたいですね。mallocやcallocでもいけると思いますけどわざわざそんな面倒なことはしなくても良いですよね。笑

// q4-5
#include <stdio.h>

int str_chnum(const char *s, int c) {
  int count = 0;
  while(*s) {
    if(*s++ == c)
      count++;
  }
  return count;
}

int main(void) {
  char str[256] = "abcdabcda";
  char c = 'a';
  int count = str_chnum(str, c);
  printf("%sの中に%c%d個あります。\n", str, c, count);
  return 0;
}

// q4-6
#include <stdio.h>

int str_dignum(const char *s) {
  int count = 0;
  while(*s) {
    switch(*s) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      count++;
    }
    s++;
  }
  return count;
}

int main(void) {
  char str[256] = "abcdabcda1234";
  int count = str_dignum(str);
  printf("数字文字の個数は%d個です。\n", count);
  return 0;
}

// q4-7
#include <stdio.h>

void swap_str(char s1[], char s2[]) {
  while(*s1 && *s2) {
    char c = *s1;
    *s1 = *s2;
    *s2 = c;
    s1++;
    s2++;
  }
  if(*s1) {
    char *p1 = s1;
    while(*s1)
      *s2++ = *s1++;
    *s2 = '\0';
    *p1 = '\0';
  } else {
    char *p2 = s2;
    while(*s2)
      *s1++ = *s2++;
    *s1 = '\0';
    *p2 = '\0';
  }
}

int main(void) {
  char str1[256] = "abcd";
  char str2[256] = "ec";
  char str3[256] = "dd";
  char str4[256] = "eebb";
  printf("%s %s\n", str1, str2);
  printf("%s %s\n", str3, str4);
  swap_str(str1, str2);
  swap_str(&str3[0], &str4[0]);
  printf("%s %s\n", str1, str2);
  printf("%s %s\n", str3, str4);
  return 0;
}

とある大学の問題を解いた

編入してみたいと思っていた大学の問題を筆記で解いてみたんですが、答えが何通りかあって迷いますね…。簡単なC言語の問題の答えをプログラムで確認してみました。こんな感じです。

#include <stdio.h>

int main(void) {
  char s[] = "090-0123-4567";
  char s2[] = "090-0123-4567";
  char c = '-';
  char *r, *w;
  char *r2, *w2;
  
  r = w = s;
  r2 = w2 = &s2[0];
  
  while(*r != '\0') {
    if(*r != c)
      *w++ = *r;
    r++;
  }
  
  *w = '\0';
  
  while(*r2 != '\0') {
    if(*r2 != c)
      *w2++ = *r2;
    r2++;
  }
  
  *w2 = '\0';
  
  printf("%s\n", s); // 09001234567
  printf("%s\n", s2); // 09001234567
  
  char a[] = "ABCDE";
  char *b[] = {"FGHIJ","KLMNO","PQRST"};
  char *c2 = *(b + 1);
  
  printf("%c\n", *a); // A
  printf("%c\n", *(b[0] + 1)); // G
  printf("%c\n", *(c2 + 2)); // M
  
  return 0;
}

柴田望洋先生のポインタ完全攻略という本をこの間から本格的にやってたんですが、その知識が役に立ちました。厄介な問題ばかり出てますなー…。

追記

ポインタ完全攻略は詳しく載っていますが、同著のそれ以外の本でも出てきますよ。解き慣れてる人ならなんとなくわかると思います。

C#で作業

参考

docs.microsoft.com

// rest_client.csproj
<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
    <PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
  </ItemGroup>
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
  </PropertyGroup>

</Project>
// Program.cs
using System;
using System.Threading.Tasks;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;
using WebAPIClient;

namespace rest_client
{
    class Program
    {
        static void Main(string[] args)
        {
            var repositories = ProcessRepositories().Result;
            foreach(var repo in repositories)
            {
                Console.WriteLine(repo.Name);
                Console.WriteLine(repo.Description);
                Console.WriteLine(repo.GitHubHomeUrl);
                Console.WriteLine(repo.Homepage);
                Console.WriteLine(repo.Watchers);
                Console.WriteLine(repo.LastPush);
                Console.WriteLine();
            }
        }

        private static async Task<List<Repository>> ProcessRepositories()
        {
          var serializer = new DataContractJsonSerializer(typeof(List<Repository>));
          var client = new HttpClient();
          client.DefaultRequestHeaders.Accept.Clear();
          client.DefaultRequestHeaders.Accept.Add(
              new MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
          client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
          var streamTask = client.GetStreamAsync("https://api.github.com/orgs/dotnet/repos");
          var repositories = serializer.ReadObject(await streamTask) as List<Repository>;
          return repositories;
        }
    }
}
// repo.cs
using System;
using System.Runtime.Serialization;
using System.Globalization;

namespace WebAPIClient
{
    [DataContract(Name="repo")]
    public class Repository
    {
        [DataMember(Name="name")]
        public string Name
        {
            get { return this._name; }
            set { this._name = value; }
        }
        private string _name;
        [DataMember(Name="description")]
        public string Description { get; set; }
        [DataMember(Name="html_url")]
        public Uri GitHubHomeUrl { get; set; }
        [DataMember(Name="homepage")]
        public Uri Homepage { get; set; }
        [DataMember(Name="watchers")]
        public int Watchers { get; set; }
        [DataMember(Name="pushed_at")]
        private string JsonDate { get; set; }
        [IgnoreDataMember]
        public DateTime LastPush
        {
            get
            {
                return DateTime.ParseExact(JsonDate, "yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture);
            }
        }
    }
}