プログラミング 大学生活

【悲報】理系(情報系)に行ってもプログラミングが出来るようになりません

この記事は、主に現在高校生で大学に入ってからのプログラミング教育の実情を知りたい方などに向けた内容となっています。

本記事の内容は主に、

  • 理系情報系におけるプログラミングの実態
  • プログラミングを学ぶにはどうすれば良いか

の2点に絞って解説していきたいと思います。

理系情報系におけるプログラミングの授業

この手の解説をする際は書き手がどういう人物なのか知っておいた方が話の内容を把握しやすいと思うので、簡単な自己紹介をします。

簡単な自己紹介
  • 大学 : 私立理系(一応そこそこ有名な方...かな)
  • 専攻 : 理工学情報系
  • 学年 : 学部3年(執筆時点)

これを踏まえた上で解説していきます。

大学の情報科の授業カリキュラム

まず、情報科では以下のような研究ができます。

  • 数理情報系(細かく分野が分かれる)
  • 人工知能
  • 量子コンピュータ
  • ソフトウエア科学 などなど

だいたいこれらの情報は大学のHPに掲載されています。そして高校生の頃の僕はこれをみたとき、「へ〜、人工知能とか量子コンピュータとか面白そう」という程度の感想しか持たなかったのですが、いざ入学してみると、授業の大半は数学でした。

微分積分、線形代数、集合論から始まり、統計、確率論、測度論など...時間割の上下左右どこをみても数学ばかりでした。

当然その結果、プログラミングの授業は少なかったです。具体的には、1年の頃は週に1コマ、2年の時に週3コマ程度でした。

少なくとも情報科学や情報工学という学問は、情報を扱うのですが、誰も「情報処理はプログラミングに終始する」とは言っていないのです。むしろそういう数学的な部分が分からないと、専門学校卒やプログラミングスクール出の人と差別化ができません。

学問の基礎的な部分ではやはり数学が幅をきかせるのです。

重要 : 「情報科=プログラミング」ではない

大学のプログラミング授業について

では肝心の数少ないプログラミングの授業はどんな感じだったのでしょうか。

結論から言うと、大学の理系学部に入って初めてプログラミングを学ぶ人の多くはプログラミングが嫌いになります。

この「初めて」というのが重要で、大学入学以前からプログラミングに触れていた人にとってはそれほど授業は苦痛でないはずです。一方大学からプログラミングを始める人はかなりの確率で嫌いになりがちです。

大学の授業の教え方はぶっちゃけ微妙

なぜ大学からプログラミングを始める人がそういう意識になってしまうのかというと、正直大学の授業が微妙だからだと思います笑

位置づけとしては多分、「プログラミング経験者は分かるが、未経験者からすると理解しにくい説明」をしているのだと思います。

具体的には、しばらくは

  • 用語や基礎的な事柄をインプットする
  • それを元に簡単な問題を解いていく

という形式で僕の学科では進んでいきました。これなら中学や高校の時の勉強と同じ感じですね。

ただ、2〜3ヶ月に一回ほど「課題」が出されます。これがプログラミング未経験者にとっては地獄のように難しいのです。

イメージとしては、普段の授業中にやる簡単な問題は数学の教科書レベルの問題で、課題は旧帝大の理系数学くらいの難易度です笑笑。

これは誇張ではないですよ笑。例えば、下のコードは授業中に出された演習問題を解いた時に作成したコードのイメージです。コードは長くなく、それほど処理する内容もありません。まさに教科書の練習レベルです。

class ForBlog{
  public static void main(String[] args){
    for(int i = 0; i < 10; i++){
      System.out.println("Jai guru de va om");
    }
    for(int k = 0; k < 10; k++){
      System.out.println("Nothing's Gonna Change My World");
    }
    System.out.println("This doesn't mean that I love
    The Beatles so musch, I used to listen to them 
    when I was a kid though");
    System.out.println("BTW, This Blog Sucks");
  }
}

一方、下のコードは、レポート課題として出された問題を解いた時のコードの一部です。

import java.awt.Color;
import java.awt.Rectangle;
import java.util.Random;
import java.awt.Graphics;
public class Player extends GameObject {
	HUD hud;

