より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

Spotify使ってみた時の感想

在宅勤務だと、どうも集中できない〜、音楽を聞いてみようと思いました。

自社には変化を楽しむという言葉があります。

そこで、Spotifyを使ってみることにしました。

職場の同僚に相談したら、

登録して聞いてればいい。あとは勝手に気に入りそうな曲をレコメンドしてくれる

とのことでした。

マコなり社長の集中力の動画で紹介してるプレイリストを使ってみたりしたのですが、いい感じです。

www.youtube.com

既にYouTubeApple Musicも利用しているのですが、SpotifySpotifyで聴ける音楽もあり、楽しめました。

鼻呼吸テープを試したこと

以下の動画を見ていた時のこと。

youtu.be

ただ、口にテープ貼るだけで、よく眠れるとのことです。

わざわざそんなの買うの?

と思いました。

本当は、蚊取り線香を買うために薬局に行ったのですが、見かけたので買ってみました。

ナイトミン 就寝時に貼る鼻呼吸テープ 口・のどの乾燥・いびきの音を軽減 安眠へ促します 15枚入

以下の効用があります。

  • 鼻呼吸を促す
  • 喉の乾燥も防ぐ
  • 風邪が引きにくくなる
  • いびき軽減
  • 睡眠の質が上がる

口を開いてしまうと、喉を圧迫してしまいます。

口なんて塞がれたら、呼吸はどうなるんだと思ったのですが、息苦しくはありませんでした。

時々あったのですが、ヨダレ垂らして寝ていたということはなくなりそうです。

イオンのプライベートブランドでもっと安くて、枚数多いのもあります。これでも良さそうです。

ただ、使ってみて数字で見ると眠りが浅くなっており、睡眠の質が上がっているようには見受けられませんでした。

あまり私には合わなかったかな、と。

Netflixからdアニメストアに移行したこと

Netflixをやめました。

見たくもないオリジナルコンテンツを押し出されて辟易してしまいました。

どんだけ高性能なAIでリコメンドしても、合わないコンテンツの中で薦められてもやっぱり合わないのだと気付かされます。

そもそもアニメしか見てないじゃないか。

と気づいた私は、Netflixを停止し、月額500円のdアニメストアに移行しました。

dアニメストアの良いところは、以下です。

  • アニメに特化している
  • Netflixより安い
  • 検索しやすい

アニメに特化しているという点では、逆を言うとドラマなどは見れません。

Netflixでは深夜食堂孤独のグルメくらいは見てましたが、もちろんそういったことはできなくなります。

その分、安くなったからいいやと割り切っています。

Netflixはあえて寄り道させてお気に入りのコンテンツを見つけさせようとしているのかコンテンツは探しやすくないと私は感じています。

Huluの方が探しやすかったです。

dアニメストアはあいうえお順ベースであり、わかりやすいです。

今のところは不満がありませんね。

ドラマも見たいとなったら、またNetflixに乗り換えればいいかなと。

月額サブスクリプションですから。

参考記事

zukkazu.com

ストップウォッチで正確に計測するということ

仕事で使っているシステムには時間を計測する機能があるのですが、ふと以下のようなゲームを思い出しました。

www.itmedia.co.jp

昔、ギリギリ10秒に近づけるゲームってやりましたね。G-SHOCKとか使ってやってました。

後述しますがやってみると5秒の方がゲームのテンポが早くて正解だと思います。

でも、正確に計測するって難しくない? 100m走とか先生、ストップウォッチ止めてるけど、ずれたりしてない? って。

Google検索すると以下のような記事がヒットしました。

https://www.jstage.jst.go.jp/article/jjtehpe/18/0/18_27/_pdf/-char/ja

詳しいことは論文の内容を読んでいただくとして、手動でストップウォッチで計測すると実際より速い値になってしまうようです。

概ね-0.2秒。悪いと-0.45秒。

遅いのであれば、わかります。通り過ぎてから押したから。ですが、ある程度、人は予測してストップウォッチを止めているということでしょう。

Let's hack !!!

最近、技術的なことを書くことが減っていてヤバいので、10秒で止めるゲームアプリケーションをWPFで書いてみます。

久しぶりにWPFのViewModelを書こうとしてどうすればいいのか焦りました。

ReactivePropertyを使います。

MainWindow.xaml

<Window x:Class="StopwatchApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StopwatchApplication"
        mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:StopwatchViewModel}"
        Title="MainWindow" Height="250" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <Grid Grid.Row="0"  Background="{Binding BackgroundColor.Value}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding TimeText.Value}" FontSize="32"/>
                <TextBlock Grid.Column="1" Text="{Binding ReviewText.Value}" FontSize="32"/>
        </Grid>
        <Button Grid.Row="1" Command="{Binding ActCommand, Mode=OneWay}" Content="{Binding ButtonName.Value}" Height="40"/>
    </Grid>
