Loading...
Valleri avatar Valleri 304 Точки

[Homework] PHP Basics - PHP Flow Control, Functions

Здравейте,
поствам решенията си на домашното от днес за "Управление на изпълнението". Има една "задача-проект", която ми беше изключително интересна, става въпрос за 7-ма разбира се :)

1. Sum Of Squares - Play at PHP Fiddle

2. Rich People`s Problems - Play at PHPFiddle

3. Find Primes In Range

4. Show Annual Expenses

5. Sum Of Digits

6. Modify String

7. Student Sorting


GitHub Repository



Тагове:
7
PHP Web Development Basics 19/08/2014 10:48:55
RoYaL avatar RoYaL Trainer 6849 Точки

Здравей,

За 7ма задача ще си позволя да направя една забележка - в РНР конструктурите от версия 5 нататък се дефинират с магическия __construct() метод, вместо с името на класа. Има backwards compatibility с РНР 4 и това, което си направил е възможно, но не е препоръчително.

Също така при неймспейснати класове, това backward compatibility отпада, тъй като класът става Namespace\Classname а методът Classname не съвпада, което означава че може да се забъркаш в нежелани резултати с тази практика.

http://php.net/manual/en/language.oop5.decon.php

Прието е по конвенция да се слагат access modifier-и на методите, дори и когато се използва дефолтния (public). Първо заради четимост и второ, че може от следващата версия дефолтния модифайър да стане например protected. Тогава всички функции, на които се пропуснал модифайъра, ще станат protected. А protected конструктур означава, че не може да инстанцираш класа :) 

public function __construct($fname, $sname, $mail, $score) {
    $this->firstName = $fname;
    $this->secondName = $sname;
    $this->email = $mail;
    $this->score = $score;
}

И тъй като съм тръгнал в този дух, има нещо, което не е толкова важно за момента, но ще го спомена - Accessors vs. Public variables

P.S.: Наясно съм, че класът е дефиниран като структура за преизползване, просто ми се искаше да спомена тези тънкости по от рано, за всички, които са решили да ползват класове и обекти :)

6
19/08/2014 10:10:21
Valleri avatar Valleri 304 Точки

Благодаря, мен! Попринцип се интересувам доста от стандартите при писане на код и мнението ти ми беше много полезно. Ще го подобря. Кудос!

0
RoYaL avatar RoYaL Trainer 6849 Точки

Радвам се, че се интересуваш от тези неща :)

В такъв случай, ако ти е интересно, разгледай и PSR-2 стандарта, който неофициално се е наложил сред големите проекти и обикновено е конвенционалния за писане, когато пишеш с други хора в отбор.

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md

Изчиства разни дребни нещо като else-а да е на същия ред на затварящата скоба на if-a, на класове и методи скобата да е на новия ред, и най-важното според мен - индентацията да е спейсове, а не табове :) Както и установява доста добри практики за четимостта

3
19/08/2014 11:09:28
iordan_93 avatar iordan_93 Trainer 407 Точки

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

Ето ги и моите решения на задачите. Както винаги, ще се радвам на коментари и критика smile

1. Square Root Sum - задачата е ясна
2. Rich People's Problems - тук има две интересни неща. Първо, array_rand() връща ключ, а не стойност от масива и синтаксисът става малко грозен (ако не обичате да декларирате много локални променливи laughing) - $arr[array_rand($arr)];. Второ, preg_match() има опция PREG_SPLIT_NO_EMPTY, която работи като StringSplitOptions.RemoveEmptyEntries в C#.

И още нещо, което ме разочарова - в PHP няма named parameters. Така ако искам да подам на функцията preg_match($pattern, $string, $flags = PREG_SPLIT_NO_EMPTY), т. е. ако пропусна третия параметър и подам четвъртия по име, това не работи cry. Тези named parameters май само в PHP още ги няма...
3. Show Annual Expenses - задачата е сравнително лесна, решава се с два вложени цикъла (за годините и месеците). По-интересната част е да се вземат имената на месеците наготово, а не като hardcode-нат масив
4. Find Primes in Range - в тази задача е интересен алгоритъмът за намиране на просто число. Той може да се напише по много начини, но хубавото е, че позволява да бъде страшно оптимизиран. Не се проверяват числа, по-малки от две, всички четни се изключват, проверява се за делимост само на нечетни числа (във for-цикъла) и последно - цикълът върви не до самото число, което проверяваме, а до квадратния му корен (което може да се докаже - оставям това на по-добри математици от мен tongue-out). Коментарите във функцията обясняват за какво става въпрос, но аз ще илюстрирам с пример - ако проверяваме дали числото 100 се дели на всяко число от 2 до 100 (което е най-наивният и най-бавният вариант), правим около 100 проверки, а с тази функция правим само една - виждаме, че числото е четно и изобщо не се занимаваме с него.
5. Sum of Digits - интересното тук, е че може да използваме директно array_sum() върху split-натия string и да си спестим писането на един for-цикъл smile
6. Modify String - един много ценен урок, който може да се научи от тази задача е, че входните данни от външния сват винаги трябва да се проверяват много стриктно, особено пък ако един прост string е име на функция, която ще се изпълни. POST заявка може да се направи не само от браузър и е много лесно един хакер да подаде dangerousFunction като string и тя да се изпълни (бих могъл да направя за демонстрация видео или нещо като tutorial). Още по-лесно е, ако функцията не приема параметри (така ще игнорира подадения ѝ string и може да направи още по-големи поразии laughing).
7. Student Sorting - тук също проверявам дали полето и редът за сортиране са сред разрешените, защото в противен случай сортирането ще гръмне. В StackOverflow има много интересна функция, която може да сортира масив от масиви (jagged array) в зависимост от даден ключ и дадена последователност на сортиране. Още по-интересното на функцията е, че ако ѝ се подадат повече параметри, тя сортира масива последователно по всички (действа както .OrderBy().ThenBy().ThenBy()... в LINQ). С помощта на тази функция задачата става доста по-лесна smile

18
20/08/2014 13:12:04
Valleri avatar Valleri 304 Точки

Амиии не е лош алгоритъма за prime, но "моя е по-добър" : )) Много си го харесвам и мисля че е доста по-бърз защото проверява и кратни на 3 и минава през 6 елемента на врътка на цикъла.

0
iordan_93 avatar iordan_93 Trainer 407 Точки

Със сигурност - но така можем да направим едни if-ове (не може да стане със switch, защото проверяваме изрази), дето проверяват с числата до 100 (до 97 по-точно). Въпросът е, че всяко следващо число "отмахва" все по-малко възможности (а if-овете не са много бързи като цяло, особено голяма серия if  /elseif...). Това също не е много оптимизирано за performance - if($num % 2 == 0) return ($num == 2); - трите if-a може да са if / elseif / elseif. Но да не издребняваме - двата if-a във for-цикъла например правят кода по-труден за четене, освен това има т. нар. класове сложност на алгоритмите - броят операции в двата алгоритъма се различават с константа, освен това константата е много малка.

Всъщност, истинската оптимизация в алгоритъма е да не проверяваш всички числа до числото, а до корен квадратен от него - това прави сложността на алгоритъма от линейна (по подаденото число) до sub-linear (не знам как се превежда на български).

Така де, харесвам алгоритъма ти, но е малко overkill smile. Има две основни правила при оптимизацията на код за бързодействие: 1) оптимизирай само когато се налага (защото това обикновено води до гаден код), 2) оптимизирай само ако резултатът е по-добър в пъти (примерно кодът върви 5 пъти по-бързо), а не в проценти (особено добре е да смениш алгоритъма, ако минеш в "по-бърз" клас сложност).

1
19/08/2014 20:31:39
Valleri avatar Valleri 304 Точки

Първо, този алгоритъм, който си ползвал е на-стандартния, тоест, ако отвориш един туториал, първо него намираш и не е никак оптимизиран, дори и моя не е - ако ги пуснеш в SPOJ - задачата с прости числа, ще увиснат яко. 
Този се води от най-бързите и със сигурност ми е трудно четим на пръв поглед Sieve of Atkins
Не виждам нищо 'бавно' в if защото е една проста математическа операция. докато вляза в цикъла да търся номера вече съм намерил решение за много голям брой случай. 
Второ, и в моето решение стигам до корен на числото, не до самото число.
За четимостта е малко субективно, аз не виждам нищо нечетимо в моя код, но виждам ползите - проверката за остатък от делене на 3, което ни улеснява като след това можем да минаваме през 6 числа в цикъла. Не ми се правят тестове сега, но основната ми идея е - if - бързо, loop - бавно.

0
RoYaL avatar RoYaL Trainer 6849 Точки

Моите препоръки са по-скоро към код стандарта.

Ако погледнеш тази статия, която показва различните начини за темплейтване с РНР (вярно, малко стара е, показани са и неща, които не трябва да се ползват, като например Smarty) ще видиш, че повечето common ways държат отварящия и затварящия РНР таг, там където е контролната структура

А и на мен лично ми зиглежда по-четимо като са на същия ред. Няма нужда от 3 за отварянето на форийч или пък за затварянето му :)

http://www.smashingmagazine.com/2011/10/17/getting-started-with-php-templating/

<?php foreach ($this->friends as $friend): ?>
    <friend><?=$friend?></friend>
<?php endforeach; ?>

2
20/08/2014 17:18:17
Ventsislav avatar Ventsislav 343 Точки

Малко решения и от мен : цък.

1
ZvetanIG avatar ZvetanIG 907 Точки

Ето и моето домашно  ТУК.

В 5 задача се сблъсках с интересни функции, които вместо false връщат 0. Това понякога доста може да ти обърка сметките.

Шеста изглежда страшна, но се оказа доста приятна и лека задачка.

4
Stoyan.Stoyanov avatar Stoyan.Stoyanov 96 Точки
Колега, само една малка забележка за първа задача. Аз също бях подходил по същият начин - използвайки number_format функцията. Проблемът е, че тя стрингосва променливата, при което се губи точност. Това показа и Наков на упражненията. В случая, по-точно би се получило с round($int, 2). Предполагам ги знаеш тези неща, но все пак.
0
ZvetanIG avatar ZvetanIG 907 Точки

Стояне, блогодаря за забележката. По принцип първо сумирах числата и накрая закръглях само резултата, като според мен това е правилния начин. Единствено така не се губи нищо.  Но тогава се получаваше резултат различен от примера.

А относно двете функции според мен няма никакво значение дали е стринг или число, защото и при двете ти остават само цифрите до вторият знак след запетаята.

1
Stoyan.Stoyanov avatar Stoyan.Stoyanov 96 Точки

Да, объркването идва от това, че примера в условието на задачата също е грешен - т.е. закръгля грешно. При вярно математическо смятане и закръгляне, накрая трябва да се получи 338.05

0
externo avatar externo 119 Точки

Кратко и просто решение на 7.Student Sorting

Не съм оправял стилове и цветове :(

1
aslv1 avatar aslv1 304 Точки

Здравейте! laughing

На задача 2 Rich People's Problems (Car Randomizer) използвах този ресурс, за да си генерирам цветовете.

Надявам се да ви помогне wink

Успех!

1
mrslvts avatar mrslvts 7 Точки

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

Не се справям с прихващането на данните от формите. Ще е удобно ли някой да погледне този ми опит и да сподели мнението си по проблема?

Благодаря предварително!

0
shorti avatar shorti 47 Точки

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

0
24/08/2014 23:29:59
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.