yucatio@システムエンジニア

趣味で作ったものいろいろ

会社では作りたいものを作れるわけではないのにプログラミング初学者には作りたいものがあってほしい、について

先日、表題のツイートをしまして、もっとこの件について語りたいため、記事にしました。

会社では作りたいものを作れるわけではない

ネガティブな言い回しになっていますが、単に、仕事って、顧客が欲しいものを作る(そして対価を得る)ということだよね、ってだけの話です。

プログラミング初学者には作りたいものがあってほしい

一方、プログラミングを学ぶ際には作りたいものがあってほしいのも事実です。1番の理由はプログラミング学習に挫折してほしくないためです。

語学を考えてみましょう。「なんとなくかっこよさそうだから」という動機の人と、「通訳になりたい」とか、「海外に行ってやりたいことがある」とでは、「思っていたより難しかった」と感じたときに違いが出るのではないでしょうか。

プログラミング学習は語学よりも難しくないと(個人的には)感じていますが、普段は使わない概念や専門用語が多く、理解するまで時間がかかることもあります。そこで挫折しないためにも、目標は持っていてほしいのです。

また、作りたいものがある場合、プログラミングを学ぶにつれて、目標に近づいている感じがしてわくわくするものです。 そのわくわくをぜひ体感してほしいと思っています。

繰り返される「プログラミング何から始めればよいですか」「何をしたいかによりますね」

話は変わりますが、 Twitterでは、たびたび「プログラミングに興味を持ちました。まず何から始めればよいでしょう」 に対し、 「何をしたいかによりますね」 と返信しているのを見かけます。

これは「作りたいものがあってほしい」とは少々性質が異なります(多少その成分は含まれますが)。

「何をしたいかによりますね」

これは、100%善意で発言しています。 と言うのも、プログラミングを学ぶ際、

  1. 習得するプログラミング言語を決める
  2. 1.で決めた言語の入門コンテンツをオンライン学習サービスや本で学ぶ

というステップになります。なので、最初に学ぶプログラミング言語を決定する必要があります。

しかし、現在、入門にぴったりなプログラミング言語はコレ!と言った鉄板な言語は存在しません。 また、圧倒的なシェアを誇る言語も存在しません。 ただ、言語によってどのような用途で使われるかの傾向があります。

というわけで、どのプログラミング言語を学ぶかのアドバイスをしたいために聞いています。

質問を質問で返されたほうの気持ち

システムエンジニアって「かっこいい」「給料がよさそう」「リモートワークができる」。少し勉強してみて、向いてそうだったら本格的に勉強して転職しよう、と考えている人にとって、質問に質問で返されるのは予想外かもしれません。 その気持ちはなんとなく分かります。 そもそもプログラミングで何ができるのか分からないのに、何がしたいのか聞かれても答えられるはずがありません。その場合は、

  • フィーリングでプログラミング言語を選択する
  • 自分がエンジニアになったときに、周り(親戚・友人)はどんなことを頼んできそうかを想像して、作りたいものを決める*1

で次に進みましょう。

「作りたいものが無いのになぜエンジニアを目指すのか」という辛辣な意見も目にしますが、 プログラミングを学習しながら、世の中でどのようにプログラミングが使われているか意識することで作りたいものも明確になってくると思います。

おわりに

会社では作りたいものを作れるわけではないのにプログラミング初学者には作りたいものがあってほしいという矛盾に気づいてからしばらく悶々としていましたが、フローとしては

プログラミングを勉強する

自分が作りたいものをつくる

他の人がほしいシステムを作る

こんなフローをたどれたらうれしいと思います。

*1:これは発想法の話であって、実際に知り合いから仕事を受注しろと言う話ではない

『Spring Framework超入門 ~やさしくわかるWebアプリ開発~』を読んだ

Spring Framework超入門 ~やさしくわかるWebアプリ開発~』(著: 樹下雅章)を読みました。


感じたことを書いておきます。

読みやすい

著者がプログラミングの講師ということもあってか、日本語が読みやすいです。内容がスッと入ってきます。

動くものを作ることで理解が深まる

本書はサンプルコードが豊富です。サンプルを書き写すことによって、今までなんとなく理解していたSpringの挙動が、実感をもって理解ができました。サンプルコードの量も、ちょうどよいと思いました。

内容は易しめ

内容は、Spring DI、AOP、Data、Validation、Thymeleafの基礎的な話題です。それぞれ丁寧なサンプルがあります。最後に簡単なアプリ作成を通して内容を総ざらいします。

Web開発の基礎知識は必要

Javaの基礎知識はもちろん、Webの基礎知識は読む前に必要と感じました。クライアントサーバ、DB、MVClombokなど簡単には説明されていますが少ないです。

Webの知識があってSpringが初めてならかなりおすすめ

というわけでWebの知識があってSpringが初めてならばかなりおすすめできます。SpringはDIなど初めてだとちょっと戸惑う部分があるので、書いてみてどう動くか体感するにちょうどよいです。

Springをなんとなくで使っている場合にもおすすめ

チームでSpringを使っていて途中から入ったため、なんとなく周囲のコードに合わせてコードを書いている、という場合にもおすすめです。Springの基礎について丁寧に説明してあるので頭の中が整理されます。また、知らない機能を知れるかもしれません。

