ブログ

割とコンピュータよりの情報をお届けします。

コンピュータ

Ubuntu 22.04にMondo Rescueをインストール

Ubuntu 22.04にMondo Rescueをインストールしてみた。22.04用のレポジトリは使えない。20.04用のレポジトリをそのまま流用する。

基本的には、前の記事の通りなのでこちらを確認された方が良い。Ubuntu 22.04であってもUbuntu 20.04用レポジトリを使うことにする。mindi.confの設定内容を変更する必要がある。

http://www.mondorescue.org/ftp/ubuntu/20.04/mondorescue.pubkeyを/etc/apt/keyrings/mondorescue-key.ascにダウンロードして
/etc/apt/sources.list.d/mondorescue.sources.listを作成する。

sudo curl -fsSL http://www.mondorescue.org/ftp/ubuntu/20.04/mondorescue.pubkey -o /etc/apt/keyrings/mondorescue-key.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/mondorescue-key.asc] http://www.mondorescue.org/ftp/ubuntu 20.04 contrib" | sudo tee /etc/apt/sources.list.d/mondorescue.sources.list > /dev/null
echo "deb-src [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/mondorescue-key.asc] http://www.mondorescue.org/ftp/ubuntu 20.04 contrib" | sudo tee -a /etc/apt/sources.list.d/mondorescue.sources.list > /dev/null
echo -e "\n" | sudo tee -a /etc/apt/sources.list.d/mondorescue.sources.list > /dev/null

さて以下の内容を実行してみる

sudo apt update
sudo apt install mondo
sudo apt install isolinux
sudo apt install xorriso

さらに、
sudo vim /etc/mindi/mindi.conf
として

EXTRA_SPACE=1524000
BOOT_SIZE=307200

BIOSレガシー起動のものであればこうだが、EXTRA_SPACEは20.04よりかなり大きくしないと使えなくなった。あまり大きくしすぎても失敗する。まだリストアに成功していないけど

sudo mondoarchive

を実行してみて。…

(2023.06.11 追記 apt-keyは廃止予定になっていたようで記述を変更しました)

UFEI環境では

sudo apt install syslinux-efi

を実行してさらに/usr/sbin/mindiの../libutil.c32のある行を編集する必要がある。

≫ 続きを読む

2023/06/10 コンピュータ   TakeMe

ConoHa VPS 512MBプランではUbuntu 22.04以降はサポートしない

最近話題(もう一年程前から)だが、ConohaやさくらVPSの512MBではUbuntu 22.04が起動しない。

Conoha でVPSをいくつか契約しているUbuntu 20.04である。
そろそろ来年以降どうしていくかを検討中である。
512 MBではUbuntu 22.04以降が起動しない。
あと1年待つと移行用のプランが用意されるのかそれとも今のうちに動き出すべきか。512MBプランの新規受付に制限がつけられていくのか。kernel-panicになっているため、swapを使っていても関係なく起動に失敗する。
今のところConoHaではイメージ保存でイメージを保存しておいて1GBプランに移すことができる。

≫ 続きを読む

2023/06/09 コンピュータ   TakeMe

Ubuntuのtarコマンドは除外の扱いが変わったのか?

古い記事を参考にtarコマンドを使用していたら除外がうまくいかないなど不都合に遭遇した。

古い記事を参考にTarコマンドの引数を扱ってはいけない。

えらい目にあった。
何ら新しいことはないだろうと思っていたtarコマンドでさえ仕様変更が起こっている。思ったように除外が効かなかった。
おおむねの作業の流れは非常にありがたい。


dir /home/takeme/backup
cd /
tar cvpzf "/home/takeme/backup/backup.tar.gz" --exclude="/proc" --exclude=/lost+found --exclude=/mnt --exclude=/sys --exclude=/home/takeme/backup /

今回は思ったところに除外が効いた。(ように見える)

≫ 続きを読む

2023/06/07 コンピュータ   TakeMe

PyScriptはすぐに使えるのか?

CMSと組み合わせてもPyScriptはすぐに使えるのか非常に疑問だった。
一応バージョン番号付けが1未満になっている意図は察しつつ…。

