所以我在这里有这个协议
def __init__(self, master = None): #initialising the frame setup for windows
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
global lb,a,n
self.master.title("Alarm")
self.pack(fill=BOTH, expand =1)
newButton = Button(self, text="New Alarm", command=self.new_window) #create buttons and link to commands
newButton.place(x=50, y=50)
deleteButton = Button(self, text="Delete Alarm", command = self.alarmDelete)
deleteButton.place(x=250, y=50)
n=0 #loop through to find out how many rows are in the database
for row in c.execute('SELECT Start Destination FROM stocks '):
n = n + 1
i=0
remove=")"
removed="("
removing=","
remover="'"
a = [[0] * 14 for i in range(n)] #load database into multidimensional array
for row in c.execute('SELECT Start Destination FROM stocks '):
a[i][0]= row
temp=""
for j in str(a[i][0]): #remove unwanted characters from vars
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][0]=temp
i = i + 1
i=0
for row in c.execute('SELECT End Destination FROM stocks '):
a[i][1]= row
temp=""
for j in str(a[i][1]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][1]=temp
i = i + 1
i=0
for row in c.execute('SELECT hArrival FROM stocks '):
a[i][2]= row
temp=""
for j in str(a[i][2]):
if j==remove or j == removed or j == removing or j==remover :
null=""
else:
temp=temp + str(j)
a[i][2]=temp
i = i + 1
i=0
for row in c.execute('SELECT mArrival FROM stocks '):
a[i][3]= row
temp=""
for j in str(a[i][3]):
if j==remove or j == removed or j == removing or j == remover:
null=""
else:
temp=temp + str(j)
a[i][3]=temp
i = i + 1
i=0
for row in c.execute('SELECT Preperation Time FROM stocks '):
a[i][4]= row
temp=""
for j in str(a[i][4]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][4]=temp
i = i + 1
i=0
for row in c.execute('SELECT Day Date FROM stocks '):
a[i][5]= row
temp=""
for j in str(a[i][5]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][5]=temp
i = i + 1
i=0
for row in c.execute('SELECT Month Date FROM stocks '):
a[i][6]= row
temp=""
for j in str(a[i][6]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][6]=temp
i = i + 1
i=0
for row in c.execute('SELECT Year Date FROM stocks '):
a[i][7]= row
temp=""
for j in str(a[i][7]):
if j==remove or j == removed or j == removing :
null=""
else:
temp=temp + str(j)
a[i][7]=temp
i = i + 1
i=0
for row in c.execute('SELECT AlarmName FROM stocks '):
a[i][10]= row
temp=""
for j in str(a[i][10]):
if j==remove or j == removed or j == removing or j ==remover :
null=""
else:
temp=temp + str(j)
a[i][10]=temp
i = i + 1
i=0
for i in range(n):#convert times and dates to timestamp and datestamps
a[i][8] = int(a[i][2])*3600 + int(a[i][3])*60
a[i][9] = str(a[i][6]) + "/" + str(a[i][5]) + "/" + str(a[i][7])
i=i+1
i=0
for i in range(n): #set all boolean value to true for later validation in calc
a[i][12] = "00:00"
a[i][12] = datetime.strptime(a[i][12], '%H:%M').time()
i=i+1
for i in range(n): #set all boolean value to true for later validation in calc
a[i][13] = 0
i=i+1
i=0
lb=Listbox(root) #create listbox and insert values
lb.pack()
for i in range(n):
for item in [str(a[i][10])]:
lb.insert(END, item)
i=i+1
lb.bind('<Double-Button-1>', Window.alarmInfo) #if list item is double clicked call alarmInfo
Window.alarmCalc(self) #call calculations
def alarmInfo(self): #finds out which listbox item was selcted and prints info about it
global lb,a,n
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
window = Toplevel(root)
window.geometry("200x150")
Label(window, text="Start Destination:").grid(row=0, sticky=W)
Label(window, text=a[i][0]).grid(row=0,column=1, sticky=W)
Label(window, text="End Destination:").grid(row=1, sticky=W)
Label(window, text=a[i][1]).grid(row=1,column=1, sticky=W)
Label(window, text="Arrival Time:").grid(row=2, sticky=W)
Label(window, text=a[i][2] + ":" + a[i][3]).grid(row=2,column=1, sticky=W)
Label(window, text="Preperation Time:").grid(row=3, sticky=W)
Label(window, text=a[i][5]).grid(row=3,column=1, sticky=W)
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
Label(window, text=a[i][9]).grid(row=4,column=1, sticky=W)
Label(window, text="Alarm Name:").grid(row=5, sticky=W)#
Label(window, text=a[i][10]).grid(row=5,column=1, sticky=W)
def alarmDelete(self):
global a,n,lb
listName = lb.get(ACTIVE)
i=-1
for i in range(n):
if listName == a[i][10]:
break
else:
i=i+1
for row in c.execute('SELECT AlarmName FROM stocks '): #deletes selected item from database
temp = row
if listName in temp:
c.execute('DELETE FROM stocks WHERE AlarmName=?', (listName,))
conn.commit()
break
def new_window(self): #create new window, and initialise layout
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
window = Toplevel(root)
window.geometry("550x300")
Label(window, text="Start Destination").grid(row=0, sticky=W)
Label(window, text="End Destination").grid(row=1, sticky=W)
Label(window, text="Arrival Time").grid(row=2, sticky=W)
Label(window, text=":").grid(row=2, column=2, sticky=W)
Label(window, text="Preperation Time").grid(row=3, sticky=W)
Label(window, text="Alarm Name").grid(row=5, sticky=W)#
eSd = Entry(window, width=5)
eEd = Entry(window,width=5)
eAth = Spinbox(window, from_=0, to=23)
eAtm = Spinbox (window, from_=0, to=59)
eDd = Spinbox (window, from_=1, to=31)
eDm = Spinbox (window, from_=1, to=12)
eDy = Spinbox (window, from_=2017, to=2019)
ePt = Entry(window,width=5)
eAn = Entry(window, width=20)
eSd.grid(row=0, column=1, sticky=W)
eEd.grid(row=1, column=1, sticky=W)
eAth.grid(row=2, column=1, sticky=W)
eAtm.grid(row=2,column=3, sticky=W)
ePt.grid(row=3, column=1, sticky=W)
eAn.grid(row=5, column=1, sticky=W)#
Label(window, text="Date").grid(row = 4,column=0, sticky=W)
eDd.grid(row = 4,column=3, sticky=W)
Label(window, text="/").grid(row = 4,column=2, sticky=W)
eDm.grid(row = 4,column=1, sticky=W)
Label(window, text="/").grid(row = 4,column=4, sticky=W)
eDy.grid(row = 4,column=5, sticky=W)#
createButton = Button(window, text ="Create", command = self.create) #link to def create()
createButton.place(x =50,y=150)
def create(self):
global eSd,eEd,eAth,eAtm,ePt,eDd,eDm,eDy,eAn
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an
val1 = False
val2 = False
val3 = True
error=""
sd = eSd.get()
ed = eEd.get()
ath = eAth.get()
atm = eAtm.get()
pt = ePt.get()
Dd = eDd.get()
Dm = eDm.get()
Dy = eDy.get()
an = eAn.get()#
with open('zipcode.csv') as csvfile: #check through csv file to validate zipfiles
reader = csv.reader(csvfile)
for row in reader:
for col in row:
if col == sd:
val1= True
if col ==ed:
val2 = True
if len(pt) < 5: #validate pt
try:
val3 = int(pt)
except ValueError:
val3 = False
else:
val3 = False
if val1 == False and val2 == False and val3 == False: #Compare boolean values to generate correct error message
error = "Invalid Prep Time and Zipcodes"
elif val1 == False and val3 == False :
error = "Invalid Prep Time and Start Zipcode"
elif val1 == False and val2 == False :
error = "Invalid Zipcodes"
elif val2==False and val3==False:
error= "Invalid Prep Time and End Zipcode"
elif val1 == False:
error="Invalid Start Zipcode"
elif val2==False:
error="Invalid End Zipcode"
elif val3==False:
error = "Invalid Prep Time"
if val1 == False or val2 == False or val3 == False: #call different function depending on errors
Window.valEr(self,error)
else:
Window.addList(self)
def valEr(self, error): #displays error message
window = Toplevel(root)
window.geometry("100x100")
Label(window, text=error).place(x=40, y=40)
def addList(self):
global sd,ed,ath,atm,pt,Dd,Dm,Dy,an#
if len(ath)< 2: #add preceeding 0's to single values to make calculations easier
ath = "0" + ath
if len(atm) < 2:
atm = "0" + atm
if len(Dm) < 2:
Dm = "0" + Dm
if len(Dd) <2:
Dd = "0" + Dd
pt = int(pt) * 60
writeTo = (sd,ed,ath,atm,pt,Dd,Dm,Dy,an) #create tuple to make writing to database easier
c.execute("INSERT INTO stocks VALUES(?,?,?,?,?,?,?,?,?)", writeTo) #insert data into database
conn.commit()
#################################################################################
def alarmCalc(self):
global a,n
x=1000000000000000000000000
i=0
nowDate = date.today()
temp =""
temp2 = ""
nowDate = str(nowDate.month) + "/" + str(nowDate.day) + "/" + str(nowDate.year) #get todays date
for i in range(n):
if nowDate == a[i][9]:
Link= 'https://www.mapquestapi.com/directions/v2/route?key=YCGaovp1Y6fRO5f1RVWv2c1Qs9F4qF1N&from='+str(a[i][0])+'%2C+NY&to='+str(a[i][1])+'%2C+NY&outFormat=json&routeType=fastest&avoidTimedConditions=true&narrativeType=none'
response = requests.get(Link)
data = json.loads(response.text)
rawtravelTime =int( data["route"]["time"]) #request and retrieve correct time
#print(rawtravelTime)
a[i][11]= int(a[i][8]) - int(a[i][4]) - rawtravelTime #calculate time in seconds
#print(a[i][11])
m, s = divmod(a[i][11], 60) # convert seconds to time using quotients
h, m = divmod(m, 60)
a[i][11]= str("%d:%02d:%02d" % (h, m, s))
a[i][11] = a[i][11][:-3] #validation of time string
if len(a[i][11]) < 5:
a[i][11] = "0" + a[i][11]
a[i][11] = datetime.strptime(a[i][11], '%H:%M').time() #turn into datetime object
#print(a[i][11])
nowTime = datetime.now().strftime('%H:%M') #get current time
nowTime = datetime.strptime(nowTime, '%H:%M').time()
#print(nowTime)
if a[i][11] < nowTime or a[i][11] == nowTime or x < (10*3600) : #if alarm time = or exceeds current time call alarmTrig
Window.alarmTrig(self)
else:
#print("NO")
a[i][12] = datetime.combine(date.min, a[i][11]) - datetime.combine(date.min, nowTime)
temp = str(a[i][12])
print(temp)
if len(temp) > 7: # gets time left in seconds
temp2 = temp[4:6]
temp = temp[:2]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
else:
temp2 = temp[2:4]
temp = temp[:1]
a[i][13] = (int(temp) *3600) + (int(temp2) *60)
print(a[i][13])
# i=i+1
else:
# i=i+1
print("not date")
for i in range(n): #finds smallest time
if int(a[i][13]) < int(x):
x=int(a[i][13])
print(x)
time.sleep(x/2) #make it wait half the time before recalc
Window.alarmCalc
def alarmTrig(self):
print("TRIG")
winsound.PlaySound("*", winsound.SND_ALIAS)
#Delete alarm
我有一个像这样实现public protocol UseCase {
associatedtype ResponseType
associatedtype Parameters
func build(params: Parameters) -> Single<ResponseType>
}
public extension UseCase {
func execute(params: Parameters) -> Single<ResponseType> {
return build(params: params)
.subscribeOn(ConcurrentDispatchQueueScheduler(qos: DispatchQoS.background))
.observeOn(MainScheduler.instance)
}
}
协议的结构
UseCase
我希望在另一个课程中使用此public struct CreateNewAccount: UseCase {
private let repository: AuthRepository
public init(repository: AuthRepository) {
self.repository = repository
}
public func build(params: Params) -> Single<User> {
return repository.register(params: params)
}
public struct Params: RequestParams {
...
}
}
,但我不想直接使用CreateNewAccount
而我希望将其作为CreateNewAccount
传递,因为因为它是一个协议它可以很容易地模拟测试。
但是当我做这样的事情时
UseCase
这给了我一个像这样的错误
class RegisterViewModel: ViewModel {
private let createNewAccount: UseCase // Error on this line
init(createNewAccount: UseCase) { // Error on this line
self.createNewAccount = createNewAccount
}
}
那么,是否有一些我可以从我的代码中更改以使这种情况有效的东西?提前谢谢。
答案 0 :(得分:1)
您不能将具有关联类型的协议用作字段。
您必须仅将它们用作类的实现。在大多数情况下,这些类应该是通用的。
例如,允许使用此代码:
require'
/Users/xxx/xxx/Rakefile:4:in
等等,
<top (required)>'
/Users/xxx/.rbenv/versions/2.3.1/bin/bundle:23:in
或用其他协议以某种方式包装它。