	Random r = new Random();
	Handler handler;
	public Player(int x, int y, ID id, Handler handler) {
		super(x, y, id);
		this.handler = handler;

	}

	public Rectangle getBounds() {
		return new Rectangle((int)x,(int)y,32,32);
	}


	public void tick() {

		x += velX;
		y += velY;

		x = Game.clamp((int)x, 0, Game.WIDTH - 37);
		y = Game.clamp((int)y, 0, Game.HEIGHT - 60);



		collision();
	}

		private void collision(){
			for(int i = 0; i < handler.object.size(); i++) {
				GameObject tempObject = handler.object.get(i);

			if(tempObject.getId() == ID.Blocks || tempObject.getId() == ID.VerticalBlocks
			|| tempObject.getId()== ID.TransparentBlocks || tempObject.getId() == ID.TrVertBlocks) {
				if(getBounds().intersects(tempObject.getBounds())) {
					x -= velX;
					y -= velY;
				}
			}
				else if(tempObject.getId() == ID.HPRecovery) {
					if(getBounds().intersects(tempObject.getBounds())) {
						HUD.HEALTH += 3;
					}
				}
					else if(tempObject.getId() == ID.FastEnemy) {
						if(getBounds().intersects(tempObject.getBounds())) {
							HUD.HEALTH -= 2;
					}
					}

						else if(tempObject.getId() == ID.BasicEnemy) {
						if(getBounds().intersects(tempObject.getBounds())) {
							HUD.HEALTH -= 1;
						}
					}
					}
				}






	public void render(Graphics g) {

		g.setColor(Color.cyan);
		g.fillRect((int)x, (int)y, 32, 32);


	}




}

import java.util.Random;
public class Spawn {
    private Handler handler;
    private HUD hud;
    private Random r = new Random();

    private int scoreKeep = 0;

    public Spawn(Handler handler, HUD hud) {
	    this.handler = handler;
	    this.hud = hud;

    }

    public void tick() {

    scoreKeep++;

    if(scoreKeep >= 100) {
    	scoreKeep = 0;
    	hud.setLevel(hud.getLevel() + 1);

    }
    }


    }


}

import java.awt.*;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;

//import javax.swing.JPanel;


/*public class Window{
	public static void main(String[] args) {
		JFrame fr = new JFrame("TileBased Game");

		fr.setSize(400,400);
		fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		fr.getContentPane().setBackground(new Color(240,255,255));

		TileBasedPanel panel = new TileBasedPanel();
		panel.setOpaque(false);
		fr.add(panel);
		fr.setVisible(true);
	}

}

*/




public class Window extends Canvas{
public Window(int width, int height, String title, Game game) {
	JFrame frame = new JFrame(title);
	frame.setPreferredSize(new Dimension(width, height));
	frame.setMaximumSize(new Dimension(width, height));
	frame.setMinimumSize(new Dimension(width, height));

	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setResizable(false);
	frame.setLocationRelativeTo(null);
	frame.add(game);
	frame.setVisible(true);
	game.start();
}
}

import java.awt.Canvas;
import java.awt.Rectangle;
import java.util.Random;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.image.BufferStrategy;
public class Game extends Canvas implements Runnable{
	public static final int WIDTH = 640, HEIGHT = WIDTH / 12 * 9;

	private Thread thread;
	private boolean running = false;

	private Random r;

	private Handler handler;
	private Spawn spawner;
	private static HUD hud;

	public Game() {
		handler = new Handler();
		hud = new HUD();

		this.addKeyListener(new KeyInput(handler));



		new Window(WIDTH, HEIGHT, "Escaping Game", this);


		spawner = new Spawn(handler, hud);

		r = new Random();
	}


