Home > Blockchain >  How to get number from array with range?
How to get number from array with range?

Time:11-25

It is necessary to realize the volume of the TV. struct Setting var volume range 0...100. How to write to print the volume level?

Another question: Is it possible to better make the brand and model of the TV in the same field? var tvName

struct Setting {
    var volume = (0...100)
    enum Display: String {
         case colorful = "Color"
         case blackwhite = "Black&White"
    }
}
class Tv {
    var tvName = (firm: "", model: 0)
    var isActive = Bool()
    enum Channels: String {
        case news = "News"
        case serials = "Serials"
        case horror = "Horror"
        case comedy = "Comedy"
        case history = "History"
        case cartoons = "Cartoons"
    }
    func tvStatus() {
        if isActive == true {
            print("The TV \(tvName.0) \(tvName.1) is on and shows the channel \(channelOldTv), display: \(display), volume: ")
        } else {
            print("TV is off")
        }
    }
}
let oldTv = Tv()
let channelOldTv = Tv.Channels.serials.rawValue
let display = Setting.Display.colorful.rawValue
oldTv.tvName.firm = "LG"
oldTv.tvName.model = 6643
oldTv.isActive = true
oldTv.tvStatus()

CodePudding user response:

You need another variable in the Setting struct that is going to hold the currently selected value.

For example: var currentVolume = 50

If you'd like to be able to lock the currentVolume variable so that it can only be set between your range of 0 to 100, one possible implementation would be to make the currentVolume variable private to the Setting struct and create a function that sets the volume based on a given input, or functions that increment/decrement the volume based on some step, like this:

struct Setting {
    private var volumeRange = (0...100)
    // We've made it private(set) so that we can read and print it, but not change it,
    // because we want it to only be changed by the functions we created,
    // which functions will make sure it stays within range.
    private(set) var currentVolume = 10
    private var step = 5

    enum Display: String {
        case colorful = "Color"
        case blackwhite = "Black&White"
    }

    mutating func setVolume(to newVolume: Int) {
        // Here we are checking if newVolume is within the range of 0 to 100
        if volumeRange.contains(newVolume) {
            currentVolume = newVolume

        // If it is not, here we are checking if newVolume is above 100,
        // and if so, we set it to our upper range, which is 100
        } else if volumeRange.upperBound < newVolume {
            currentVolume = volumeRange.upperBound

        // And finally we are checking if newVolume is below 0,
        // and if so, we set it to our lower range, which is 0
        } else {
            currentVolume = volumeRange.lowerBound
        }
    }

    mutating func incrementVolume() {
        // Here we are creating a newVolume variable that will have
        // our currentVolume incremented by the step variable (which in this case is 5)
        let newVolume = currentVolume   step

        // Here we are checking if the new volume is within our specifed range
        // For example, if currentVolume was 100, the newVolume would now be 105,
        // which is not the in range, so we would not want to change currentVolume
        if newVolume <= volumeRange.upperBound {
            currentVolume = newVolume
        }
    }

    mutating func decrementVolume() {
        // Here we are creating a newVolume variable that will have
        // our currentVolume decremented by the step variable (which in this case is 5)
        let newVolume = currentVolume - step

        // Here we are checking if the new volume is within our specifed range
        // For example, if currentVolume was 0, the newVolume would now be -5,
        // which is not the in range, so we would not want to change currentVolume
        if newVolume >= volumeRange.lowerBound {
            currentVolume = newVolume
        }
    }
}

var setting = Setting()
print(setting.currentVolume) // 10

setting.incrementVolume()
print(setting.currentVolume) // 15

setting.setVolume(to: 105)
print(setting.currentVolume) // 100

setting.incrementVolume()
print(setting.currentVolume) // 100

setting.decrementVolume()
print(setting.currentVolume) // 95

setting.setVolume(to: -5)
print(setting.currentVolume) // 0

setting.decrementVolume()
print(setting.currentVolume) // 0

Your volume variable var volume = (0...100) is of type ClosedRange<Int>. It cannot hold a specific value, what it holds is a range with a lower and an upper bound. You can double-check this on any variable by holding down the option key and then clicking on the variable name (in this case clicking on 'volume'). You can find information on the ClosedRange type and others in Apple's documentation here: https://developer.apple.com/documentation/swift/closedrange

CodePudding user response:

From my point of view, you'll need to tweak a little your code, since the data types are not well implemented. This is how I'd write it:

class TV {
    let type: TVType
    let isActive: Bool
    let setting: TVSetting
    let channel: TVChannel
    
    
    init(type: TVType, isActive: Bool, setting: TVSetting, channel: TVChannel) {
        self.type = type
        self.isActive = isActive
        self.setting = setting
        self.channel = channel
    }
    
    func printTVStatus() {
        if self.isActive {
            print("The TV \(self.type.brand) \(self.type.model) is on and shows the channel \(self.channel.rawValue), display: \(self.setting.display.rawValue), volume: \(self.setting.volume)")
        } else {
            print("TV is off")
        }
    }
}

struct TVSetting {
    let volumeRange: (ClosedRange<Int>) = (0...100)
    let volume: Int
    let display: Display
    
    enum Display: String {
         case colorful = "Color"
         case blackwhite = "Black&White"
    }
    
    
    init(volume: Int, display: Display) {
        self.volume = self.setVolumeValue(volume)
        self.display = display
    }
    
    private func isVolumeValueValid(_ value: Int) -> Bool {
        return self.volumeRange.contains(value)
    }
    
    private func setVolumeValue(_ value: Int) -> Int {
        if self.isVolumeValueValid(value) {
            return value
        } else {
            // handle the caae when the value is not a valid one, maybe set a default one and throw an error, or print a message
            return 0
        }
    }
}


enum TVChannel: String {
    case news = "News"
    case serials = "Serials"
    case horror = "Horror"
    case comedy = "Comedy"
    case history = "History"
    case cartoons = "Cartoons"
}

struct TVType {
    let brand: String
    let model: Int // Maybe it would be better to change it to String, because you might have models which start with 034 etc
}



class MyClass {
    
    let oldTv = TV(type: TVType(brand: "BrandName", model: 233), isActive: true, setting: TVSetting(volume: 20, display: .blackwhite), channel: .cartoons)
    
    func doSomething() {
        self.oldTv.printTVStatus()
    }
    
 
}

As someone stated above, the variable volume has to hold the value. The volumeRange represents the range which volume has to be included in. For that, you'll have to put some validation on volume field when the setting is initialized.

  • Related