【Java】JDBCを使ってSQLServerに接続する【JDBC】

JDBCを使ってSQLServerに接続するのに大変苦労したので解決方法を紹介します。
因みに名前付きインスタンスのサーバーに接続しています。

環境はWindows10、Java11、JDBCドライバは7.0です。
https://www.microsoft.com/ja-JP/download/details.aspx?id=57175 

先ずソースコードは以下の通り

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnectURL {
    public static void main(String[] args) {
        try{
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        }
        catch(ClassNotFoundException e){
            e.printStackTrace();
            return;
        }
        String connectionUrl = "jdbc:sqlserver://localhost\\MSSQLSERVER2017;databaseName=Login;user=sa;password=パスワード";
        try {
            Connection con = DriverManager.getConnection(connectionUrl);
            Statement stmt = con.createStatement();
            String SQL = "SELECT TOP 10 * FROM LOGIN";
            ResultSet rs = stmt.executeQuery(SQL);
            while (rs.next()) {
                System.out.println(rs.getString("ID") + " " + rs.getString("PWD"));
            }
            rs.close();
            con.close();
        }
        catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

通常のJava環境ではドライバを認識できなかったのでEclipseでドライバを参照設定すると成功した。

しかし通常のJava環境で実現したかったのでYahoo!知恵袋で質問した所、ドライバをカレントディレクトリに展開してクラスパスをカレントディレクトリに指定せよとの回答。

展開コマンドは以下の通り

>jar -xvf mssql-jdbc-7.2.1.jre11.jar

次にクラスパスを指定してコンパイル

>javac ConnectURL.java -cp .

実行時にはクラスパスは必要ありません

>java ConnectURL

あとでわかったことですがカレントディレクトリに展開しておけばコンパイル時も実行時にもクラスパスは必要ありませんでした。

Eclipseでも同様の事が行われているかは疑問ですがどんな環境構築しているのか興味が湧きますね。しかし通常のJava開発環境で簡単に実装出来ない(ドライバを展開しなければならない)のは問題があると思います。

【JavaScript/JQuery】YTPlayerを使ってWebページの背景に動画を表示する

Webページの背景に動画を表示する方法です。

https://github.com/pupunzi/jquery.mb.YTPlayer
からダウンロードし
Distフォルダ内のj query.mb.YTPlayer.min.jsと

Dist\cssフォルダ内のjquery.mb.YTPlayer.min.css
をhtmlファイルと同じフォルダ内に置きます。

HTMLファイルは次のコードになります。

<!DOCTYPE html>
<html>
<head>
<link href="jquery.mb.YTPlayer.min.css" media="all" rel="stylesheet" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="jquery.mb.YTPlayer.min.js"></script>
<script>
    jQuery(function(){
      var myPlayer;
      myPlayer = jQuery("#bgVideo").YTPlayer({});
    });
</script>
</head>
<body>
<!--<button onclick="jQuery('#bgVideo').YTPToggleVolume()">Mute/Unmute</button>
<button onclick="jQuery('#bgVideo').YTPFullscreen()">Fullscreen</button>-->
<input id="videoID" type="text" value="RawC-7fxME0" onfocus="$('#loadOptions').slideDown()">
<button onclick="jQuery('#bgVideo').YTPChangeMovie({videoURL: $('#videoID').val(), mute: false,stopMovieOnBlur: false,showControls: true, loop: true, autoplay: true, ratio: 16/9})">change video</button>
<div class="video" id="bgVideo" data-property="{ videoURL: 'biMO46z_VSY',containment:'body', mute: false,stopMovieOnBlur: false,showControls: true, loop: true, autoplay: true, ratio: 16/9,opacity:1,addFilters: {grayscale: 50,sepia: 80,opacity: 30}}">jquery.mb.YTPlayer</div>
</body>
</html>

初期値の動画を変更する場合はコード内のvideoURL: '***********'の*に
YouTubeの動画へのリンクを入力してください。

テキストボックスにYouTubeのリンクを入力して「change video」ボタンを
押すことで動画を変更することができます。
テキストボックスに入力する動画の指定方法は以下の3タイプが指定できます。
https://www.youtube.com/watch?v=V2rifmjZuKQ
http://youtu.be/V2rifmjZuKQ
V2rifmjZuKQ

設定やメソッドなどの詳しい情報は
https://github.com/pupunzi/jquery.mb.YTPlayer/wiki
を見てください。

因みにChromeではファイルを直接開いても再生されますが、
EdgeではWebサイトにアクセスしないと再生されません。
Edgeの場合はIISなどをインストールするなどしてWebサイトから
ファイルを呼び出して確認してください。

補足情報
以前のバージョンでは動画変更するのにはYTPChangeVideoが
使われていましたが新しいバージョンではYTPChangeMovieになりました。

参考デモページ
https://pupunzi.com/mb.components/mb.YTPlayer/demo/demo.html

【Python/Tkinter】写真を点滅させる

Python/Tkinter】写真を点滅させる
f:id:Jikoryuu:20200119175545g:plain
PILをインストールする必要があります
PILで扱える画像の種類はbmptiff、gif、jpg、pngtiffppm、pgmです

PILがインストールされてない場合はpipでインストールしてください

>pip install Pillow

※参考URL

pythonGUIでオブジェクトを点滅させたい

https://teratail.com/questions/191769

PythonGUIに画像を表示する
https://water2litter.net/rum/post/python_tkinter_canvas_create_image/

円が動くアニメーションをつくるよ!after()でタイマーを作ろう!
https://python-channel.com/1370.html

ライブラリ:PIL
https://www.lifewithpython.com/2013/09/pil.html

 

import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()
root.geometry('800x560')
root.title('IMG')

class Photo(object):
  root = None
  canvas = None
  # dt=点滅間隔[msec]
  def __init__(self,id,dt):
    self.id= str(id)
    self.state = 'normal'
    self.dt = dt
    Photo.root.after(self.dt, self.blink)
  def blink(self):
    if self.state == 'normal':
      self.state = 'hidden'
    else:
      self.state = 'normal'
  self.canvas.itemconfigure(self.id, state=self.state)
  self.root.after(self.dt, self.blink)

class Photo2(object):
  root = None
  canvas = None
  # dt=点滅間隔[msec]
  def __init__(self,id,dt):
    self.id= str(id)
    self.state = 'normal'
    self.dt = dt
    Photo2.root.after(self.dt, self.blink)
  def blink(self):
    if self.state == 'normal':
      self.state = 'hidden'
    else:
      self.state = 'normal'
    self.canvas.itemconfigure(self.id, state=self.state)
    self.root.after(self.dt, self.blink)

rimg1 = Image.open('picture.png')
img1 = ImageTk.PhotoImage(rimg1) # 表示するイメージを用意

canvas1 = tk.Canvas(
  root, # 親要素をメインウィンドウに設定
  #scrollregion=tk.W,
  width=rimg1.width-20, # 幅を設定
  height=rimg1.height-20, # 高さを設定
  relief=tk.RIDGE, # 枠線を表示
  borderwidth=10# 枠線の幅を設定
)
canvas1.create_image( # キャンバス上にイメージを配置
  0, # x座標
  0, # y座標
  image=img1, # 配置するイメージオブジェクトを指定
  tag="illust", # タグで引数を追加する。
  anchor=tk.NW # 配置の起点となる位置を左上隅に指定
)
canvas1.pack(fill = 'none', side = 'left')
Photo.root = root
Photo.canvas = canvas1
root.a1 = Photo(1,500)

rimg2 = Image.open('picture2.png')
img2 = ImageTk.PhotoImage(rimg2) # 表示するイメージを用意

canvas2 = tk.Canvas(
  root, # 親要素をメインウィンドウに設定
  width=rimg2.width-20, # 幅を設定
  height=rimg2.height-20, # 高さを設定
  relief=tk.RIDGE, # 枠線を表示
  borderwidth=10# 枠線の幅を設定
)
canvas2.create_image( # キャンバス上にイメージを配置
  0, # x座標
  0, # y座標
  image=img2, # 配置するイメージオブジェクトを指定
  tag="illust2", # タグで引数を追加する。
  anchor=tk.NW # 配置の起点となる位置を左上隅に指定
)
canvas2.pack(fill = 'none', side = 'left')
Photo2.root = root
Photo2.canvas = canvas2
Photo2(1,250)

root.mainloop()

【VBS】ドラッグ&ドロップで結合ファイルを作成する

下のコードをテキストファイルにコピーして「MargeTextFile.vbs」とでも名前を付けて保存してください。

このvbsファイルに複数選択したテキストファイルをドラッグ&ドロップするとマージされたファイル「Marge.txt」ができます。

MargeTextFile.vbs

if WScript.Arguments.Count>1 Then
  Dim FSO
  Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
  Dim sMarge
  For i=0 To WScript.Arguments.Count-1
    Dim oArg
    oArg=WScript.Arguments.Item(i)
    If FSO.FileExists(oArg) Then
      Dim oFs
      Set oFs=FSO.GetFile(oArg).OpenAsTextStream
      sMarge=sMarge & oFs.ReadAll
    End If
  Next
  Dim oMrg
  Set oMrg=FSO.OpenTextFile(fso.getParentFolderName(WScript.ScriptFullName) & "\Marge.txt",2,True)
  oMrg.Write sMarge
  oMrg.Close
End If

UTF-8
MargeTextFileforUTF8.vbs

if WScript.Arguments.Count>1 Then
  Dim FSO
  Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
  Dim sMarge
  For i=0 To WScript.Arguments.Count-1
    Dim oArg
    oArg=WScript.Arguments.Item(i)
    If FSO.FileExists(oArg) Then
      Dim oFs
      Set oFs=CreateObject("ADODB.Stream")
      oFs.Type=2
      oFs.Charset="UTF-8"
      oFs.Open
      oFs.LoadFromFile oArg
      sMarge=sMarge & oFs.ReadText
      oFs.Close
    End If
  Next
  Dim oMrg
  Set oMrg=CreateObject("ADODB.Stream")
  oMrg.Type=2
  oMrg.Charset="UTF-8"
  oMrg.Open
  oMrg.WriteText sMarge
  oMrg.SaveToFile FSO.getParentFolderName(WScript.ScriptFullName) & "\Marge.txt", 2
  oMrg.Close
End If

【Java Swing】csvファイルをJTableに表示するプログラム

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
public class CsvView extends JFrame {
 private final static Charset SJIS = Charset.forName("sjis");
 private final JTable table = new JTable();
 private final JFileChooser filechooser = new JFileChooser();
 public CsvView(String title) {
  setTitle(title);
  setBounds(100, 100, 300, 250);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  filechooser.setDialogTitle("Csvファイルを開く");
  filechooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
  FileFilter filter = new FileNameExtensionFilter("CSVファイル", "csv");
  filechooser.addChoosableFileFilter(filter);
  JMenuItem menuitem1 = new JMenuItem("Csvファイルを開く");
  menuitem1.addActionListener(e -> loadCSV(true));
  JMenu menu1 = new JMenu("ファイル");
  menu1.add(menuitem1);
  JMenuBar menubar = new JMenuBar();
  menubar.add(menu1);
  setJMenuBar(menubar);
  table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
  JScrollPane sp = new JScrollPane(table);
  add(sp);
 }

 private void loadCSV(boolean hasColHeader) {
  int selected = filechooser.showOpenDialog(this);
  if (selected != JFileChooser.APPROVE_OPTION) {
   return;
  }
  Path path = filechooser.getSelectedFile().toPath();
  int option = JOptionPane.showConfirmDialog(this, "ヘッダー(1行目)にタイトルを含みますか?",
    "ヘッダーの有無指定", JOptionPane.YES_NO_OPTION, 
    JOptionPane.WARNING_MESSAGE);
  if (option == JOptionPane.YES_OPTION){
   hasColHeader=true;
  }else if (option == JOptionPane.NO_OPTION){
   hasColHeader=false;
  }
  
  try (BufferedReader reader = Files.newBufferedReader(path, SJIS)) {
   String line = reader.readLine();
   if (line == null || line.isEmpty()) {
    table.setModel(new DefaultTableModel());
    return;
   }
   String[] lineData = line.split(",", -1);
   DefaultTableModel model;
   if (hasColHeader) {
    model = new DefaultTableModel(lineData, 0);
   } else {
    model = new DefaultTableModel(0, lineData.length);
    model.addRow(lineData);
   }
   while ((line = reader.readLine()) != null) {
    model.addRow(line.split(",", -1));
   }
   table.setModel(model);
  } catch (IOException e) {
   JOptionPane.showMessageDialog(this, e);
  }
 }

 public static void main(String args[]) {
  SwingUtilities.invokeLater(() -> {
   CsvView frame = new CsvView("Csvファイル表示");
   frame.setVisible(true);
  });
 }
}

【JavaFX】csvファイルをTableViewに表示するプログラム

■[JavaFX]csvファイルをTableViewに表示するプログラム

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Optional;
import java.util.StringTokenizer;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;
public class CsvView extends Application {
    ObservableList<String> headers = FXCollections.observableArrayList();
    ObservableList<ObservableList> data = FXCollections.observableArrayList();
    FileChooser fileChooser = new FileChooser();
    TableView<ObservableList> table;
    @Override
    public void start(Stage stage) {
        stage.setTitle("Csvファイル表示");
        Group root = new Group();
        Scene scene = new Scene(root,400,250);
        MenuBar menuBar = new MenuBar();
        generateMenu(menuBar, stage);
        table = new TableView();
        BorderPane borderPane = new BorderPane();
        borderPane.prefHeightProperty().bind(scene.heightProperty().subtract(0));
        borderPane.prefWidthProperty().bind(scene.widthProperty());
        borderPane.setTop(menuBar);
        borderPane.setCenter(table);
        ((Group) scene.getRoot()).getChildren().addAll(borderPane);
        stage.setScene(scene);
        stage.show();
    }
    private void generateMenu(MenuBar menuBar, Stage stage) {
        // Menu File
        Menu menuFile = new Menu("ファイル");
        menuBar.getMenus().addAll(menuFile);
        // MenuItem Exit
        MenuItem open = new MenuItem("CSVファイルを開く");
        open.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {
                fileChooser.setTitle("CSVファイルを開く");
                fileChooser.getExtensionFilters().clear();
                fileChooser.getExtensionFilters().addAll(
                        new FileChooser.ExtensionFilter("CSVファイル", "*.csv"),
                        new FileChooser.ExtensionFilter("全てのファイル", "*.*")
                );
                File file = fileChooser.showOpenDialog(stage);
                if (file != null) {
                    readCSV(file);
                }
            }
        });
        // MenuItem Exit
        MenuItem exit = new MenuItem("Exit");
        exit.setOnAction((ActionEvent t) -> {
            System.exit(0);
        });
        menuFile.getItems().addAll(open, new SeparatorMenuItem(), exit);
    }
    void readCSV(File file) {
        try {
            if (checkBeforeReadfile(file)) {
                FileInputStream in = new FileInputStream(file);
                InputStreamReader sr = new InputStreamReader(in, "sjis");
                BufferedReader br = new BufferedReader(sr);
                String line;
          Alert alrt = new Alert(AlertType.NONE,"",ButtonType.YES,ButtonType.NO);
          alrt.setTitle("ヘッダーの有無指定");
          alrt.setHeaderText(null);
          alrt.setContentText("ヘッダー(1行目)にタイトルを含みますか?");
          Optional<ButtonType> result = alrt.showAndWait();
          boolean colomnhead=false;
          if (result.get() == ButtonType.YES) {
           colomnhead = true;
          }
          data.clear();
          headers.clear();
          table.getColumns().clear();
          String linedata;
          linedata=br.readLine();
          if(linedata == null || linedata.isEmpty()) {
           return;
          }
          StringTokenizer token2 = new StringTokenizer(linedata, ",");
          if(colomnhead) {
                    while (token2.hasMoreTokens()) {
                  headers.add(token2.nextToken());
                    }
          }else {
                    while (token2.hasMoreTokens()) {
                  headers.add(null);
                  token2.nextToken();
                    }
                    StringTokenizer token3 = new StringTokenizer(linedata, ",");
                    ObservableList<String> lineList2 = FXCollections.observableArrayList();
                    while (token3.hasMoreTokens()) {
                        lineList2.add(token3.nextToken());
                    }
           data.add(lineList2);
       }
          while ((line = br.readLine()) != null) {
           StringTokenizer token = new StringTokenizer(line, ",");
           ObservableList<String> lineList = FXCollections.observableArrayList();
                    while (token.hasMoreTokens()) {
                        lineList.add(token.nextToken());
                    }
           data.add(lineList);
          }
            } else {
                System.out.println("No file exists or can't open.");
            }
        } catch (FileNotFoundException e) {
            System.out.println("FileNotFoundException : " + e.getMessage());
        } catch (IOException e) {
            System.out.println("IOException : " + e.getMessage());
        }
        generateTable();
    }
    private void generateTable() {
        int colN = 0;
        TableColumn[] column = new TableColumn[headers.size()];
        for (String colName : headers) {
            final int idx = colN;
            column[colN] = new TableColumn(colName);
            column[colN].setCellValueFactory(
                    new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
                        @Override
                        public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
                            return new SimpleStringProperty(param.getValue().get(idx).toString());
                        }
                    });
            colN++;
        }
        table.getColumns().addAll(column);
        table.setItems(data); // finally add data to tableview
    }
    boolean checkBeforeReadfile(File file) {
        if (file.exists()) {
            if (file.isFile() && file.canRead()) {
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        launch(args);
    }
}

【Batch】2次元配列を扱う

Batchプログラムで2次元配列を扱います
科目データを個人・総合・性別ごとの合計・平均を求めています
遅延環境変数が必須なのでsetlocal enabledelayedexpansionを使います

data.txt

性別 名前 科目1 科目2 科目3

1 akiyama 67 89 78 
2 kimura 79 86 92 
1 tanaka 62 85 79
1 inoue 96 86 91
2 satou 69 74 70
2 nomura 89 85 71 
2 mutou 65 58 90
2 harada 78 85 82
1 ueda 93 84 69
1 enomoto 59 88 75 
2 okada 62 85 97
1 yamada 98 75 84 
2 watanabe 89 71 96 
1 chida 87 90 91

Avarage.bat

@echo off

setlocal enabledelayedexpansion
rem ファイルから2次元配列にデータを格納
set n=0
cd %~dp0
for /f "tokens=1,2,3,4,5" %%a in (data.txt) do (
  set name[!n!][0]=%%a
  set name[!n!][1]=%%b
  set name[!n!][2]=%%c
  set name[!n!][3]=%%d
  set name[!n!][4]=%%e
  set /a n=n+1
)
set /a n=n-1
set tmp=0
set avg=0
set total=0
set t1=0
set t2=0
set t3=0
set tm=0
set tm1=0
set tm2=0
set tm3=0
set tmc=0
set tw=0
set tw1=0
set tw2=0
set tw3=0
set twc=0
rem 各個人の成績と合計と平均
echo 名前 性別 科目1 科目2 科目3 合計 平均
echo ==============================================
for /l %%x in (0,1,!n!) do (
  set /a total=total+!name[%%x][2]!+!name[%%x][3]!+!name[%%x][4]!
  set /a t1=t1+!name[%%x][2]!
  set /a t2=t2+!name[%%x][3]!
  set /a t3=t3+!name[%%x][4]!
  if !name[%%x][0]!==1 (
    set /a tm=tm+!name[%%x][2]!+!name[%%x][3]!+!name[%%x][4]!
    set /a tm1=tm1+!name[%%x][2]!
    set /a tm2=tm2+!name[%%x][3]!
    set /a tm3=tm3+!name[%%x][4]!
    set /a tmc=tmc+1
  ) else (
    set /a tw=tw+!name[%%x][2]!+!name[%%x][3]!+!name[%%x][4]!
    set /a tw1=tw1+!name[%%x][2]!
    set /a tw2=tw2+!name[%%x][3]!
    set /a tw3=tw3+!name[%%x][4]!
    set /a twc=twc+1
  )
  set /a tmp=!name[%%x][2]!+!name[%%x][3]!+!name[%%x][4]!
  set /a avg=tmp/3
  echo !name[%%x][1]! !name[%%x][0]! !name[%%x][2]! !name[%%x][3]! !name[%%x][4]! total=!tmp! average=!avg!
)
echo ==============================================
rem 全体の科目ごとの合計と総合計と平均
set /a n=n+1
echo total=!total! 1total=!t1! 2total=!t2! 3total=!t3!
set ave=0
set ave1=0
set ave2=0
set ave3=0
set /a ave=total/!n!
set /a ave1=t1/!n!
set /a ave2=t2/!n!
set /a ave3=t3/!n!
echo allaverage=!ave! all1average=!ave1! all2average=!ave2! all3average=!ave3!

rem 男性の科目ごとの合計と総合計と平均
echo mantotal=!tm! man1total=!tm1! man2total=!tm2! man3total=!tm3!
set manave=0
set man1ave=0
set man2ave=0
set man3ave=0
set /a manave=!tm!/!tmc!
set /a man1ave=!tm1!/!tmc!
set /a man2ave=!tm2!/!tmc!
set /a man3ave=!tm3!/!tmc!
echo manaverage=!manave! man1average=!man1ave! man2average=!man2ave! man3average=!man3ave!

rem 女性の科目ごとの合計と総合計と平均
echo womantotal=!tw! woman1total=!tw1! woman2total=!tw2! woman3total=!tw3!
set womanave=0
set woman1ave=0
set woman2ave=0
set woman3ave=0
set /a womanave=!tw!/!twc!
set /a woman1ave=!tw1!/!twc!
set /a woman2ave=!tw2!/!twc!
set /a woman3ave=!tw3!/!twc!
echo womanaverage=!womanave! woman1average=!woman1ave! woman2average=!woman2ave! woman3average=!woman3ave!

結果

名前 性別 科目1 科目2 科目3 合計 平均
==============================================
akiyama 1 67 89 78 total=234 average=78
kimura 2 79 86 92 total=257 average=85
tanaka 1 62 85 79 total=226 average=75
inoue 1 96 86 91 total=273 average=91
satou 2 69 74 70 total=213 average=71
nomura 2 89 85 71 total=245 average=81
mutou 2 65 58 90 total=213 average=71
harada 2 78 85 82 total=245 average=81
ueda 1 93 84 69 total=246 average=82
enomoto 1 59 88 75 total=222 average=74
okada 2 62 85 97 total=244 average=81
yamada 1 98 75 84 total=257 average=85
watanabe 2 89 71 96 total=256 average=85
chida 1 87 90 91 total=268 average=89
==============================================
total=3399 1total=1093 2total=1141 3total=1165
allaverage=242 all1average=78 all2average=81 all3average=83
mantotal=1726 man1total=562 man2total=597 man3total=567
manaverage=246 man1average=80 man2average=85 man3average=81
womantotal=1673 woman1total=531 woman2total=544 woman3total=598
womanaverage=239 woman1average=75 woman2average=77 woman3average=85