Софтуерно Инженерство
Loading...
+ Нов въпрос
Tr00peR avatar Tr00peR 569 Точки

[Homework] OOP - Other Types - Септември 2014

Здравейте колеги, нека тук коментираме задачите от домашното за други типове в ООП.

Ето моите решения:

  1. Galactic GPS
  2. Fraction Calculator
  3. Generic List - докато първите две задачи са си straight-forward тук може да има доста различни варианти и ще ми е интересно да видя други решения, както и да получа коментари за моето.

Интересно ми е и за версията дали има начин да се извади директно в променлива, а не да се взима от масива с атрибути. 

Поздрави!

14
C# OOP Basics 26/09/2014 23:42:27
ttitto avatar ttitto 1155 Точки

Ето го и моят комплект. Старал съм се да спазвам правилата за форматиране от първия урок по КПК.

GalacticGPS

FractionCalculator

GenericList<T> + Version - не можах да избегна dynamic при двата generic метода Min<T> и Max<T>, въпреки че пробвах да кастна изхода към типа на T с reflection. Създадох си един клас Student за тестовете, защото исках да видя как ще реагира референтен тип на многобройните копирания на вътрешния масив.

ЕДИТ: Добавена задача!

WordDocumentGenerator - Единствено не успях да направя списъкът с точките да бъде навътре. Знам как се променя поредността на ListItem в йерархията на списъка, но тогава се променя и булетът пред него.

3
25/09/2014 21:10:17
StanDimitroff avatar StanDimitroff 90 Точки

Здравей,

всъщност проверките за препълване на типа в пропъртитата на задача 2 не са ли излишни? Препълването става при самото умножение и гърми в checked блока, а иначе ако искаме да подадем на конструктора или на пропъртито стойности, които са извън обхвата на типа няма да ни даде още compiletime. Или бъркам?

0
borislavml avatar borislavml 368 Точки

 @ttitto гледам, че при overload-a на операторите ползваш пропъртитата. Има ли някаква причина? Нали един път вече създадени двете дроби,които събираме са минали проверка от там през сетъра. Или това е по конвенция, оувърлоуда се прави като конструктора, с пропъртита. Стана ми интерсно просто, дали би имало някакво значение при последващо евентуално наследяване на структа, или за пърформънса? smile

0
ttitto avatar ttitto 1155 Точки

@StanDimitroff: Ако се опиташ да създадеш нов Fraction през конструктора, чрез сума на две променливи за знаменател или числител ще успееш да вкараш препълнен long. Имам предвид нещо подобно: long a = someExpression; long b = someOtherExpression; Fraction fr = new Fraction(a + b, a); Това компилаторът не би трябвало да го хване, но runtime може да се стигне до препълване.

@borislavml: Когато имам свойства, ползвам винаги тях в класа, освен ако не трябва да прескоча умишлено валидацията. Незнам дали е по конвенции така, но със сигурност ми създава комфорт и не мисля всеки път дали трябва да е полето или свойството.

1
Valleri avatar Valleri 292 Точки

@Tr00per - добре си се сетил за този начин за кастване на "VersionAttribute", аз доста мъчих и излязох с едно доста дълго LINQ, но пък върши работа :)

Ето една задача с звезда от мен, останалите са в репо-то.

Word File Generator

Извинявам се за разплетения код, но утре ще го рефакторирам, докато се лутах из слабата документация...тоест форум на пичовете направили DocX трупах код и накрая излезе това. Сигурно ще го подредя по класове според обекта, който се създава.

2
ttitto avatar ttitto 1155 Точки

@Trooper:

По Fraction: Защо са ти публични свойства Denominator и Numerator, след като използваш директно полетата?При това умножение на числител и знаменател много лесно може да се превърти long типът и да подадеш грешен резултат.

GenericList<T>: Много чисто решение. Само методите Min и Max трябва също да са generic, което малко усложнява нещата

1
Valleri avatar Valleri 292 Точки

Не знам дали е логично да са Generic Min/Max, защото после трябва да зададеш тип, вместо лесно да им сложиш точката и да вземеш стойността. И не ги усложнява много : )

0
ttitto avatar ttitto 1155 Точки

условието

0
Tr00peR avatar Tr00peR 569 Точки

Ами в моя случай няма значение дали ползвам поле или пропърти, защото изобщо не се бях сетил, че може да превърти.

Ще трябва да сложа валидация в пропъртитата явно. Мерси за коментара.

EDIT - всъщност няма нужда от валидация, един checked блок е достатъчен :)

 

Иначе за generic Min & Max в конкретната задача за мен просто няма никакъв смисъл, така или иначе класът е типизиран, няма какво друго да се търси. Или е недогледано условието, или идеята е да ображним дженерик метод без да има смисъл от него.

0
24/09/2014 09:12:53
BoniMislyashki avatar BoniMislyashki 36 Точки

На втора задача може да се добави метод GCD (greatest common divisor) в конструктора , за да не се получава 1/8 + 1/2 = 10/16, а да изкарва за числител и знаменател съответно 5 и 8. Ето едно примерно решение: Fraction Calculator

2
oconne avatar oconne 113 Точки

Точно щях да поствам за GCD-то, но видях че ти си го направил. В допълнение може да се сложи публичен нормиращ метод Normalize(), който напълно копира имплементацията на конструктора, за да може когато сетваме по отделно num и denum отново да имаме възможноста да ги съкратим. Пробвах цялата тази история да я вложа в сетерите, но се получи голяма каша.

2
RoYaL avatar RoYaL SoftUni Team Trainer 6883 Точки

