diff --git a/build.gradle.kts b/build.gradle.kts
index 72be7ed..8f867b3 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,19 +1,30 @@
plugins {
id("java")
+ id("application")
}
group = "ru.urfu"
version = "1.0-SNAPSHOT"
+application {
+ mainClass = "ru.urfu.Main"
+}
+
repositories {
mavenCentral()
}
dependencies {
- testImplementation(platform("org.junit:junit-bom:5.10.0"))
- testImplementation("org.junit.jupiter:junit-jupiter")
+ implementation("org.jfree:jfreechart:1.5.3")
+ testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
+ testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0")
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0")
+ testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0")
}
tasks.test {
useJUnitPlatform()
-}
\ No newline at end of file
+ testLogging {
+ events("passed", "skipped", "failed")
+ }
+}
diff --git a/src/main/java/ru/urfu/Main.java b/src/main/java/ru/urfu/Main.java
index 5845f6d..e1ab4ef 100644
--- a/src/main/java/ru/urfu/Main.java
+++ b/src/main/java/ru/urfu/Main.java
@@ -1,17 +1,9 @@
package ru.urfu;
-//TIP To Run code, press or
-// click the icon in the gutter.
+import ru.urfu.console.Communicator;
+
public class Main {
public static void main(String[] args) {
- //TIP Press with your caret at the highlighted text
- // to see how GIGA IDE suggests fixing it.
- System.out.printf("Hello and welcome!");
-
- for (int i = 1; i <= 5; i++) {
- //TIP Press to start debugging your code. We have set one breakpoint
- // for you, but you can always add more by pressing .
- System.out.println("i = " + i);
- }
+ Communicator.solve();
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/ru/urfu/console/Communicator.java b/src/main/java/ru/urfu/console/Communicator.java
new file mode 100644
index 0000000..58e0358
--- /dev/null
+++ b/src/main/java/ru/urfu/console/Communicator.java
@@ -0,0 +1,30 @@
+package ru.urfu.console;
+
+import ru.urfu.parser.CsvParser;
+import ru.urfu.graphics.Graphic;
+import ru.urfu.resolver.Resolver;
+
+import java.util.Scanner;
+
+public class Communicator {
+ public static void solve() {
+ String fileName = "src/main/resources/fakePlayers.csv";
+ var players = CsvParser.parseCsvToList(fileName);
+
+ var resolver = new Resolver(players);
+
+ System.out.print("Количество игроков, интересы которых не представляет агентство: ");
+ System.out.println(resolver.getCountWithoutAgency());
+
+ System.out.print("Максимальное число голов, забитых защитником: ");
+ System.out.println(resolver.getMaxDefenderGoalsCount());
+
+ System.out.print("Русское название позиции самого дорогого немецкого игрока: ");
+ System.out.println(resolver.getTheExpensiveGermanPlayerPosition());
+
+ System.out.print("Команда с наибольшим средним числом красных карточек на одного игрока: ");
+ System.out.println(resolver.getTheRudestTeam());
+
+ Graphic.showGraphic(players);
+ }
+}
diff --git a/src/main/java/ru/urfu/csv/CsvParser.java b/src/main/java/ru/urfu/csv/CsvParser.java
new file mode 100644
index 0000000..c218da9
--- /dev/null
+++ b/src/main/java/ru/urfu/csv/CsvParser.java
@@ -0,0 +1,50 @@
+package ru.urfu.parser;
+
+import ru.urfu.model.Player;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.nio.file.Path;
+import java.util.Scanner;
+
+public class CsvParser {
+
+ public static ArrayList parseCsvToList(String pathString) {
+ Path path = Paths.get(pathString);
+ Scanner scanner = getScanner(path);
+ var list = new ArrayList();
+ scanner.nextLine();
+ while (scanner.hasNextLine()) {
+ list.add(parsePlayerRow(scanner.nextLine()));
+ }
+
+ return list;
+ }
+
+ private static Player parsePlayerRow(String row) {
+ var cells = row.split(";");
+ return new Player(
+ cells[0],
+ cells[1],
+ cells[2],
+ cells[3],
+ cells[4],
+ cells[5],
+ Integer.parseInt(cells[6]),
+ Integer.parseInt(cells[7]),
+ Integer.parseInt(cells[8]),
+ Integer.parseInt(cells[9]),
+ Integer.parseInt(cells[10]),
+ Integer.parseInt(cells[11])
+ );
+ }
+
+ private static Scanner getScanner(Path path) {
+ try {
+ return new Scanner(path);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/main/java/ru/urfu/graphics/Graphic.java b/src/main/java/ru/urfu/graphics/Graphic.java
new file mode 100644
index 0000000..9d1f661
--- /dev/null
+++ b/src/main/java/ru/urfu/graphics/Graphic.java
@@ -0,0 +1,42 @@
+package ru.urfu.graphics;
+
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.data.xy.XYSeries;
+import ru.urfu.model.Player;
+
+import javax.swing.*;
+import java.util.List;
+
+public class Graphic {
+ static XYSeriesCollection createDataset(List players) {
+ XYSeries series = new XYSeries("Нападающие");
+ players
+ .stream()
+ .filter(player -> player.getPosition().equals("FORWARD"))
+ .forEach(p -> series.add(p.getTransferCost(), p.getGoals()));
+ return new XYSeriesCollection(series);
+ }
+
+ public static void showGraphic(List players) {
+ var dataset = createDataset(players);
+ JFreeChart chart = ChartFactory.createXYLineChart(
+ "Зависимость количества забитых голов от трансферной стоимости для нападающих",
+ "Трансферная стоимость",
+ "Голы",
+ dataset,
+ PlotOrientation.VERTICAL,
+ true,
+ true,
+ false
+ );
+ JFrame frame = new JFrame("Диаграмма зависимости количества забитых голов от трансферной стоимости для нападающих");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.add(new ChartPanel(chart));
+ frame.pack();
+ frame.setVisible(true);
+ }
+}
diff --git a/src/main/java/ru/urfu/model/Player.java b/src/main/java/ru/urfu/model/Player.java
new file mode 100644
index 0000000..e727b9a
--- /dev/null
+++ b/src/main/java/ru/urfu/model/Player.java
@@ -0,0 +1,57 @@
+package ru.urfu.model;
+
+public class Player {
+ private String name;
+ private String team;
+ private String city;
+ private String position;
+ private String nationality;
+ private String agency;
+ private int transferCost;
+ private int participations;
+ private int goals;
+ private int assists;
+ private int yellowCards;
+ private int redCards;
+
+ public Player(
+ String name,
+ String team,
+ String city,
+ String position,
+ String nationality,
+ String agency,
+ int transferCost,
+ int participations,
+ int goals,
+ int assists,
+ int yellowCards,
+ int redCards
+ ) {
+ this.name = name;
+ this.team = team;
+ this.city = city;
+ this.position = position;
+ this.nationality = nationality;
+ this.agency = agency;
+ this.transferCost = transferCost;
+ this.participations = participations;
+ this.goals = goals;
+ this.assists = assists;
+ this.yellowCards = yellowCards;
+ this.redCards = redCards;
+ }
+
+ public String getName() { return name; }
+ public String getTeam() { return team; }
+ public String getCity() { return city; }
+ public String getPosition() { return position; }
+ public String getNationality() { return nationality; }
+ public String getAgency() { return agency; }
+ public int getTransferCost() { return transferCost; }
+ public int getParticipations() { return participations; }
+ public int getGoals() { return goals; }
+ public int getAssists() { return assists; }
+ public int getYellowCards() { return yellowCards; }
+ public int getRedCards() { return redCards; }
+}
diff --git a/src/main/java/ru/urfu/resolver/Resolver.java b/src/main/java/ru/urfu/resolver/Resolver.java
new file mode 100644
index 0000000..2663fec
--- /dev/null
+++ b/src/main/java/ru/urfu/resolver/Resolver.java
@@ -0,0 +1,80 @@
+package ru.urfu.resolver;
+
+import ru.urfu.model.Player;
+import ru.urfu.graphics.Graphic;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Comparator;
+import java.util.stream.Collectors;
+
+public class Resolver implements IResolver {
+ private final List players;
+
+ public Resolver(List players) {
+ this.players = players;
+ }
+
+ private String translatePositionToRussian(String position) {
+ switch (position.toUpperCase()) {
+ case "GOALKEEPER": return "Вратарь";
+ case "DEFENDER": return "Защитник";
+ case "MIDFIELD": return "Полузащитник";
+ case "FORWARD": return "Нападающий";
+ default: return position;
+ }
+ }
+
+ @Override
+ public int getCountWithoutAgency() {
+ return (int) players
+ .stream()
+ .filter(player ->
+ player.getAgency() == null ||
+ player.getAgency().isEmpty() ||
+ player.getAgency().equals("-")
+ )
+ .count();
+ }
+
+ @Override
+ public int getMaxDefenderGoalsCount() {
+ return players
+ .stream()
+ .filter(player -> player.getPosition().equals("DEFENDER"))
+ .mapToInt(Player::getGoals)
+ .max()
+ .orElse(0);
+ }
+
+ @Override
+ public String getTheExpensiveGermanPlayerPosition() {
+ Player expensiveGerman = players
+ .stream()
+ .filter(player -> player.getNationality().equals("Germany"))
+ .max((p1, p2) -> Long.compare(p1.getTransferCost(), p2.getTransferCost()))
+ .orElse(null);
+
+ if (expensiveGerman != null) {
+ return translatePositionToRussian(expensiveGerman.getPosition());
+ }
+ return "Не найден";
+ }
+
+ @Override
+ public String getTheRudestTeam() {
+ Map teamRedCardsAvg = players
+ .stream()
+ .collect(Collectors.groupingBy(
+ Player::getTeam,
+ Collectors.averagingDouble(Player::getRedCards)
+ ));
+
+ return teamRedCardsAvg
+ .entrySet()
+ .stream()
+ .max(Map.Entry.comparingByValue())
+ .map(Map.Entry::getKey)
+ .orElse("Не найдена");
+ }
+}
diff --git a/src/test/java/ru/urfu/graphics/GraphicTest.java b/src/test/java/ru/urfu/graphics/GraphicTest.java
new file mode 100644
index 0000000..6790837
--- /dev/null
+++ b/src/test/java/ru/urfu/graphics/GraphicTest.java
@@ -0,0 +1,81 @@
+package ru.urfu.graphics;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+import ru.urfu.model.Player;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class GraphicTest {
+
+ private List testPlayers = Arrays.asList(
+ new Player("Forward1", "Team1", "City1", "FORWARD", "Germany", "Agency1", 10000000, 20, 15, 5, 2, 1),
+ new Player("Forward2", "Team2", "City2", "FORWARD", "Brazil", "Agency2", 20000000, 25, 20, 8, 3, 0),
+ new Player("Defender1", "Team3", "City3", "DEFENDER", "Spain", "Agency3", 15000000, 18, 5, 10, 4, 2),
+ new Player("Goalkeeper1", "Team4", "City4", "GOALKEEPER", "France", "Agency4", 8000000, 30, 0, 2, 1, 0),
+ new Player("Forward3", "Team5", "City5", "FORWARD", "Italy", "Agency5", 30000000, 22, 25, 12, 5, 1)
+ );
+
+ @Test
+ void testCreateDataset_FiltersOnlyForwards() {
+ var dataset = Graphic.createDataset(testPlayers);
+
+ assertNotNull(dataset);
+ assertEquals(1, dataset.getSeriesCount());
+
+ var series = dataset.getSeries("Нападающие");
+ assertNotNull(series);
+ assertEquals(3, series.getItemCount());
+ }
+
+ @Test
+ void testCreateDataset_DataCorrectness() {
+ // Act
+ var dataset = Graphic.createDataset(testPlayers);
+ var series = dataset.getSeries("Нападающие");
+
+ assertEquals(3, series.getItemCount());
+
+ boolean foundForward1 = false;
+ boolean foundForward2 = false;
+ boolean foundForward3 = false;
+
+ for (int i = 0; i < series.getItemCount(); i++) {
+ double x = series.getX(i).doubleValue();
+ double y = series.getY(i).doubleValue();
+
+ if (x == 10000000 && y == 15) {
+ foundForward1 = true;
+ } else if (x == 20000000 && y == 20) {
+ foundForward2 = true;
+ } else if (x == 30000000 && y == 25) {
+ foundForward3 = true;
+ }
+ }
+
+ assertTrue(foundForward1, "Должен содержать данные Forward1");
+ assertTrue(foundForward2, "Должен содержать данные Forward2");
+ assertTrue(foundForward3, "Должен содержать данные Forward3");
+ }
+
+ @Test
+ void testCreateDataset_NoForwards() {
+ List noForwards = Arrays.asList(
+ new Player("Defender1", "Team1", "City1", "DEFENDER", "Germany", "Agency1", 10000000, 20, 2, 5, 2, 1),
+ new Player("Goalkeeper1", "Team2", "City2", "GOALKEEPER", "Brazil", "Agency2", 5000_000, 25, 0, 1, 1, 0),
+ new Player("Midfielder1", "Team3", "City3", "MIDFIELD", "Spain", "Agency3", 15000000, 18, 8, 12, 3, 0)
+ );
+
+ var dataset = Graphic.createDataset(noForwards);
+
+ assertNotNull(dataset);
+ assertEquals(1, dataset.getSeriesCount());
+
+ var series = dataset.getSeries("Нападающие");
+ assertNotNull(series);
+ assertEquals(0, series.getItemCount());
+ }
+}
diff --git a/src/test/java/ru/urfu/resolver/ResolverTest.java b/src/test/java/ru/urfu/resolver/ResolverTest.java
new file mode 100644
index 0000000..7f8259a
--- /dev/null
+++ b/src/test/java/ru/urfu/resolver/ResolverTest.java
@@ -0,0 +1,62 @@
+package ru.urfu.resolver;
+
+import org.junit.jupiter.api.Test;
+import ru.urfu.model.Player;
+import ru.urfu.resolver.Resolver;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ResolverTest {
+
+ @Test
+ void testGetCountWithoutAgency() {
+ List players = Arrays.asList(
+ new Player("Player1", "Team1", "City1", "FORWARD", "Germany", "", 1000000, 10, 5, 3, 1, 0),
+ new Player("Player2", "Team2", "City2", "DEFENDER", "Brazil", "Agency1", 2000000, 15, 2, 4, 2, 0),
+ new Player("Player3", "Team3", "City3", "MIDFIELD", "Croatia", "", 1500000, 12, 3, 5, 1, 1)
+ );
+
+ Resolver resolver = new Resolver(players);
+ assertEquals(2, resolver.getCountWithoutAgency());
+ }
+
+ @Test
+ void testGetMaxDefenderGoalsCount() {
+ List players = Arrays.asList(
+ new Player("Player1", "Team1", "City1", "DEFENDER", "Germany", "Agency1", 1000000, 10, 3, 2, 1, 0),
+ new Player("Player2", "Team2", "City2", "DEFENDER", "Brazil", "Agency2", 2000000, 15, 5, 4, 2, 0),
+ new Player("Player3", "Team3", "City3", "FORWARD", "Croatia", "Agency3", 3000000, 12, 10, 5, 1, 0)
+ );
+
+ Resolver resolver = new Resolver(players);
+ assertEquals(5, resolver.getMaxDefenderGoalsCount());
+ }
+
+ @Test
+ void testGetTheExpensiveGermanPlayerPosition() {
+ List players = Arrays.asList(
+ new Player("Player1", "Team1", "City1", "DEFENDER", "Germany", "Agency1", 1000000, 10, 3, 2, 1, 0),
+ new Player("Player2", "Team2", "City2", "FORWARD", "Germany", "Agency2", 5000000, 15, 5, 4, 2, 0),
+ new Player("Player3", "Team3", "City3", "MIDFIELD", "Brazil", "Agency3", 3000000, 12, 10, 5, 1, 0)
+ );
+
+ Resolver resolver = new Resolver(players);
+ assertEquals("Нападающий", resolver.getTheExpensiveGermanPlayerPosition());
+ }
+
+ @Test
+ void testGetTheRudestTeam() {
+ List players = Arrays.asList(
+ new Player("Player1", "Team1", "City1", "DEFENDER", "Germany", "Agency1", 1000000, 10, 3, 2, 1, 2),
+ new Player("Player2", "Team1", "City1", "FORWARD", "Brazil", "Agency2", 2000000, 15, 5, 4, 2, 3),
+ new Player("Player3", "Team2", "City2", "MIDFIELD", "Croatia", "Agency3", 3000000, 12, 10, 5, 1, 1),
+ new Player("Player4", "Team2", "City2", "GOALKEEPER", "Germany", "Agency1", 4000000, 8, 1, 0, 0, 1)
+ );
+
+ Resolver resolver = new Resolver(players);
+ assertEquals("Team1", resolver.getTheRudestTeam());
+ }
+}