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.