Копиране на имплементацията на конструктора е лоша идея.

Ако ще има такъв метод, то той трябва да връща чисто нова инстанция на класа с новите стойности.

0
oconne avatar oconne 113 Точки

Много ми харесва това което казваш. Но пък Normalize() няма сигнатурата на конструктура, това не извинява ли донякъде ползването. Можеш ли да го разпишеш в явен вид това което каза, ако имаш време, само да видя дали правилно съм те разбрал. (новата истанция замества напълно старата нали?)

0
oconne avatar oconne 113 Точки

Tрупър, GenericList-a ми се струва че също е straight-forward. Защото става въпрос за имплементиране на масив, а това е стандартна здача в ООП. В домашното не е ли "загатнато"  че трябва да използваме auto-grow functionality, което афтоматично стеснява стратегията ни до статичен масив, остава само да го типизираме и наследим с подходящият интерфейс (за сравнимост) и сме готови. За Макс и Мин използваме CompareTo, което е наследство от интерфейса. Домашно

0
borislavml avatar borislavml 368 Точки

Още един пакет след двудневна борба! ЦЪК

2
ZvetanIG avatar ZvetanIG 925 Точки

Най-накрая приключих с това домашно и аз.

Първа и втора нямаше никакви проблеми.  В трета и аз смятам, че e  нелогично за Min()  и Max() да са generic, тъй като типа си го подава GenericList. Опитах се да ги направя такива, но нещо не можа да ми се пречупи акъла, как точно да стане това.

За четвърта благодаря на колегите, които са я направили преди мен. Бяха ми много полезни.

Ето и ДОМАШНОТО.

2
HPetrov avatar HPetrov 822 Точки

Здравей.

Ще си призная, че малко взаимствах от твоята 3-та задача докато запаля малко за какво иде реч. Имплементирах си мой метод, който да проверява дали индексите, които подаваш в методите са в границите вместо всекъ път дългите try/catch и допълнителни проверки в последствие. Също така мога да ти предложа 1 по кратко и според мен по-готино решение за принтиране на колекцията на 1 ред:

string.Join(", ", this.storage.Select(x =&amp;gt; x.ToString()).ToArray());

 Кратко и ясно без StringBuilder-и :) Не знам дали е по-бързо обаче но пък е доста по-елегантно решение. Естествено елементите в тази колекция трябва да имат някаква имплементация на ToString()

Edit: Мдаам. В случая със StringBuilder е по-добре явно, защото ако го създадеш и добавиш само 1 елемент, и после го принтираш ще ти изплюе целия лист а не само тези стойности, който са добавени.

1
27/09/2014 21:48:56
vvulevv avatar vvulevv 51 Точки

Може ли да те попитам какво прави : this() в конструктора на Location от първата задача?

0
ZvetanIG avatar ZvetanIG 925 Точки

Ако не го сложиш компилатора дава грешка.  Просто така са направени struct.  Искат да се изпълни дефолтния конструктор.

1
b.grigorov avatar b.grigorov 7 Точки

Здравей колега,

можеш ли да ми обясниш " public T Min<X>()" или по-точно Х,

защо са различни буквите и защо гърми ако и 2те са Т

0
Velichkov avatar Velichkov 87 Точки

Защото типът T вече е деклариран на ниво клас (class GenericList<T>) и когато сложиш <Т> и на методите, се опитва да го редефинира. Оттам идва и грешката. Друг е въпросът, че тези два метода Min и Max няма смисъл да са generic тъй като се извикват от инстанция на класа.

1
30/09/2014 10:14:35
aslv1 avatar aslv1 304 Точки

Здравейте и от мен!

На трета задача (GenericList<T>) първоначално се опитах да спазя стриктно условието, т. е. самият клас да може да създава инстанции за всяко T, а методите Min<T> и Max<T> да са позволени/видими само за тия T, за които T имплементира IComparable<T>.

Класът ми трябваше да бъде public class GenericList<T>,
а методите ми: public T Min<T>() where T : IComparable<T>.

За съжаление установих, че това не мога да го направя, имам предвид, че не можах да направя класа за всяко T, а методите Min и Max да са само за T : IComparable<T>. Затова извърших следната проверка (вътре в тялото на метода) - ако T не е сравним тип, хвърлям InvalidOperationException:

if (!typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
{
    throw new InvalidOperationException(string.Format("Elements of type {0} are not comparable, so the GenericList<{0}> cannot has maximal value.", typeof(T).FullName));
}

Тук е пълният ми код - моля за коментари и забележки smile

Успех!

1
27/09/2014 20:08:14
iordan_93 avatar iordan_93 SoftUni Team Trainer 407 Точки

Здравейте на всички!

Моите решения:

1. Galactic GPS
2. Fraction Calculator
- задачата може да се направи много по-интересна, ако се смята и съкращаването на дробите, но реших да пропусна тази част за простота. Иначе би могло да се направи с още две полета, примерно realNumerator и realDenominator и да се проверява дали numerator се дели на denominator по някакъв начин. Проблемът за integer factorization обаче хич не е приятен laughing3. Generic List - една много интересна задача. Мисля, че кодът се документира сам. Бих могъл да направя unit tests, а не просто един Main() метод, в който пиша на конзолата, но реших, че засега и това върши работа.
4. Version Attribute - стандартна имплементация на атрибут. Интересното е, че за да се вземат атрибутите на един клас, трябва да се използва reflection.

Очаквам вашите предложения за оправяне на бъгове и коментари. Благодаря предварително smile!

2