デモのhello worldを張り付けてみたら以下のようになる。最初はpyscriptのライブラリを見込む必要がある。結構ロードするファイルサイズがでかいことが分かったので公開を中止した。
改めてspimle clockの方をインラインフレームで作り直した。

意図通りにはならない。

HTMLではコード中の改行を気にしない仕組みだからでないかと思われる。それ用に作られているCMSのエディタでは改行を気にしない。Pythonは改行とインデントを気にする。(違うのかな)
少し検討が必要かもしれないが、サンプルではMatplotlibの使用例を含んでおり、データをお客に見せるときにこれでよいのであれば使えるかもしれない。
念のため確認だが、依然としてChrome系統のブラウザで動作確認をして活発に更新されているのでわずかな変化で動作に問題が生じる可能性がある。
デモページの3d表示のサンプルも直前まで動いていたような気がしたが、今日は動いていない

≫ 続きを読む

2023/06/06 コンピュータ   TakeMe
タグ:Python

Bodhi LinuxでAvalonia UIアプリの使用

最近 .NET 7.0 GUIアプリケーションがWindowsで開発できるようになってきている。割と便利だ。

GUIアプリケーションの作成にxamlを使用していると、最初は大変だったが慣れてくると割と便利だ。.NET Framework 4.5程度のときはMVVMの対応に割と時間がかかってイベントハンドラを記述するなんてやっていたが、最近はMVVMの対応が楽になった。
そして.NET MAUIやAvalonia UIやUno Platformはそれをマルチプラットフォームに拡張する。
例えば、Avaloinia UIのアプリケーションをUbuntu 20.04で実行してみた。

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install aspcorenet-runtime-7.0
LC_ALL=C dotnet AvaloniaApplication1.Desktop.dll

LC_ALL=Cが大事みたい。

ただ、.NET Framework 4.x世代の安定した互換性に比べて.NET 5.0 .NET 6.0 .NET 7.0の機能の追加・廃止の速さは少し怖い
(.NET Framework 4.xもWindows 7 の最後における.NET Framework 4.8のシステム破壊(WPFアプリがクラッシュする問題)はあったが)

≫ 続きを読む

2023/06/05 コンピュータ   TakeMe

Mondo Rescue をUbuntu 20.04でインストール

Mondo Rescue をUbuntu 20.04でインストールしてみた。しかし、依然としてefiには非対応である。どうしても使いたい場合には、バグを自分で修正する必要がある。

Ubuntu 20.04でMondo Rescueをインストールしてみることにした。
まずは、
sudo vim /etc/apt/sources.list.d/mondorescue.sources.list
内容は以下の2行。

deb http://www.mondorescue.org/ftp/ubuntu 20.04 contrib
deb-src http://www.mondorescue.org/ftp/ubuntu 20.04 contrib

この状態で、

sudo apt update 

を実行するとkey is not available: NO_PUBKEY 6BA8C2D220EBFB0Eなどの表示がでるので、

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6BA8C2D220EBFB0E
sudo apt update
sudo apt install mondo
sudo apt install isolinux
sudo apt install xorriso

ここまで。さらに、
sudo vim /etc/mindi/mindi.conf
として

EXTRA_SPACE=1024000
BOOT_SIZE=307200

Ubuntuのgenisoimage はefi booting のディスク作成機能を持たないために、UEFI環境でbootディスクの作成には失敗する。らしい。

どうもこの続きがあってUFEI環境では
sudo apt install syslinux-efi
とxorrisoを自分でビルドするが示されている?

ディストリビューションによってはできるらしい。

インストールしてさらに
/usr/sbin/mindi
をテキストエディタ(vimなど)で開き ../libutil.c32を探す。
その行のcp $LDLINUXE64/../libutil.c32を
cp /usr/lib/syslinux/modules/efi64/libutil.c32
と変更してしまう。

                                # cp $LDLINUXE64/../libutil.c32 $efidir 2>> $LOGFILE || Die "Cannot copy $LDLINUXE64 to $efidir). Did you run out of disk space?"
                                cp /usr/lib/syslinux/modules/efi64/libutil.c32 $efidir 2>> $LOGFILE || Die "Cannot copy $LDLINUXE64 to $efidir). Did you run out of disk space?"