	public synchronized void start() {
	thread = new Thread(this);
	running = true;
	thread.start();
}
	public synchronized void stop() {
	try {
		thread.join();
		running = false;

	}catch(Exception e) {
		e.printStackTrace();
	}
}

	public void run() {
		this.requestFocus();
	long lastTime = System.nanoTime();
	double amountOfTicks = 60.0;
	double ns = 1000000000 / amountOfTicks;
	double delta = 0;
	long timer = System.currentTimeMillis();
	int frames = 0;
	while(running) {
		long now = System.nanoTime();
		delta += (now - lastTime) / ns;
		lastTime = now;
		while(delta >= 1) {
			tick();
			delta--;
		}
		if(running)
			render();
		frames++;

		if(System.currentTimeMillis() - timer > 1000) {
			timer += 1000;
			//System.out.println("FPS: " + frames);
			frames = 0;
		}
	}
	stop();
	}


	private void tick() {

		handler.tick();


		hud.tick();
		spawner.tick();

		if(HUD.HEALTH <= 0) {
			HUD.HEALTH = 100;
			handler.clearEnemies();
		  int score = hud.getScore();
			System.out.println("Game Over!");
			System.out.println("Your Score is " + hud.getScore());
			System.out.println("Your Level is " + hud.getLevel());
			System.out.println("Press ESC button to quit this game");


		}
	}

	private void render() {
		BufferStrategy bs = this.getBufferStrategy();
		if(bs == null) {
			this.createBufferStrategy(3);
			return;
		}

		Graphics g = bs.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0,0,WIDTH, HEIGHT);

		handler.render(g);
		hud.render(g);
		g.dispose();
		bs.show();
	}

	public static int clamp(int var, int min, int max) {
		if(var >= max)
			return var = max;
		else if(var <= min)
			return var = min;
		else
			return var;
	}

	public static void main(String[] args) {
		new Game();

	}

}

import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class GameObject {

	protected float x, y;
	protected ID id;
	protected int velX, velY;

	public GameObject(float x, float y, ID id) {
		this.x = x;
		this.y = y;
		this.id = id;


	}

	public abstract void tick();
	public abstract void render(Graphics g);
	public abstract Rectangle getBounds();

	public void setX(int x) {
		this.x = x;
	}

	public void setY(int y) {
		this.y = y;

	}

	public float getX() {
		return x;
	}
	public float getY() {
		return y;
	}

	public void setId(ID id) {
		this.id = id;

	}
	public ID getId() {
		return id;
	}

	public void setVelX(int velX) {

		this.velX = velX;
	}

	public void setVelY(int velY) {
		this.velY = velY;
	}

	public int getVelX() {
		return velX;

	}

	public int getVelY() {
		return velY;
	}


}

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyInput extends KeyAdapter{

	private Handler handler;
	private boolean[] keyDown = new boolean[4];

	public KeyInput(Handler handler) {
		this.handler = handler;

		keyDown[0] = false;
		keyDown[1] = false;
		keyDown[2] = false;
		keyDown[3] = false;

	}


	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();

		for(int i = 0; i < handler.object.size(); i++) {
			GameObject tempObject = handler.object.get(i);

			if(tempObject.getId() == ID.Player) {


				if(key == KeyEvent.VK_W) {tempObject.setVelY(-5); keyDown[0] = true;}
				if(key == KeyEvent.VK_A) {tempObject.setVelX(-5); keyDown[1] = true;}
				if(key == KeyEvent.VK_D) {tempObject.setVelX(+5); keyDown[2] = true;}
				if(key == KeyEvent.VK_S) {tempObject.setVelY(+5); keyDown[3] = true;}

			}
			if(key == KeyEvent.VK_ESCAPE) {
				System.exit(1);
			}

		}

	}

	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();

		for(int i = 0; i < handler.object.size(); i++) {
			GameObject tempObject = handler.object.get(i);

			if(tempObject.getId() == ID.Player) {
				//key events for player 1

				if(key == KeyEvent.VK_W) keyDown[0] = false;//tempObject.setVelY(0);
				if(key == KeyEvent.VK_A) keyDown[1] = false;//tempObject.setVelX(0);
				if(key == KeyEvent.VK_D) keyDown[2] = false;//tempObject.setVelX(0);
				if(key == KeyEvent.VK_S) keyDown[3] = false;//tempObject.setVelY(0);

				//vertical movement
				if(!keyDown[0] && !keyDown[3]) tempObject.setVelY(0);
				//horizontal movement
				if(!keyDown[2] && !keyDown[1]) tempObject.setVelX(0);

			}


			}
		}
	}


