Conversation
JekaMas
left a comment
There was a problem hiding this comment.
Код, насколько я вижу, должен работать, но есть несколько замечаний. Большей частью они связаны с нейдачным выбором структур данных.
countshopprice/countshopprice.go
Outdated
| ) | ||
|
|
||
| /* Добавление нового товра в справочник - если есть измениться цена */ | ||
| func addItemsPrice(itemsPrice map[int]*mu.ItemPrice, item *mu.ItemPrice) string { |
There was a problem hiding this comment.
Проясни, зачем item *mu.ItemPrice по указателю нужно тут.
countshopprice/countshopprice.go
Outdated
| func addItemsPrice(itemsPrice map[int]*mu.ItemPrice, item *mu.ItemPrice) string { | ||
| /* проверим наличие в каталоге */ | ||
| fnd := false | ||
| vIdx := 0 |
There was a problem hiding this comment.
Не понял идею itemsPrice map[int]*mu.ItemPrice. Зачем map[int]*mu.ItemPrice, ключами у тебя int, которые порядковые индексы. Но это усложняет поиск по map и сводит ее к slice []int. Почему бы не сделать map[string]*mu.ItemPrice, где string - это название товара? Тогда циклы с поиском исчезнут полностью.
countshopprice/countshopprice.go
Outdated
| if fnd { | ||
| msg += "--обновиление--цены--старая:" + fmt.Sprintf("%.2f", oldPrice) + | ||
| " новая:" + fmt.Sprintf("%.2f", item.ItemPrice) | ||
| itemsPrice[vIdx] = item |
There was a problem hiding this comment.
Несколько неудачное название itemsPrice - оно говорит о том, что это цены товаров, а там товары целиком. Может попробовать items?
mutils/structsdef/structsdef.go
Outdated
| @@ -0,0 +1,19 @@ | |||
| package structsdef | |||
|
|
|||
| // ItemPrice - описание товара | |||
There was a problem hiding this comment.
type Item struct {
Name string
Price float32
}
Может так? Выразительность даже лучше.
mutils/structsdef/structsdef.go
Outdated
| } | ||
|
|
||
| // User - описание пользователя | ||
| type User struct { |
There was a problem hiding this comment.
ype User struct {
Name string // Имя пользователя
Account float32 // остаток на счету
}
countshopprice/countshopprice.go
Outdated
| */ | ||
| func getOrderCost(itemsList map[int]*mu.ItemPrice, shopList mu.Order) float32 { | ||
| var ordrCost float32 = 0 | ||
| for _, shopName := range shopList.Items { // бегу по списку товаров в заказе |
There was a problem hiding this comment.
Этот вложенный цикл тоже упрастится, если поменять тип itemsList, как описал выше.
countshopprice/countshopprice.go
Outdated
| сохраним список товаров с ценой во время запроса от пользователя | ||
| */ | ||
|
|
||
| func compStrArr(in1, in2 []string) bool { |
There was a problem hiding this comment.
Неясно, зачем эта функция. Комментарий, как мне кажется, не от неё.
countshopprice/countshopprice.go
Outdated
| func orderRegister(acountList map[int]*mu.User, // список пользователей | ||
| ordersPrice *[]mu.Order, // списки товаров с ценами | ||
| itemsPrice map[int]*mu.ItemPrice, // справочник товаров | ||
| billList map[int]map[int]float32, // список счетов |
There was a problem hiding this comment.
по описанию неясно, что это за map и что у неё за ключи
countshopprice/countshopprice.go
Outdated
| return | ||
| } | ||
| // проверим кредитоспособность | ||
| if ostatok <= 0 { |
There was a problem hiding this comment.
float32 точно всегда будет проходить это сравнение корректно?
countshopprice/countshopprice.go
Outdated
| // добавить ветку просмотра | ||
|
|
||
| tmp := seveListwithCost(ordersPrice, itemsPrice, itemsList) | ||
| var saldo float32 = ostatok - tmp.TotalSum |
countshopprice/countshopprice.go
Outdated
| fnd := false | ||
| vIdx := 0 | ||
| msg := item.ItemName | ||
| var oldPrice float32 = 0 |
There was a problem hiding this comment.
В golang это var oldPrice float32
А скорее var oldPrice float
countshopprice/countshopprice.go
Outdated
| vIdx := 0 | ||
| msg := item.ItemName | ||
| var oldPrice float32 = 0 | ||
| for cidx, citem := range itemsPrice { |
There was a problem hiding this comment.
По прежнему не хватает items map[string]Item, если принимать такой и подобные параметры, то уйдут всй эти куски кода с поиском item, user
countshopprice/countshopprice.go
Outdated
| break | ||
| } | ||
| } | ||
| if fnd { |
There was a problem hiding this comment.
found немного лучше - более полные имена предпочтительнее.
Общее правило таково: чем больше время жизни переменной и шире ее контекст, тем более распространенное имя стоит сделать. Короткоживущая переменная одного цикла - подойдёт i, idx, k, v; переменная для использования в нескольких проверках, в среднем куске кода на десяток и более строк кода - лучше чтобы это было полное слово index, validator, config, item, price; сложное понятие или переменная в большом методе или тем более уровня пакета - несколько слов: lowestPrice, areItemsSorted, SortByItemName.
countshopprice/countshopprice.go
Outdated
| for _, shopName := range shopList.Items { // бегу по списку товаров в заказе | ||
| fond := false | ||
| for _, item := range itemsList { // бегу по списку товаров в каталоге | ||
| if shopName == item.ItemName { |
There was a problem hiding this comment.
От этого стоит избавиться полностью - от цикла с поиском.
There was a problem hiding this comment.
Может стоит сделать новые методы у shop - getUser, getItem, которые возвращают пользователя и товар по соответствующим именам.
countshopprice/countshopprice.go
Outdated
| } | ||
|
|
||
| func seveListwithCost( | ||
| ordersPrice *[]mu.Order, // списки товаров с ценами |
There was a problem hiding this comment.
зачем тут слайсы по указателю? по названию фукнции не очень понятно, что она должна делать
countshopprice/countshopprice.go
Outdated
| var ostatok float32 = 0 | ||
| //var totalCost float32 = 0 | ||
| var vIxd int = -1 | ||
| for idx, iUser := range acountList { |
There was a problem hiding this comment.
Этот цикл надо убрать, как и вспомогательные к нему переменные.
countshopprice/countshopprice.go
Outdated
| func showAccount(acountList map[int]*mu.User, p int) { | ||
| switch p { | ||
| case 0: | ||
| { |
There was a problem hiding this comment.
Этим константам стоит дать имена и тип, чтобы было очевидно при использовании
type sortDirection uint8
const (
ByNameAsc sortDirection = iota
ByNameDesc
// и так далее
)
countshopprice/countshopprice.go
Outdated
| func (a ByAcc) Less(i, j int) bool { return a[i].Account < a[j].Account } | ||
| func (a ByAcc) Swap(i, j int) { a[i].Account, a[j].Account = a[j].Account, a[i].Account } | ||
|
|
||
| func showAccount(acountList map[int]*mu.User, p int) { |
There was a problem hiding this comment.
Посмотри, какое более очевидное имя можно дать для p
countshopprice/countshopprice.go
Outdated
|
|
||
| ordersPrice := []mu.Order{} // список заказов с посчитанной общей ценой | ||
|
|
||
| fmt.Println(seveListwithCost(&ordersPrice, itemsPrice, mu.Order{[]string{"Хлеб", "Сосиски"}, 0})) |
There was a problem hiding this comment.
Посмотри, как происходит заказ и все операции с магазином. Они очень много заставляют пользователя делать, создавать корректные данные, передавать их куда надо. Лучше было бы, чтобы это было скрыто от пользователя кодом Shop. Посмотри на предложенный интерфейс магазина, возможно это подскажет направление.
mutils/structsdef/structsdef.go
Outdated
| } | ||
|
|
||
| // Order - описание заказа | ||
| type Order struct { |
mutils/structsdef/structsdef.go
Outdated
| @@ -0,0 +1,19 @@ | |||
| package structsdef | |||
There was a problem hiding this comment.
названия пакетов лучше делать по задачам или типам, которые определены в пакете. то же и про файлы.
item.go shop.go в пакете shop будут более понятны (это просто пример, возможно ты найдешь лучшее устройство кода).
| //SaveAcountList - схраним пользователей | ||
| func SaveAcountList(vacountList map[string]*User) { | ||
| if len(vacountList) == 0 { | ||
| panic(collectionEmpty) |
|
|
||
| // SetDiscount - устанавливаем скидку на заказ в зависимости от пользователя | ||
| // типов товаров и заказов | ||
| func (order *Order) SetDiscount(userName string, |
There was a problem hiding this comment.
Возможно я неверно понял, но это больше похоже на подсчёт скидки, чем на ее установку в order данных.
There was a problem hiding this comment.
получилось путано - там есть комментарий
244 Воспользуемся SetDiscount - сделаем скидку
тут собственно скидка устанавливается
| itemsPrice[itemName] = item | ||
| msg += "--новый--товар--по цене--:" + fmt.Sprintf("%.2f", item.ItemPrice) | ||
| } else { // нашли - обноавляем цену и тип | ||
| msg += "--обновиление--цены--старая:" + fmt.Sprintf("%.2f", vItemPrice.ItemPrice) + |
There was a problem hiding this comment.
Очень много кода в разных методах, которые нужны только для вывода сообщений. Их стоит полностью убрать и заменить на тесты функций и методов.
| vitemsList, ok := itemsList[name] | ||
| if ok { | ||
| switch vitemsList.ItemType { | ||
| case 2: |
There was a problem hiding this comment.
Трудно понять, что тут происходит. попробуй добавить имена константам, выделить подобные куски кода в отдельные функции.
| если больше 1,2,...,4....> товаров - то вернуть список без пробника | ||
| */ | ||
| switch { | ||
| case (len(probnik) == 1 && len(tovar) == 2): |
| if r := recover(); r != nil { | ||
| switch r { | ||
| case openFileError: | ||
| { |
There was a problem hiding this comment.
если оператор один , то {} - можно опускать ?
There was a problem hiding this comment.
Даже если их много в конструкции switch внутри каждого case фигурные скобки не нужны
| } | ||
| } | ||
| } else { | ||
| f.Close() |
There was a problem hiding this comment.
может в начале функции сделать
defer func() {
if f != nil {
f.close()
}
}()
There was a problem hiding this comment.
не знаю почему , но go ругалась - дескать не вижу f !
| import "fmt" | ||
|
|
||
| // ItemPrice - описание товара в дальнейшем map[ItemName] *ItemPrice | ||
| type ItemPrice struct { |
There was a problem hiding this comment.
По сути, это не ItemPrice, а Item, который включает в себя не только цену.
Префикс Item- для полей структуры лишний, он не добавляет смысла.
// 0 - обычный товар 1 - премиум товар 2 - пробник с нулевой ценой
лучше сделать новый тип и для него определить эти три константы и дать им имена.
There was a problem hiding this comment.
полагаю это надо было сделать через iota
|
|
||
| func addItemsPrice(itemsPrice map[string]*mu.ItemPrice, | ||
| itemName string, | ||
| item *mu.ItemPrice) string { |
There was a problem hiding this comment.
зачем item *mu.ItemPrice, равно как и itemsPrice - по указателю?
There was a problem hiding this comment.
ну я раньше задавал вопрос - у меня не получалось обновить значение в структуре
было так acountList *map[int]mu.User , и я не мог выполнить (*acountList)[vIxd].Account = 10.
Ты рекомендовал acountList map[int]*mu.User - чтоб можно было это сделать , и я ещё
попробовал и спросил https://play.golang.org/p/YhSH0hAHHiX - верно или нет.
Получив утвердительный ответ, я рассудил , что если в структуре надо что-то менять, то нужно ставить * - по этому map[string]*mu.ItemPrice - а там я как раз меняю цену.
| вернуть заказ с посчитанной ценой | ||
| */ | ||
| func getOrderCost(itemsList map[string]*mu.ItemPrice, shopList mu.Order) float32 { | ||
| var ordrCost float32 = 0 |
There was a problem hiding this comment.
инициализация нулевым значением не нужна
There was a problem hiding this comment.
это остаточное - со временем буду опускать, просто до автоматизма отработано - если завел переменную - присвой значение.
No description provided.