今のところインストールはできるがバックアップに成功するにはmindi.confでEXTRA_SPACEを結構大きく設定する必要がある。
上の例はConoha VPSでUbuntu 20.04をバックアップしたときのものである。UEFIでは今のところ無理(2023.06.11追記)

UEFIではバックアップまではできるが、リストアに成功していない。

≫ 続きを読む

2023/06/03 コンピュータ   TakeMe

Windows 11 「アカウント>家族」が曲者

ローカルアカウントからMicrosoftアカウントに切り替えたいなーと思ったときにOffice 365 Familyなどを使っている場合には、注意があるようだ。

ローカルアカウントからMicrosoftアカウントに切り替えたいなーと思ったときにOffice 365 Familyなどを使っている場合には、ファミリーメンバーのアカウントが待機状態になっている。いつでも「設定」から有効にできるアカウントである。

この状態でも、(ファミリーメンバーに含まれているMicrosoftアカウントに含まれていれば)「このデバイスの他のユーザーがこのMicrosoftアカウントを使用しているため、ここに追加することはできません」と表示されて自分のアカウントもMicrosoftアカウントに切り替えることができなくなるのだ。
おそらく多くの人は自分で登録した覚えがないので、「???」となる。
 lusrmgr.mscを実行してデバイスに登録されている「ユーザー」を一覧表示させてみると初めて待機状態になっているアカウントがあることがわかる。長すぎるアカウント名は一部省略名が使われる。アイコンに下向き矢印が表示されている場合には、待機状態になっていて、「設定」>「アカウント」>「家族」から「サインインを許可する」ボタンをクリックすると有効になる。

十分に注意が必要だ。しかも、日本では発売が遅かったため日本語の情報が不足している。
「このデバイスの他のユーザーがこのMicrosoftアカウントを使用しているため、ここに追加することはできません」と表示されたら、 lusrmgr.mscで いったん待機アカウントを削除してやると、ローカルアカウントをマイクロソフトアカウントに変更できるようになる。英語のMicrosoftサポートコミュニティには2019年時点でこのような情報が入っている。

≫ 続きを読む

2023/05/28 コンピュータ   TakeMe

C#でclassのフィールドなどをインデックスで扱う方法

C#でクラスメンバを扱うとき[index]のように扱えると便利だが,Marshalの関係でメンバ数を固定にしないといけない場合がある.その場合にもインデックスで変数を扱う方法を確認.

System.Reflection.dllを使用する.
例えばフィールドならFieldInfoクラスを使う.

下の例では,
(FieldInfo)typeof(SampleA).GetField("item" + (i + 1))
で取得できるFieldInfoを使ってGetValueを使う.

代入の時には,SetValueを使用することができる(プロパティならGetProperty / SetProperty).

GetField()で取得できるのはpublic属性が付いているものに限る.privateになっているフィールドを取ろうとすると例外が発生する.実行時でないとわからないのでわかりにくいバグを発生する.ただし,「public / private」に関係なくプロパティを取得することは仕様としてはできる.デバッガーはこの仕組みを利用してデバッグを行うことができる.
一人でプログラムしている場合には気にならないが,複数人でプログラムしている場合には,ほかの人の部品の公開意図のないものを扱ってしまうのは,ややリスクがある.
この方法でだけ変数を使用していた場合,Visual Studio などでは変数の使用を検知できないのでCS0414が発生する,

using System;
using System.Reflection;

namespace Sample1
{
    class Program
    {
        static void Main(string[] args)
        {
            SampleA sampleA = new SampleA()
            {
                item1 = 1,
                item2 = 2,
                item3 = 3,
            };

            SampleA sampleA2 = new SampleA()
            {
                item1 = 11,
                item2 = 12,
                item3 = 13,
            };

            
            for (int i = 0; i < 3; i++)
            {
                Int32 item = (Int32)((FieldInfo)typeof(SampleA).GetField("item" + (i + 1))).GetValue(sampleA);
                Console.WriteLine($"{item}");
            }

            for (int i = 0; i < 3; i++)
            {
                Int32 item = (Int32)((FieldInfo)typeof(SampleA).GetField("item" + (i + 1))).GetValue(sampleA2);
                Console.WriteLine($"{item}");
            }
        }
    }

