Klasa Program.cs
using System;
using ObliczeniaTablica.Logika;
class Program
{
static void Main()
{
Console.WriteLine("=== PROGRAM DO OBLICZEŃ ==="); // menu wyboru
Console.WriteLine("1) W = (3x - 2) / (2y)");
Console.WriteLine("2) Q = ((2x - 3) * y) / z");
Console.WriteLine("3) AB = (2x - y)^2 / (3x + 2)");
Console.WriteLine("4) AC = √((3x - 7)^2 / (2y))");
Console.Write("Wybierz numer zadania (1-4): ");
try
{
int wybor = int.Parse(Console.ReadLine());
var zadanie = (Zadanie)wybor; // TU DOKONUJEMY WYBORU ZADANIA, jednocześnie
// tu liczba z wyboru jest rzutowana (zamieniana) na typ wyliczeniowy
//enum Zadanie (public enum Zadanie z LogikaObliczenia.cs
//
// wczytujemy tylko potrzebne zmienne
double x = 0, y = 0, z = 0; //ustawienia startowe
Console.Write("Podaj x: ");
x = LogikaObliczen.ParseDouble(Console.ReadLine());
if (zadanie != Zadanie.Q && zadanie != Zadanie.AC && zadanie != Zadanie.W && zadanie != Zadanie.AB)
throw new ArgumentOutOfRangeException(nameof(zadanie)); //tu sprawdzamy, czy zmienna zadanie
// NIE jest żadną z czterech dozwolonych opcji
// (W,Q,AB,AC)
// ostatnia linia jeśli wybór nie pasuje , wyrzuca błąd
Console.Write("Podaj y: ");
y = LogikaObliczen.ParseDouble(Console.ReadLine());
if (zadanie == Zadanie.Q) // jeśli użytkownik wybrał Q
{
Console.Write("Podaj z: "); // podajemy dodatkowo y
z = LogikaObliczen.ParseDouble(Console.ReadLine());
}
double wynik = LogikaObliczen.Oblicz(zadanie, x, y, z); // tu przekazujemy wszystkie dane do LogikaObliczenia
// do metody Oblicz
Console.WriteLine("\n--- WYNIK ---");
Console.WriteLine($"{zadanie}: {wynik:F6}");
}
catch (FormatException)
{
Console.WriteLine("Błąd: wprowadź poprawne liczby (np. 2.5 lub 2,5).");
}
catch (ArgumentException ex)
{
Console.WriteLine("Błąd danych: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Nieoczekiwany błąd: " + ex.Message);
}
Console.WriteLine("\nNaciśnij dowolny klawisz, aby zakończyć...");
Console.ReadKey();
}
}
klasa LogikaObliczenia
using System;
using System.Globalization;
using ObliczeniaTablica.Walidacja;
namespace ObliczeniaTablica.Logika
{
public enum Zadanie { W = 1, Q = 2, AB = 3, AC = 4 } //tu definiujemy typ wyliczeniowy dla Program.cs
// czyli jakby nowy typ danych ale z kilkama
//konkretnymi wartościami (liczba-nazwa)
public static class LogikaObliczen
{
// (1) W = (3x - 2) / (2y)
public static double W(double x, double y)
{
WalidacjaWejscia.RzucGdyZero(y, nameof(y));
return (3 * x - 2) / (2 * y);
}
// (2) Q = ((2x - 3) * y) / z
public static double Q(double x, double y, double z)
{
WalidacjaWejscia.RzucGdyZero(z, nameof(z));
return ((2 * x - 3) * y) / z;
}
// (3) AB = (2x - y)^2 / (3x + 2)
public static double AB(double x, double y)
{
double mianownik = 3 * x + 2;
WalidacjaWejscia.RzucGdyZero(mianownik, "3x + 2");
double licznik = Math.Pow(2 * x - y, 2);
return licznik / mianownik;
}
// (4) AC = sqrt( (3x - 7)^2 / (2y) )
public static double AC(double x, double y)
{
double mianownik = 2 * y;
WalidacjaWejscia.RzucGdyZero(mianownik, "2y");
double licznik = Math.Pow(3 * x - 7, 2);
double podPierwiastkiem = licznik / mianownik;
if (podPierwiastkiem < 0)
throw new ArgumentException("Wyrażenie pod pierwiastkiem jest ujemne.");
return Math.Sqrt(podPierwiastkiem);
}
/// Nie wszystkie parametry są używane w każdym zadaniu.
public static double Oblicz(Zadanie zadanie, double x, double y, double z)
{
return zadanie switch // Metoda Oblicz sama rozpoznaje które równanie wybrałeś
// korzystając ze switch
// parametry zmiennych uzupełniają odpowiednie metody
{
Zadanie.W => W(x, y),
Zadanie.Q => Q(x, y, z),
Zadanie.AB => AB(x, y),
Zadanie.AC => AC(x, y),
_ => throw new ArgumentOutOfRangeException(nameof(zadanie))
};
}
/// Pomocnicze: bezpieczny parse akceptujący kropkę i przecinek.
public static double ParseDouble(string input)
{
if (double.TryParse(input.Replace(',', '.'),
NumberStyles.Float,
CultureInfo.InvariantCulture,
out double val))
return val;
throw new FormatException("Niepoprawna liczba.");
}
}
}
Klasa WalidacjaWejscia.cs
using System;
namespace ObliczeniaTablica.Walidacja
{
public static class WalidacjaWejscia
{
public static void RzucGdyZero(double wartosc, string nazwa)
{
if (wartosc == 0)
throw new ArgumentException($"{nazwa} nie może być równe 0.");
}
}
}
TESTY JEDNOSTKOWE – krok po kroku
1) Dodaj drugi projekt (MSTest)
- Otwórz rozwiązanie z projektem
ObliczeniaTablica(konsola). - W Eksploratorze rozwiązań: PPM na Rozwiązanie ‘ObliczeniaTablica’ → Dodaj → Nowy projekt…
- Wyszukaj „test” i wybierz Projekt testu jednostkowego MSTest (.NET).
- Nazwa:
ObliczeniaTablica.Tests→ Utwórz. - Po utworzeniu w projekcie testowym pojawi się przykładowy plik testu — możesz go usunąć albo zastąpić własnym.
💡 Upewnij się, że oba projekty celują w ten sam framework (np.
.NET9):
- PPM na projekt → Właściwości → Aplikacja → Docelowa platforma .NET: ustaw .NET 9.0.
Jeśli główny projekt manet8.0-windows(to dotyczy WPF/WinForms), wtedy testy też ustaw nanet9.0-windowsalbo dodaj drugi „target” — najprościej ustawić tak samo.
2) Podłącz projekt testów do projektu z logiką
- W projekcie
ObliczeniaTablica.Tests: PPM na Zależności → Dodaj odwołanie do projektu… - Zaznacz
ObliczeniaTablica→ OK.
(To jest kluczowe — bez tego testy nie „widzą” klas z Twojej logiki.)
3) Utwórz plik z testami
Nazwij plik ObliczeniaTests.cs.
PPM na projekt ObliczeniaTablica.Tests → Dodaj → Nowy element… → Klasa.
Klasa Obliczenia..Tests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using ObliczeniaTablica.Logika; // odwołanie do Twojej logiki
namespace ObliczeniaTablica.Tests
{
[TestClass]
public class ObliczeniaTests
{
// --- Testy poprawnych wyników ---
[TestMethod]
public void W_Poprawny()
{
// (3*2-2)/(2*3) = 4/6 = 0.666...
Assert.AreEqual(2.0 / 3.0, LogikaObliczen.W(2, 3), 1e-9);
}
[TestMethod]
public void Q_Poprawny()
{
// ((2*2-3)*3)/4 = (1*3)/4 = 0.75
Assert.AreEqual(0.75, LogikaObliczen.Q(2, 3, 4), 1e-9);
}
[TestMethod]
public void AB_Poprawny()
{
// (2*2-3)^2/(3*2+2) = 1/8 = 0.125
Assert.AreEqual(0.125, LogikaObliczen.AB(2, 3), 1e-9);
}
[TestMethod]
public void AC_Poprawny()
{
// ((3*3-7)^2)/(2*2) = 4/4 = 1 => sqrt(1) = 1
Assert.AreEqual(1.0, LogikaObliczen.AC(3, 2), 1e-9);
}
// --- Testy wyjątków (walidacja) ---
[TestMethod]
public void W_GdyYZero_Rzuca()
=> Assert.ThrowsException<ArgumentException>(() => LogikaObliczen.W(1, 0));
[TestMethod]
public void Q_GdyZZero_Rzuca()
=> Assert.ThrowsException<ArgumentException>(() => LogikaObliczen.Q(1, 2, 0));
[TestMethod]
public void AB_GdyMianownikZero_Rzuca()
=> Assert.ThrowsException<ArgumentException>(() => LogikaObliczen.AB(-2.0 / 3.0, 5));
[TestMethod]
public void AC_GdyPodPierwiastkiemUjemne_Rzuca()
=> Assert.ThrowsException<ArgumentException>(() => LogikaObliczen.AC(0, -1));
// --- Test routera (menu) ---
[TestMethod]
public void Oblicz_W_ZwracaToSamoCoW()
{
double x = 2, y = 3;
var a = LogikaObliczen.W(x, y);
var b = LogikaObliczen.Oblicz(Zadanie.W, x, y, 0);
Assert.AreEqual(a, b, 1e-12);
}
[TestMethod]
public void Oblicz_Q_ZwracaToSamoCoQ()
{
double x = 2, y = 3, z = 4;
var a = LogikaObliczen.Q(x, y, z);
var b = LogikaObliczen.Oblicz(Zadanie.Q, x, y, z);
Assert.AreEqual(a, b, 1e-12);
}
}
}
Assert.AreEqual – porównuje dwa wyniki, pierwszy to wartość oczekiwana, drugi to co faktycznie zwrócił