...これは、旧帝大よりひどい...

高校の授業とかだったら、教科書レベルの問題をやった後に、標準、応用、発展問題と段階を踏んで進んでいくはずなのですが、大学のプログラミングの授業では、

「取り敢えず基本的なことは説明したからゲーム作っておいてくださーい。期限は1ヶ月です。じゃ」

みたいな感じでした。そして出来ない人が多数なので結局少数のデキる人のソースコードを参考にして作っていきます。ぶっちゃけ学費何十万何百万払う価値があるかと言われたら微妙です。

大学のプログラミングの授業で植えつけられる意識

そんな感じで授業が進んでいくので、プログラミング未経験者側だった自分に植え付けられたのは「自分はプログラミングに向いていないんだ...」という強烈な意識でした。おそらく同じような思いをしていた人は多かったと思います。

僕はなんとか持ちこたえたのですが、中には強烈にプログラミングが嫌いになる人も出てくるはずです。

大学(理系)で初めてプログラミングに触れた人で、必要以上にプログラミングが難しいものだという意識がある人は多いのではないでしょうか。

プログラミングに興味のある中高生が今出来ること

プログラミングに興味のある中高生は、今すぐにでもプログラミングに触れてみましょう。

今の時代だとまだPCの所持がほぼ必須なのでそれは用意しておきましょう。

その後の手順ですが、大きく

  • 書籍で学習
  • オンライン学習
  • プログラミングスクールなどで学習

の2つに分かれるかなと思います。かかるコストは書籍<オンライン<スクールですが、その分学習効率は逆にスクール<オンライン<書籍です。学習効率は「学習のしやすさ」と「学習スピード」の2つが柱です。

どのプログラム言語を学ぶかは用途によってかなり微妙ですが、「iPhoneアプリを作りたい!」みたいな明確な目的がなければ、Javascriptなどに触れてみると良いでしょう。

Javascriptは難易度が比較的低めな割に需要が高いので「学ぶべきプログラミング言語」系の動画でほぼ必ずランクインしています。下の動画では2位ですね。


ちなみに同じYouTuberの方がJavascriptでBlack Jack(トランプのゲーム)を1から作って解説しています。一応僕も半分くらいまでは見てみましたが、所々初歩的な部分の説明が抜けている場合があるので書籍でカバーする必要があります。


created by Rinker
SBクリエイティブ
¥2,728 (2020/09/21 23:03:10時点 Amazon調べ-詳細)


もっと詳しく知りたい方は以下の記事をご覧ください^^

  • この記事を書いた人
おととらべる

おととらべる

現役理系大学生。 Programming : Java, Python 音楽活動名義はRoot Introvertです。 音楽制作でのリリース、プロモーション ByeByeCopyright -> Root Introvert - Between Our Hearts (2019年3月) AirwaveDubstepTV -> SHADOWKEY - Kiss Me(feat. Jellow) (Root Introvert Remix) (2019年10月) NoCopyrightNation(NCN) -> Root Introvert - You Don't Wanna Be Lonely(2020年2月) 7even EDM -> Root Introvert - You Don't Wanna Be Lonely(Promotion) (2020年3月、4月) InspiredByInspired -> Root Introvert - You (2020年2月) AshesToFlame Records -> Root Introvert & Isura - Reminiscent (2020年4月) 一人旅 : タイ、ラオス、ベトナム、マレーシア

-プログラミング, 大学生活
-, ,

© 2020 おととらべる Powered by AFFINGER5