    public class SampleA
    {
        public Int32 item1;
        public Int32 item2;
        public Int32 item3;
    }
}

Tupleもこんな感じに扱える.(もちろん,Tupleはフィールド名を明示的に指定できるので状況によっては少し使い方が変わるかもしれないが)

            Tuple<double, double, double> tuple = new Tuple<double, double, double>(0, 1, 2);

            for (int i = 0; i < 3; i++)
            {
                double item = (double)((PropertyInfo)typeof(Tuple<double, double, double>).GetProperty("Item" + (i + 1))).GetValue(tuple);
                Console.WriteLine($"{item}");
            }

さてGetField以外にGetFieldsなるものがある.これが,求める「インデックスで扱う」ためのメソッドである.

≫ 続きを読む

2022/02/13 コンピュータ   TakeMe

OxyPlotにHeatMapSeriesというのがある

OxyPlotにHeatMapSeriesというのがあるというのを知った.これまでは,Bitmapで自分で描いていた.

Bitmapで自分で描くより楽だ.例えばここのようなサンプルが良い.
下は参考ページのやり方・名前の取り方をほぼそのまま参照している.Windows Forms用に少し手直しが入っているのと,linearColorAxis1.Palette = OxyPalettes.Gray(10);を追加しているところくらいが異なる.(参考ではRainbowになっている?)
縦横に正弦波が0.5 秒おきに流れていく(感じ).

using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot.WindowsForms;
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;

namespace HeatmapTest
{
    private OxyPlot.WindowsForms.PlotView plotView1;
        private PlotModel plotModelSpectrogram = new PlotModel();
        public HeatMapSeries heatMapSeries1 = new HeatMapSeries();
        private Double[,] Data = new Double[240, 250];
        private double t = 0;

        private System.Windows.Forms.Timer timer1;

        public Form1()
        {
            InitializeComponent();

            this.plotView1 = new OxyPlot.WindowsForms.PlotView();

            this.plotView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.plotView1.Location = new System.Drawing.Point(0, 0);
            this.plotView1.Name = "plotView1";
            this.plotView1.PanCursor = System.Windows.Forms.Cursors.Hand;
            this.plotView1.Size = new System.Drawing.Size(633, 362);
            this.plotView1.TabIndex = 0;
            this.plotView1.Text = "plotView1";
            this.plotView1.ZoomHorizontalCursor = System.Windows.Forms.Cursors.SizeWE;
            this.plotView1.ZoomRectangleCursor = System.Windows.Forms.Cursors.SizeNWSE;
            this.plotView1.ZoomVerticalCursor = System.Windows.Forms.Cursors.SizeNS;

            this.Controls.Add(this.plotView1);

            plotModelSpectrogram.Title = "TEST";

            var linearColorAxis1 = new LinearColorAxis();
            linearColorAxis1.Palette = OxyPalettes.Gray(10);
            linearColorAxis1.Position = AxisPosition.Right;
            linearColorAxis1.Minimum = 0.0;
            linearColorAxis1.Maximum = 100;
            plotModelSpectrogram.Axes.Add(linearColorAxis1);


            var linearAxis1 = new LinearAxis();
            linearAxis1.Position = AxisPosition.Bottom;
            linearAxis1.IsAxisVisible = false;
            linearAxis1.IsZoomEnabled = false;
            plotModelSpectrogram.Axes.Add(linearAxis1);

            // Dummy
            var linearAxis_a = new LinearAxis();
            linearAxis_a.Position = AxisPosition.Bottom;
            linearAxis_a.Minimum = 0.0;
            linearAxis_a.Maximum = 120.0;
            linearAxis_a.Title = "Time s";
            linearAxis_a.IsZoomEnabled = false;
            plotModelSpectrogram.Axes.Add(linearAxis_a);

            var linearAxis2 = new LinearAxis();
            linearAxis2.Position = AxisPosition.Left;
            linearAxis2.IsAxisVisible = false;
            linearAxis2.IsZoomEnabled = false;
            plotModelSpectrogram.Axes.Add(linearAxis2);

            // Dummy
            var linearAxis_b = new LinearAxis();
            linearAxis_b.Position = AxisPosition.Left;
            linearAxis_b.Minimum = 0.0;
            linearAxis_b.Maximum = 1000.0;
            linearAxis_b.Title = "Frequency kHz";
            linearAxis_b.IsZoomEnabled = false;
            plotModelSpectrogram.Axes.Add(linearAxis_b);


            heatMapSeries1.Data = new double[240, 250];
            heatMapSeries1.X0 = 0.0;
            heatMapSeries1.X1 = 100.0;
            heatMapSeries1.Y0 = 0.0;
            heatMapSeries1.Y1 = 1000.0;

            plotModelSpectrogram.Series.Add(heatMapSeries1);
            this.plotView1.Model = plotModelSpectrogram;

            this.timer1 = new Timer();
            this.timer1.Interval = 500;
            this.timer1.Enabled = true;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            PlotSpectrogram();
        }