</Window>

MainWindow.xaml.cs

#region

using System.Windows;

#endregion

namespace StopwatchApplication
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new StopwatchViewModel();
        }
    }
}

StopwatchViewModel.cs

#region

using System;
using System.Diagnostics;
using System.Windows.Media;
using Reactive.Bindings;

#endregion

namespace StopwatchApplication
{
    public class StopwatchViewModel
    {
        /// <summary>
        /// 時間計測オブジェクト
        /// </summary>
        private readonly Stopwatch _stopwatch = new Stopwatch();

        /// <summary>
        /// <see cref="StopwatchViewModel"/>のコンストラクタです。
        /// </summary>
        public StopwatchViewModel()
        {
            ActCommand = new ReactiveCommand();
            ActCommand.Subscribe(_ => ExecuteAction());
            SetButtonName();
            BackgroundColor.Value = new SolidColorBrush(Colors.Transparent);
        }

        /// <summary>
        /// 時間
        /// </summary>
        public ReactiveProperty<string> TimeText { get; } = new ReactiveProperty<string>();

        /// <summary>
        /// 評価
        /// </summary>
        public ReactiveProperty<string> ReviewText { get; } = new ReactiveProperty<string>();

        /// <summary>
        /// ボタン名
        /// </summary>
        public ReactiveProperty<string> ButtonName { get; } = new ReactiveProperty<string>();

        /// <summary>
        /// ボタン処理
        /// </summary>
        public ReactiveCommand ActCommand { get; }

        /// <summary>
        /// 評価
        /// </summary>
        public ReactiveProperty<SolidColorBrush> BackgroundColor { get; } = new ReactiveProperty<SolidColorBrush>();

        /// <summary>
        /// ボタン名を設定
        /// </summary>
        private void SetButtonName()
        {
            ButtonName.Value = _stopwatch.IsRunning ? "Stop" : "Start";
        }

        /// <summary>
        /// ボタン処理を実行します。
        /// </summary>
        private void ExecuteAction()
        {
            if (_stopwatch.IsRunning)
            {
                _stopwatch.Stop();
                TimeText.Value = _stopwatch.Elapsed.TotalSeconds + "s";
                if (_stopwatch.Elapsed.TotalSeconds >= 10d)
                {
                    ReviewText.Value = "Over...";
                    BackgroundColor.Value = new SolidColorBrush(Colors.DeepPink);
                }
                else if (_stopwatch.Elapsed.TotalSeconds >= 9.75d)
                {
                    ReviewText.Value = "Great!!!";
                    BackgroundColor.Value = new SolidColorBrush(Colors.DeepSkyBlue);
                }
                else if (_stopwatch.Elapsed.TotalSeconds >= 9.5d)
                {
                    ReviewText.Value = "Nice!";
                    BackgroundColor.Value = new SolidColorBrush(Colors.YellowGreen);
                }
                else if (_stopwatch.Elapsed.TotalSeconds >= 9.0d)
                {
                    ReviewText.Value = "Good!";
                    BackgroundColor.Value = new SolidColorBrush(Colors.DarkOrange);
                }
                else
                {
                    ReviewText.Value = "Bad...";
                    BackgroundColor.Value = new SolidColorBrush(Colors.Yellow);
                }
            }
            else
            {
                TimeText.Value = "Purpose:10s";
                ReviewText.Value = "Starting...";
                BackgroundColor.Value = new SolidColorBrush(Colors.Transparent);
                _stopwatch.Reset();
                _stopwatch.Start();
            }
        }
    }
}

実行例

9.75s〜10sだとGreatが出るのですが作った本人、一度も出せませんでした。

101,102,103と100をつけて計測するといいよという記事を読んだのですが、するとオーバーを連発。

年をとって体内時計が遅くなったかっ!と思いました。(ただ、この100をつける数え方は単純に数を数えるときに有用だったりします。私、数を数えるといつの間にか飛んでいたりするので)

1,2,3,4と普通に数えると7.8sとかBad連発...。

f:id:rimever:20200705142946p:plain

f:id:rimever:20200705142808p:plain

IsHighResolution

StopWatch.IsHighResolutionはTrueでした。

dobon.net

起動引数の間のスペース多い場合はどうなる?

プログラムを呼び出す時に起動引数を渡して実行します。

起動引数はスペース区切りで複数の引数を渡すことも可能です。

起動引数の間のスペースが1つではなく、スペースが2つ以上だったらどうなる?

