Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Java CI with Gradle

on:
push:
branches: [ master2 ]
pull_request:
branches: [ master2 ]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4 # Checks out your repository under $GITHUB_WORKSPACE
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin' # Or 'adopt', 'zulu', etc.
cache: 'gradle' # Caches Gradle dependencies
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build # This will also run the 'test' task by default
- name: Run Unit Tests
run: ./gradlew test # Explicitly run the test task if 'build' doesn't cover it
17 changes: 17 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("java")
id("application")
id("jacoco")
}

group = "ru.urfu"
Expand All @@ -13,10 +14,26 @@ repositories {
dependencies {
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.mockito:mockito-core:5.+")
implementation("org.jfree:jfreechart:1.5.6")
}

jacoco {
toolVersion = "0.8.12"
}

tasks.test {
useJUnitPlatform()
finalizedBy(tasks.jacocoTestReport)
}

tasks.jacocoTestReport {
dependsOn(tasks.test)
reports {
xml.required = false
csv.required = false
html.outputLocation = layout.buildDirectory.dir("jacocoHtml")
}
}

application {
Expand Down
28 changes: 20 additions & 8 deletions src/main/java/ru/urfu/Main.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
package ru.urfu;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
import ru.urfu.chart.ChartDrawer;
import ru.urfu.chart.ChartMapper;
import ru.urfu.model.Player;
import ru.urfu.parser.CsvParser;
import ru.urfu.resolver.Resolver;

import java.io.IOException;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import java.util.function.ToIntFunction;

public class Main {
public static void main(String[] args) {
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
// to see how GIGA IDE suggests fixing it.
System.out.printf("Hello and welcome!");
var parser = new CsvParser("/Users/denis/IdeaProjects/Java2025_2/players.csv");

Resolver resolver = new Resolver(parser);

System.out.println(resolver.getTeams());

for (int i = 1; i <= 5; i++) {
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
System.out.println("i = " + i);
}
var chartData = ChartMapper.mapDataToChart(parser.parseCsvToList());
ChartDrawer.showChart(chartData);
}
}
22 changes: 22 additions & 0 deletions src/main/java/ru/urfu/chart/ChartDrawer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ru.urfu.chart;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.xy.XYSeriesCollection;

public class ChartDrawer {
public static void showChart(XYSeriesCollection dataset) {
JFreeChart chart = ChartFactory.createXYBarChart(
"Среднее количество голов по позициям",
"Позиция",
false,
"Среднее кол-во голов",
dataset
);

ChartFrame frame = new ChartFrame("Среднее число голов по позиции", chart);
frame.pack();
frame.setVisible(true);
}
}
43 changes: 43 additions & 0 deletions src/main/java/ru/urfu/chart/ChartMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ru.urfu.chart;

import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import ru.urfu.model.Player;
import ru.urfu.model.Position;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChartMapper {
public static XYSeriesCollection mapDataToChart(List<Player> players) {
Map<Position, List<Integer>> positionToGoals = new HashMap<>();

for (Player player : players) {
Position position = player.position();
int goals = player.goals();

positionToGoals.computeIfAbsent(position, k -> new ArrayList<>()).add(goals);
}

XYSeriesCollection dataset = new XYSeriesCollection();

int seriesIndex = 0;
for (Map.Entry<Position, List<Integer>> entry : positionToGoals.entrySet()) {
Position position = entry.getKey();
List<Integer> cardsList = entry.getValue();

double average = cardsList.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0);

XYSeries series = new XYSeries(position);
series.add(seriesIndex++, average);
dataset.addSeries(series);
}

return dataset;
}
}
8 changes: 8 additions & 0 deletions src/main/java/ru/urfu/model/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.urfu.model;

public record Player(
String name,
Position position,
String agency,
int goals
) { }
8 changes: 8 additions & 0 deletions src/main/java/ru/urfu/model/Position.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ru.urfu.model;

public enum Position {
GOALKEEPER,
DEFENDER,
MIDFIELD,
FORWARD
}
39 changes: 39 additions & 0 deletions src/main/java/ru/urfu/parser/CsvParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ru.urfu.parser;

import ru.urfu.model.Player;
import ru.urfu.model.Position;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class CsvParser {
private final String path;

public CsvParser(String path) {
this.path = path;
}

public List<Player> parseCsvToList() {
try {
return Files.readAllLines(Paths.get(path))
.stream()
.skip(1)
.map(CsvParser::parsePlayerRow)
.toList();
} catch (IOException e) {
return List.of();
}
}

private static Player parsePlayerRow(String row) {
var cells = row.split(";");
return new Player(
cells[0],
Position.valueOf(cells[3]),
cells[5],
Integer.parseInt(cells[8])
);
}
}
23 changes: 22 additions & 1 deletion src/main/java/ru/urfu/resolver/IResolver.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
package ru.urfu.resolver;

import ru.urfu.model.Player;

import java.util.List;
import java.util.Map;
import java.util.Set;

public interface IResolver {

List<Player> getPlayers();

// Выведите количество игроков, интересы которых не представляет агентство.
int getCountWithoutAgency();

// Выведите максимальное число голов, забитых защинтником.
// Выведите максимальное число голов, забитых защитником.
int getMaxDefenderGoalsCount();

// Выведите русское название позиции самого дорогого немецкого игрока.
String getTheExpensiveGermanPlayerPosition();

// Верните имена игроков, сгруппированных по позициям, на которых они играют.
Map<String, String> getPlayersByPosition();

// Верните множество команд, которые представлены в чемпионате.
Set<String> getTeams();

// Верните топ-5 команд по количеству забитых мячей, и количество этих мячей.
Map<String, Integer> getTop5TeamsByGoalsCount();

// Верните агентство, сумма игроков которого наименьшая.
String getAgencyWithMinPlayersCount();

// Выберите команду с наибольшим средним числом удалений на одного игрока.
String getTheRudestTeam();
}
72 changes: 72 additions & 0 deletions src/main/java/ru/urfu/resolver/Resolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ru.urfu.resolver;

import ru.urfu.model.Player;
import ru.urfu.model.Position;
import ru.urfu.parser.CsvParser;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class Resolver implements IResolver {
private final List<Player> players;

public Resolver(CsvParser parser) {
this.players = parser.parseCsvToList();
}

@Override
public List<Player> getPlayers() {
return players;
}

@Override
public int getCountWithoutAgency() {
return (int) players.stream()
.filter(player -> player.agency() == null || player.agency().isEmpty())
.count();
}

@Override
public int getMaxDefenderGoalsCount() {
return players.stream()
.filter(player -> player.position() == Position.DEFENDER)
.mapToInt(Player::goals)
.max()
.orElse(0);
}

@Override
public String getTheExpensiveGermanPlayerPosition() {
return "";
}

@Override
public Map<String, String> getPlayersByPosition() {
return Map.of();
}

@Override
public Set<String> getTeams() {
return players.stream()
.map(Player::agency)
.filter(agency -> agency != null && !agency.isEmpty())
.collect(Collectors.toSet());
}

@Override
public Map<String, Integer> getTop5TeamsByGoalsCount() {
return Map.of();
}

@Override
public String getAgencyWithMinPlayersCount() {
return "";
}

@Override
public String getTheRudestTeam() {
return "";
}
}
Loading