        private void AddLastData(Double[] data)
        {
            for (int i = 0; i < Data.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < Data.GetLength(1); j++)
                {
                    Data[i, j] = Data[i + 1, j];
                }
            }
            for (int j = 0; j < Data.GetLength(1); j++)
            {
                Data[Data.GetLength(0) - 1, j] = data[j];
            }

            var pldata = new double[240, 250];
            Array.Copy(Data, pldata, Data.Length);
            heatMapSeries1.Data = pldata;
        }

        public void PlotSpectrogram()
        {
            Double[] data = new Double[Data.GetLength(1)];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = (50.0 + 20.0 * Math.Sin(0.2 * i) + 20.0 * Math.Sin(t));

            }
            t += 0.5;
            AddLastData(data);
            plotModelSpectrogram.InvalidatePlot(true);
        }
    }
}

≫ 続きを読む

2021/06/07 コンピュータ   TakeMe
タグ:Windows Forms

Math.NET Numericsに機能が増えている

最近使っていないうちに Math.NET Numericsの機能が増えている.数値最小化問題を解けるようになっている.

MathNet.Numerics.Optimizationには数値最小化問題を解ける機能が備わっている.

最小化問題だが,符号を変えれば最大化問題も最小化問題になる.また,目的関数最小化(最適化)問題と呼ぶこともある.例えば以下のように使用できる.
最近の.NETには
var f1 = new Func<double, double>(x => sample(x));
というFuncという汎用のデリゲートがあるのが面白い.

using MathNet.Numerics.Optimization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 一次元探索
            var f1 = new Func<double, double>(x => sample(x));
            var obj = ObjectiveFunction.ScalarValue(f1);
            var r1 = GoldenSectionMinimizer.Minimum(obj, -100, 100, 1e-8, 1000, 10, 4, 4);

            Console.WriteLine($"{r1.FunctionInfoAtMinimum.Point:G16}");
            Console.WriteLine($"{r1.FunctionInfoAtMinimum.Value:G16}");

            // 多次元探索
            var f2 = new Func<MathNet.Numerics.LinearAlgebra.Vector<double>, double>(x => sample2(x));
            var obj2 = ObjectiveFunction.Value(f2);
            var init = MathNet.Numerics.LinearAlgebra.Vector<double>.Build;
            

            var r2 = NelderMeadSimplex.Minimum(obj2, init.Dense(new double[] { 0.0, 0.0 }));
            Console.WriteLine($"{r2.FunctionInfoAtMinimum.Point[0]:G16},{r2.FunctionInfoAtMinimum.Point[1]:G16}");
            Console.WriteLine($"{r2.FunctionInfoAtMinimum.Value:G16}");
        }

        static double sample(double x)
        {
            return (x - 3000) * (x - 3000);
        }

        static double sample2(MathNet.Numerics.LinearAlgebra.Vector<double> x)
        {
            return (x[0] - 1000) * (x[0] - 1000) + (x[1] - 3000) * (x[1] - 3000);
        }
    }
}

≫ 続きを読む

2021/05/09 コンピュータ   TakeMe