ふと、疑問が浮かびました。

以下のような起動引数だったらどうなるのか、と。

one two            three four

twoとthreeの間の長いスペースは一つの区切りとなるのか、そうではないのか、と。

実際にコードを動かして確認したこと

using System;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Start");
            for (int i = 0; i < args.Length; i++)
            {
                Console.WriteLine($"{i+1}:{args[i]}");
            }
            Console.WriteLine("End");
        }
    }
}

f:id:rimever:20200701202739p:plain

f:id:rimever:20200701202817p:plain
スペース一つだろうか、スペース二つ以上でも分割されて処理された。

C#では長いスペースも一つの区切りと見なされ、one,two,three,fourという4つの起動引数となりました。

上記のコードもRiderでデバッグで動かすと、以下のようにスペース複数を一つの区切りとみなしてくれませんでした。

f:id:rimever:20200701204658p:plain
あれ?

Visual Studioでも動作確認したところ、Macから起動引数をコピーして、Windowsで実行すると

f:id:rimever:20200701204828p:plain

スペース複数を一つの区切りとみなしてくれてませんね。

f:id:rimever:20200701204926p:plain
しかし、手で入れ直すと問題なくスペース複数を一つの区切りとみなしてくれる

結局、きちんとexeに起動引数を渡して試すことにしました。

スペース複数を一つの区切りとみなして処理されました。

f:id:rimever:20200701205051p:plain

原則、スペース複数でも一つの区切りとなると思って良さそうですが、変なことはしないと良さそうですね。

InkCanvasのGesture認識機能や使えるGesture

エッセンシャルWPFを読んでいたのですが、WPFのInkCanvasにはGesture機能があります。

f:id:rimever:20200701220735p:plain
Check

チェックマークを入力するとチェックのジェスチャーと認識してくれるのです。

AI? 機械学習? 深層学習? とか思い浮かびますが、この本は2007年に発刊されています。

その時点でこんな機能が実現できていたのです。

どんなジェスチャーが認識できるのかというと、以下の列挙型を見ればわかります。

docs.microsoft.com

円や三角形、矢印、星など。

ただ、これを実際の製品に組み込めるかというと微妙です。

チェックマークで書いたつもりでも、Chevron Down(∨という形)として認識されてしまったり、円を書いているつもりでも、No Gestureと認識されないこともあります。

認識できるジェスチャーも特定のものにのみ絞れますが、どうですかねえ。

とはいえ、夢のある機能ですね。

コード

MainWindows.xaml

<Window x:Class="Chapter3_34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Chapter3_34"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
<Grid.RowDefinitions>
    <RowDefinition Height="*"/>
    <RowDefinition Height="200"/>
</Grid.RowDefinitions>
        <InkCanvas Grid.Row="0" Name="InkCanvas" Gesture="InkCanvas_OnGesture" EditingMode="InkAndGesture"/>
        <ListBox Name="ListBox1" Grid.Row="1"/>
         </Grid>
</Window>

MainWindow.xaml.cs

#region

using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;

#endregion

namespace Chapter3_34
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InkCanvas.SetEnabledGestures(new[] {ApplicationGesture.AllGestures});
        }

        private void InkCanvas_OnGesture(object sender, InkCanvasGestureEventArgs e)
        {
            ListBox1.Items.Add(e.GetGestureRecognitionResults()[0].ApplicationGesture);
        }
    }
}

iPhoneの言語設定を英語にして思ったこと

たまたま英会話の動画を見ていた時のことです。

youtu.be

いちいち英語を日本語に翻訳しなくても、さっと出るように「iPhoneの言語設定を英語にしてみたら」という話です。

日本人はOKとか英語が混ざって使っているので、その感覚をより得ようという点ではなるほどなと思います。

大体はわかるのですが、Amazonのアプリの英語になると焦りますね。

仕事で担当しているシステムは日英中に対応しているため、中国語版でもテストする機会があります。

漢字なんだから、なんとなくわかるだろうと思ってましたが、さっぱりわかりません。

例えば、日本語でいう「次」。インストーラーのような画面で登場しますね。

残念ながら中国語は「次」ではありません。「下一步」なんです。

日本語で言う「言語切替」もそうではありません。

それと比べると、英語版だと安心します。

ちなみに、英語端末でテストしているときに、Slackの雑談チャンネルに英語で投稿してみたりします。

英語端末だと日本語が入力できないためです。

英語使ってみると、文法的におかしくても、主語なくても大丈夫だろ、日本語だって主語ないときあるしとか、気づくこともあります。

仕事仲間(もちろん日本人)も英語で返事くれることもあります。