個人的にはとても役に立ちました

私自身は「Springをなんとなくで使っている」、に該当していたので、この本で基礎を再確認してよかったです。どの機能をどのように使うか知ることで、現在担当しているアプリの問題点と改善点を発見できたのはよい経験でした。 欲を言えばテストまで書いてほしかったです。

基礎が固まったので今後もっと実践的な書籍も読んでみたいと思いました。

【Java】ネストした型のワイルドカードでエラーが出る場合の対処法

例えば、ListのListで、中身はなんでもよい、みたいな場合があるとする。コードであらわすとこんな感じ。

List<List<?>> wildcardList;

これに、例えばIntegerのListのListを割り当てようとするとエラーになる。

List<List<?>> wildcardList = new ArrayList<List<Integer>>();  // コンパイルエラー
// 型の不一致: ArrayList<List<Integer>> から List<List<?>> には変換できません

これを解消するには、境界型を使用して、

List<? extends List<?>> wildcardList = new ArrayList<List<Integer>>();

のように書くとよい。

参考: Java generics, nested collection of wildcard - Stack Overflow

『Spring Framework 超入門』のレイアウト化の作成がうまく出てこないときの対処法

Spring Framework超入門 ~やさしくわかるWebアプリ開発~』を読んでいます。


問題発生

6章の「レイアウト化の作成」のコードがうまく動きませんでした。

pageA.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorator="~{commons/layout}">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
  <div layout:fragment="content">
    <h1>Page A</h1>
  </div>
</body>
</html>

期待したページ

f:id:yucatio:20220209225619p:plain

実際に表示されたページ

f:id:yucatio:20220209225632p:plain

共通レイアウトであるcommons/layoutが読み込まれていません。

Spring-bootのバージョンは2.6.3です。

対応方法

4行目のlayout:decoratorlayout:decorateにします。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{commons/layout}">

原因

  • Spring boot 2.6からthymeleaf-layout-dialectのバージョン3を使うことになりました。

github.com

  • thymeleaf-layout-dialectのバージョン3でlayout:decoratorが廃止されました。

ultraq.github.io

という2つの要因が重なって動かなかったわけです。Spring boot 2.5まではサンプルコードのままで動くはずです。

Draft.jsで何も出てこない→出てるはず

Facebook社のReact用リッチエディタDraft.js。 Overview | Draft.jsにあるサンプルを試したけれど、何も出てこなかったときのメモ。

ソースコード

import React from 'react';
import {Editor, EditorState} from 'draft-js';
import 'draft-js/dist/Draft.css';

function MyEditor() {
  const [editorState, setEditorState] = React.useState(
    () => EditorState.createEmpty(),
  );

  return <Editor editorState={editorState} onChange={setEditorState} />;
}

export default MyEditor

このMyEditorコンポーネントを親コンポーネントから呼び出しています。

実行結果です。

f:id:yucatio:20211120092127p:plain

何も出てきてません。いえ、実は出ています。Editorがあるあたりをクリックします。

f:id:yucatio:20211120093511p:plain

そうするとカーソルが出てきます。何か文字を入力すると文字が出てきます。これがEditorの本体です。

f:id:yucatio:20211120092517p:plain

見やすくするためにborderを入れましょう。

function MyEditor() {
  const [editorState, setEditorState] = React.useState(
    () => EditorState.createEmpty(),
  );

  return (
    <div style={{border: '1px solid #666666'}}>
      <Editor editorState={editorState} onChange={setEditorState} />
    </div>
  );
}

f:id:yucatio:20211120091912p:plain

これで開発が始められそうです。

参考: reactjs - Can't figure out why draft-js is not shown - Stack Overflow

Javaで1日の始まりと終わりを取得する

Javaで1日の始まりと終わりを取得します。

LoalDateから取得する場合

LocalTime.MINLocalTime.MAXを使います。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2021-11-01", formatter);

LocalDateTime startOfDay = date.atTime(LocalTime.MIN);  // 2021-11-01T00:00
LocalDateTime endOfDay = date.atTime(LocalTime.MAX);  // 2021-11-01T23:59:59.999999999

LocalDateTimeから取得する場合

LocalDateTimetoLocalDate()で一旦LocalDateに変換してから、上記と同様にLocalTime.MINLocalTime.MAXを使います。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime datetime = LocalDateTime.parse("2021-11-01 12:15:30", formatter);

LocalDateTime startOfDay = datetime.toLocalDate().atTime(LocalTime.MIN);  // 2021-11-01T00:00
LocalDateTime endOfDay = datetime.toLocalDate().atTime(LocalTime.MAX);  // 2021-11-01T23:59:59.999999999

参考にしたページ

www.baeldung.com

JavaのLocalDateTime.parse()に日付だけ渡すとエラー

JavaのLocalDateTime.parse()で日付のみを指定したらエラーになりました。回避策も書いておきます。

コード

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime datetime = LocalDateTime.parse("2021-11-01", formatter);

エラー

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-11-01' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2021-11-01 of type java.time.format.Parsed
    at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2023)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1958)
    at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:494)

一旦LocalDateでパースし、LocalDateTimeに変換する必要があります。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2021-11-01", formatter);
LocalDateTime datetime = date.atStartOfDay();