linux 正則查找email_Hello Iris簡易微博類App開發教程3-查找用戶和用戶登錄

0afed76f8514e7a4c020408c0f9dba59.png

用戶郵箱地址有效性驗證

在上一節中,我們編寫了用于用戶注冊的代碼。但是當時并沒有為用戶的Email添加有效性驗證,導致Email被設置為任何字符串都能注冊成功。所以在本節初,我們首先來為Email添加一個有效性驗證。

首先還是來編寫測試數據,打開我們上一節創建的test_user_data.json,向其中添加一個測試用的用戶信息。

代碼清單3-1

models/test_user_data.json

[
.
.
. {"email":"email8@exam_ple.com","password": "password8","username": "username8"}
]

我們添加的這個新的用戶信息的Email是一個無效的郵箱地址。接著我們打開user_test.go,也向其中增加一個測試case。

代碼清單3-2

models/user_test.go

func TestUserCreate(t *testing.T) {
.
.
.err = users[7].Create() // 測試Email為無效的郵箱地址的情況if err == nil {t.Error("expected get an error but no error occured.")} else if err.Error() != "Invalid email address" {t.Errorf("expected get "Invalid email address" but got "%s"n", err.Error())}
}

然后打開user.go,我們向其中增加一個isValidEmail()方法用來檢測設置的用戶Email是否有效,然后再在向數據庫插入數據之前,檢查郵箱地址是否有效。如果無效的話,我們返回一個“Invalid email address”的錯誤。

代碼清單3-3

models/user.go

package modelsimport ("errors""regexp""time"
)type User struct {ID intEmail *string `gorm:"not null;unique_index"`Password *string `gorm:"not null"`Username *string `gorm:"not null;unique_index"`Message stringCreatedAt time.TimeUpdatedAt time.Time
}func (u *User) Create() (err error) {if u.Email != nil && !u.isValidEmail() {err = errors.New("Invalid email address")return err}if u.Password == nil {err = errors.New("Error occured when creating user")return err}plain := *u.Passwordencrypt := Encrypt(plain)u.Password = &encrypterr = DB.Create(&u).Errorif err != nil {err = errors.New("Error occured when creating user")}return
}func (u *User) isValidEmail() bool {pat := `(?i)A[w+-.]+@[a-zd-.]+.[a-z]+z`email := u.Emailok, _ := regexp.MatchString(pat, *email)return ok
}

在isValidEmail()方法里,我們使用了正則表達式去匹配Email屬性。如果能匹配上,則返回true,否則就會返回false。所使用的正則表達式的含義如下:

fadb739c6ed09dcf3274fd737362868b.png

完成后我們新打開一個命令行工具,cd到models文件夾下,運行go test

C:Userssxu37GosrcGoWeb>cd models
C:Userssxu37GosrcGoWebmodels>go test

結果如下:

PASS
ok GoWeb/models 4.101s

測試Pass,說明我們添加的用于測試郵箱地址是否有效的代碼是正確的。

查找用戶

既然我們已經有了創建用戶的功能,接下來,我們就來實現簡單的用戶查找的功能。在創建用戶模型的時候,我們在數據庫中,將用戶的id列設置為了primary key,并且在email和username都創建了index,這就意味著,通過ID、Email和Username這三者我們都可以快速檢索到一個用戶的信息。

首先我們還是來編寫查找用戶的測試代碼。打開user_test.go,向其中增加下面三個函數。

代碼清單3-4

models/user_test

.
.
.
func TestFindUserByID(t *testing.T) {id1, id2 := 5, 4user1, err := FindUserByID(id1)if err == nil {t.Error("expected find no user but got:", user1)}user2, err := FindUserByID(id2)if err != nil {t.Error("got an unexpected error:", err)} else if user2.ID != id2 {t.Errorf("expected find user which id is %d but got user which id is: %dn", id2, user2.ID)} else if user2.Email != nil || user2.Password != nil {t.Error("expected do not get user email and password but got them now")}
}func TestFindUserByEmail(t *testing.T) {email1, email2 := "email6@exam.com", "email5@exam.com"user1, err := FindUserByEmail(email1)if err == nil {t.Error("expected find no user but got:", user1)}user2, err := FindUserByEmail(email2)if err != nil {t.Error("got an unexpected error:", err)} else if *user2.Email != email2 {t.Errorf("expected find user which email is "%s" but got user which email is: "%s"", email2, *user2.Email)}
}func TestFindUserByUsername(t *testing.T) {username1, username2 := "username6", "username5"user1, err := FindUserByUsername(username1)if err == nil {t.Error("expected find no user but got:", user1)}user2, err := FindUserByUsername(username2)if err != nil {t.Error("got an unexpected error:", err)} else if *user2.Username != username2 {t.Errorf("expected find user which username is "%s" but got user which username is: "%s"", username2, *user2.Username)} else if user2.Email != nil || user2.Password != nil {t.Error("expected do not get user email and password but got them now")}
}

在上面的測試代碼中,我們分別測試了通過ID、Email和Username來查找用戶的情況。因為這三個屬性在數據庫中都是唯一的,所以我們每條測試case最多只能找到一條數據。所以我們只測試了找到的這條數據的某一項值是否是我們所期待的值。如果是,就表明這條數據就是我們需要的數據,如果不是,說明我們查找用戶的功能代碼有問題。我們還檢查了查找到的數據中是否包含用戶的Email和Password,如果包含了的話也不能通過測試。

接下來,我們就來編寫查找用戶的代碼。因為在查找用戶之前,我們通常不會事先得到一個用戶的實例,所以我們直接將查找用戶的代碼作為函數來編寫的。另外,我們為FindUserByID()和FindUserByUsername()添加了Select()函數,對查詢到的數據進行篩選,不從數據庫中獲取用戶的email和password信息,以保證用戶賬號的安全。

代碼清單3-5

models/user.go

.
.
.
var QueryKey string = "id, username, message"
func FindUserByID(id int) (user User, err error) {DB.Where("id = ?", id).Select(QueryKey).Find(&user)if user.ID == 0 {err = errors.New("Cannot find such user")}return
}func FindUserByEmail(email string) (user User, err error) {DB.Where("email = ?", email).Find(&user)if user.ID == 0 {err = errors.New("Cannot find such user")}return
}func FindUserByUsername(username string) (user User, err error) {DB.Where("username = ?", username).Select(QueryKey).Find(&user)if user.ID == 0 {err = errors.New("Cannot find such user")}return
}

清空數據庫,然后打開命令行,cd到models目錄下,運行go test。

C:Userssxu37GosrcGoWebmodels>go test
.
.
.
PASS
ok GoWeb/models 3.781s

接下來,我們為查找用戶編寫一個接口。在我們的App中,我們不會將FindUserByEmail()公開。這個函數將只在App內部被使用。FindUserByUsername()可以作為通過用戶名查找用戶的功能被公開,但是我們目前并不打算先實現這個功能。我們首先實現通過ID來查找用戶,然后我們通過訪問類似“users/1”的路徑來獲取某個具體的用戶的信息。我們先編寫測試代碼。向users_controller_test.go中增加如下的測試代碼:

代碼清單3-6

controllers/users_controller_test.go

func TestFindUserByID(t *testing.T) {id := 1controller := UsersController{}user, err := controller.Show(id)if user.ID == 0 || err != nil {t.Error("expected to show user but error occured:", user, err)}
}

這個測試case很簡單,就是指定id為1,看能不能返回id為1的用戶。

接著我們就應用代碼,應用代碼也很簡單。

代碼清單3-7

controllers/users_controller.go

func (c *UsersController) BeforeActivation(b mvc.BeforeActivation) {middleware := func(ctx iris.Context) {ctx.Application().Logger()ctx.Next()}b.Handle("POST", "/users/new", "Create", middleware)b.Handle("GET", "/users/{id:int}", "Show", middleware)
}func (c *UsersController) Create(ctx iris.Context) (user models.User, err error) {...
}func (c *UsersController) Show(id int) (user models.User, err error) {user, err = models.FindUserByID(id)return
}

注意在設置路徑的時候,我們用/users/{id:int}的形式設置了一個動態路徑。int值會通過{id:int}作為id參數傳入到Show()方法中。加入我們訪問/users/1這個路徑,那么訪問就會被轉發到Show()方法并且參數為1,即Show(1)。

清空數據庫,cd到controllers目錄,運行go test

C:Userssxu37GosrcGoWebcontrollers>go test
.
.
.
PASS
ok GoWeb/controllers 3.124s

接著,我們再試一試接口。

代碼清單3-8

main_test.go

.
.
.func TestUsersShowRoute(t *testing.T) {app := weiboApp()e := httptest.New(t, app)request := e.Request("GET", "/users/1")response := request.Expect()response.Status(httptest.StatusOK)
}
C:Userssxu37GosrcGoWeb>go test
.
.
.
PASS
ok GoWeb 2.655s

現在我們不僅能創建用戶,還能根據用戶的ID查詢一個用戶。查詢到用戶之后,我們可以實現對這些用戶的資料進行更新和刪除。

但是僅僅這樣操作就會產生一個問題,任何用戶,只要知道其他用戶的ID,就可以隨意地向服務器發送請求,去更改、刪除其他用戶的信息。這明顯是很不安全的,所以我們需要為更新和刪除操作增加一點安全性。大多數App在進行更新和刪除操作的時候都需要有先進行登錄,有些嚴格的App還需要登錄的用戶擁有這些操作的權限才可以。在這里,我們實現只要用戶登錄就能對自己的賬號進行更新和刪除。

用戶登錄

那么接下來,我們來實現用戶登錄。用戶登錄功能的實現最簡單的方式就是利用session,通過下面幾個步驟來實現:

1. 客戶端通過request將用戶的郵箱和密碼提交到服務器。

2. 服務器取得request的數據后,會首先從數據庫讀取該用戶的信息,并判斷數據庫和request提交上來的信息是否一致。

3. 如果一致的話,服務器將該用戶的信息記錄到session里,并將session的標識返回給客戶端。

4. 客戶端收到session的標識之后將它添加到之后每一次request的header里,服務器通過識別request的header里的session標識,來判斷該客戶端是否已經登錄。

一般還會給服務器的session 設置一個有效期,一旦某個session生成后超過了一個固定期限即視為過期,過期的session也是無效的。

在上面的登錄過程中,我們User模型需要做的就是進行登錄驗證:對客戶端request過來的郵箱和密碼進行驗證,并返回一個布爾值來表示驗證結果是否通過。首先我們來編寫登錄驗證的測試代碼。打開models文件夾,新建一個test_auth_data.json,然后將下列測試數據保存到該文件中。

代碼清單3-9

models/test_auth_data.json

[{"email": "wrongemail4@example.com","password": "password4"},{"email": "email4@exam.com","password": "wrongpassword4"},{"email": "email4@exam.com","password": "password4"}
]

然后打開test_user.go,稍微修改一下setup()函數,然后向其中增加一個TestUserAuthenticate()函數。

代碼清單3-10

models/test_user.go

.
.
.
func setup(filename string) (users []User) {file, _ := os.Open(filename)defer file.Close()data, _ := ioutil.ReadAll(file)json.Unmarshal(data, &users)return users
}func TestUserCreate(t *testing.T) {users := setup("test_user_data.json")  
.
.
.}func TestUserAuthenticate(t *testing.T) {users := setup("test_auth_data.json")if _, err := users[0].Authenticate(); err == nil {if err.Error() != "Invalid email or password" {t.Errorf("expected get "Invalid email or password" but got "%s"n", err.Error())}t.Error("expected authentication fail but it passed")}if _, err := users[1].Authenticate(); err == nil {if err.Error() != "Invalid email or password" {t.Errorf("expected get "Invalid email or password" but got "%s"n", err.Error())}t.Error("expected authentication fail but it passed")}if user, err := users[2].Authenticate(); err != nil {t.Error("expected authentication pass but it failed cause:", err)} else if user.ID != 3 {t.Errorf("expected user id to be 3 but got %dn", user.ID)}}

在這份測試代碼中,我們分別測試了三種情況:email不正確、password不正確和兩者都正確。

前兩種情況,我們除了驗證不通過以外,我們還得到了一個Invalid email or password的錯誤信息。只有email和password都正確的時候,我們確認驗證通過,此時錯誤為空。

接下來,我們就為User模型添加Authenticate()方法。

代碼清單3-11

models/user.go

.
.
.
func (u *User) Authenticate() (user User, err error) {user, err = FindUserByEmail(*u.Email)if err != nil {return}if user.ID == 0 || *user.Password != Encrypt(*u.Password) {user = User{}err = errors.New("Invalid email or password")return}return
}

登錄驗證的代碼中,我們通過FindUserByEmail()函數尋找數據庫中email和待驗證的用戶的Email一致的數據。將找到的數據的password和待驗證的用戶的Password進行比較。如果找不到用戶,或者找到的記錄和待驗證的用戶兩者的password不一致,那么我們就判定為驗證失敗,并返回一個Invalid email or password錯誤。如果既能找到記錄,而且password也一致,我們就判定為驗證通過。

登錄驗證的代碼就編寫完成,就可以進行測試了。我們首先還是清空數據庫:

DROP TABLE users;

然后打開命令行工具,cd到models目錄下,運行go test。

C:Userssxu37GosrcGoWebmodels>go test
.
.
.
PASS
ok GoWeb/models 4.417s

說明我們登錄驗證的代碼的行為符合預期。

接下來,我們還需要在控制器里面添加一個Login()方法,我們希望用這個Login()方法來處理用戶登錄。如果用戶登錄驗證成功,Login()方法會返回登錄成功的用戶信息。如果登錄驗證失敗,我們就返回從User#Authenticate()得到的錯誤。

首先我們還是來編寫測試代碼。打開users_controller_test.go,向里面添加下面的函數。

代碼清單3-12

controllers/users_controller_test.go

.
.
.
func TestUserLogin(t *testing.T) {app := iris.New()ctx := context.NewContext(app)// 向新創建的ctx中添加一個ResponseWriter用來寫入session的信息w := context.AcquireResponseWriter()hw := httptest.NewRecorder()w.BeginResponse(hw)ctx.ResetResponseWriter(w)// 向新創建的ctx中添加一個Request并將文件中的數據讀取到Request的Body中file, _ := os.Open("sample_login_user.json")defer file.Close()newRequest, _ := http.NewRequest("POST", "/login", nil)newRequest.ContentLength = 500newRequest.Body = filectx.ResetRequest(newRequest)// 創建一個UsersController的實例,并設置該實例的Session屬性controller := UsersController{}cookie := http.Cookie{Name: "sample_cookie_uuid", Value: ""}ctx.SetCookie(&cookie)sess := sessions.New(sessions.Config{Cookie: "weibo_app_cookie"})controller.Session = sess.Start(ctx)// 調用UsersController實例的Login()方法進行測試user, err := controller.Login(ctx)if err != nil {t.Error("expected no error, but an error occured:", err)}if user.ID != 1 {t.Errorf("expected returned user id to be 1, but got %dn:", user.ID)}id, _ := controller.Session.GetInt("userID")if id != 1 {t.Errorf("expected user id in session to be 1, but got %dn", id)}
}

在上面的代碼中,我們會從一個叫sample_login_user.json中讀取測試數據,然后用測試數據作為參數調用Login()方法模擬登錄。登錄后,我們首先檢查登錄過程有無err以及被登錄的用戶是否是我們的測試用戶,接著我們訪問Session,并用GetInt獲得Session里的userID字段。檢查Session的userID字段的值是否和測試數據的id是一致的。

接著我們還是在controllers目錄下,新建一個sample_login_user.json文件,用來編寫測試數據。

代碼清單3-13

controllers/sample_login_user.json

{"email": "email1@sample.com","password": "password1"
}

接下來,我們打開users_controller.go,為UsersController新增一個Session屬性和一個Login()方法:

代碼清單3-14

controllers/users_controller.go

package controllersimport ("goweb/models""github.com/kataras/iris""github.com/kataras/iris/mvc""github.com/kataras/iris/sessions"
)type UsersController struct {Session *sessions.Session
}
.
.
.
func (c *UsersController) Login(ctx iris.Context) (user models.User, err error) {if err = ctx.ReadJSON(&user); err != nil {ctx.StatusCode(iris.StatusBadRequest)return}if user, err = user.Authenticate(); err != nil {return}c.Session.Set("userID", user.ID)return
}

在Login()方法中,我們讀取客戶端request中的json格式的數據,然后將這些數據映射為一個User實例。調用這個User實例的Authenticate()方法進行驗證,如果驗證能夠通過,我們就將該用戶的ID記錄到session里,并且將驗證通過的用戶保存到前面我們聲明的全局變量里。

接下來,我們在main.go里將session注冊到WeiboApp里。

代碼清單3-15

main.go

package mainimport ("github.com/kataras/iris""github.com/kataras/iris/middleware/logger""github.com/kataras/iris/middleware/recover""github.com/kataras/iris/mvc""github.com/kataras/iris/sessions""goweb/controllers"
)func main() {app := weiboApp()app.Run(iris.Addr(":8080"))
}func weiboApp() *iris.Application {app := iris.New()app.Use(recover.New())app.Use(logger.New())weiboApp := mvc.New(app)expiresTime, _ := time.ParseDuration("168h")sess := sessions.New(sessions.Config{Cookie: "weibo_app_cookie", Expires: expiresTime})weiboApp.Register(sess.Start,)helloWorldController := new(controllers.HelloWorldController)usersController := new(controllers.UsersController)weiboApp.Handle(helloWorldController)weiboApp.Handle(usersController)return app
}

我們在創建session的時候,設置的session的名字“weibo_app_cookie”和過期的時間168個小時,即一個星期。

接下來,我們清空數據庫,打開命令行工具,cd到controllers目錄,運行go test

C:Userssxu37Go>cd srcgowebcontrollers
C:Userssxu37GosrcGoWebcontrollers>go test
.
.
.
PASS
ok GoWeb/controllers 8.059s

說明我們用戶登錄的代碼也是編寫正確的。接著我們只需要再測試一下”/login“這個路徑是否可以用”POST“方法訪問即可。

代碼清單3-16

main_test.go

.
.
.
func TestLoginRoute(t *testing.T) {app := weiboApp()e := httptest.New(t, app)request := e.Request("POST", "/login")request.WithJSON(map[string]interface{}{"email": "email1@example.com", "password": "password1"})response := request.Expect()response.Status(httptest.StatusOK)
}

清空數據庫,然后打開命令行工具,cd到項目根目錄下,運行go test

C:Userssxu37GosrcGoWeb>go test
.
.
.
PASS
ok GoWeb 3.684s

用戶登錄的功能我們也成功實現了。 我們也還是可以使用crul命令測試一下:

C:Userssxu37GosrcGoWeb>curl -i -X POST -d {""email"":""email1@example.co
m"",""password"":""password1""} “http://localhost:8080/login”

1bda7156e2e7b66369fe2a74b09279dd.png

服務器按照預期返回了登錄成功的用戶信息。

在開始下一節之前,我們還是先把代碼push到Github上保管。

C:Userssxu37GosrcGoWeb>git add –A
C:Userssxu37GosrcGoWeb>git commit -m "user login"
C:Userssxu37GosrcGoWeb>git push

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529779.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529779.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529779.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pyqt生成 android,PyQt on Android

問題Im working on PyQt now, and I have to create the application on Android, Ive seen the kivy library, but its too crude.Is there any way now to run an application on Android made on PyQt?回答1:Android does not support pyQt4. PyQt5 is however supported(r…

原生的html組件,如何創建HTML5與原生UI組件混合的移動應用程序

本文將介紹如何使用Trigger.io創建原生的頂部欄、標簽欄、以及HTML/CSS/JavaScript的混合型移動應用程序。以后我們將添加更多的原生UI組件到Trigger.io,但現在你只需要使用web技術就可以在IOS和Android上創建漂亮而流暢的移動應用。這是一個簡單的菜譜應用程序的屏…

c語言不會可以學好java嗎_有人說學了C語言,兩天就能學會Java,兩個星期就可以找工作?...

作為一個過來人來說,編程如果真的那么簡單就不會導致現在各大公司還喊著招不到人的情況了,雖然編程領域里面有觸類旁通的說法,但這個說法只是針對于對于一種編程已經掌握到一定程度了,不是簡單的學過或者做過就可以輕松的轉向別的…

html 正則表達式驗證金額,js金額校驗,js正則表達式,包含正負,小數點后兩位...

js金額校驗,js正則表達式,包含正負,小數點后兩位,js代碼如下:function isMoney(s) {//金額 只允許正數//var exp /(^[1-9]([0-9])?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/;//金額 允許正()負數//…

蘋果app商品定價_【知乎問答】蘋果 App Store 新推出的 1 元或 3 元定價對開發者有什么影響?...

徐小懶:我的游戲今年 10 月 1 日上線,定價 6 元。上線后,排名起起落落,總的來說一直在爬升。截止到 19 號之前,爬到總榜前 20(未刷榜),最多一天 300 個下載,累計下載 3500。19 號改成 1 元后,當…

sublime默認html,Sublime Text默認HTML評論

似乎對安裝包裝或拆卸包裝有點隱蔽,因此需要進行一些調查才能解決問題。對于后臺,用于注釋(單行或塊)的字符或字符的設置信息由tmPreferences類型的文件提供(不是tmLanguage,如在{您在問題的評論中鏈接到的教程)。文件的名稱及其包含的包無關…

筆記本連接顯示器后沒有聲音_電腦用HDMI外界顯示器后,沒有聲音

本人使用Y450, 總感覺屏幕小, 現有PHILIPS 202E, 但是笨笨VGA壞了(真是悲催啊, 但是我強悍小Y跟我也有4~5個年頭了, 可以理解) 所以買了HDMI賺VGA, 接上顯示器后顯示非常棒, 很爽, 絕對高清. 但是唯一的缺點就是接上HDMI后笨笨就沒聲音, 而且我的飛利浦又沒有音頻輸出. 悲催了…

html文本域 高度自適應,textarea高度自適應,textarea隨著內容高度變化

有時候我們需要textarea的高度隨著內容的多少去自適應的變化,今天我使用了JS原生和JQ寫了一個textarea的高度隨著他的內容高度變化的代碼,希望能幫上忙。廢話不多說直接貼代碼:textarea{ width:500px; margin:20px auto; padding:0; font-siz…

layer 線上_LAYER

SHIPPING TO : ??(GHANA)SHIPPING TO : ??(GABON)SHIPPING TO : ????(GUYANA)SHIPPING TO : ???(GAMBIA)SHIPPING TO : ????(GUATEMALA)SHIPPING TO : ????(GRENADA)SHIPPING TO : ????(GEORGIA)SHIPPING TO : ???(GREECE)SHIPPING TO : ??(GUINEA…

ajax為什么返回html標簽,AJAX與特定值后返回的HTML標簽

我想寫使用jQuery的post.I傳遞的參數,以ajax.php并獲得josn數據添加用戶注釋代碼,如下:AJAX與特定值后返回的HTML標簽var formObjectData $(# form_id).serialize() &flagadd_comment; // all$.post(http://192.168.3.3/myblog/ajax.p…

wps合并所有sheet頁_WPS里面如何批量打印(WPS2019)

WPS里面如何批量打印(WPS2019)分四步:1. 創建WPS表格獲獎名單2. 創建WPS文字的獲獎模板3. 將WPS表格名單內容調入到WPS文字獎狀模板中4. 批量打印(或保存)(注:我在這里用了別人的office版本的表…

丘成桐科學獎計算機類,2017東潤丘成桐科學獎計算機參賽指引.PDF

2017東潤丘成桐科學獎計算機參賽指引2017 東潤丘成桐科學獎 (計算機)參賽指南一、 參賽方式? 每支參賽隊伍由1 至3 位華人中學生組成,由一位指導老師帶領,提交研究報告。? 學生身份:以在參賽報名之時是否為在校中學生為準。? 導師身份&…

keepalived mysql雙主架構圖_基于MySQL雙主的高可用解決方案理論及實踐

MySQL在互聯網應用中已經遍地開花,但是在銀行系統中,還在生根發芽的階段。本文記錄的是根據某生產系統實際需求,對數據庫高可用方案從需求、各高可用技術特點對比、實施、測試等過程進行整理,完善Mysql高可用方案,同時…

俄亥俄州立大學計算機科學轉學成功,俄亥俄州立大學轉學成功率83.38%!!

俄亥俄州立大學The Ohio State University-Columbus,即OSU成立于1870年,全美高校排名第54位(公立學校排名第18位),是美國較好的公立學校之一,亦是“公立常春藤”的成員。OSU是美國重要的學術聯盟“美國大學協會”的成員之一&#…

小愛同學100個奇葩回復_小米小愛音箱Pro開箱評測,看到的不僅是全面升級更是小米loT的高速發展...

Hello,大家好,這里是科技能量站,今天有何大家見面了,本期小編給大家帶來的是小米最新推出的小愛同學“小米小愛音箱Pro”,小米在前兩年推出了自家的小米AI音箱,那一刻起,智能語音人工助手在小米…

你了解的繼承方式html,法定繼承、遺囑繼承、遺贈,這三種房產過戶方式你了解多少?...

在房產過戶的中,與繼承相關的方式有三種:法定繼承、遺囑繼承和遺贈。這三種過戶方式其實是有較大不同的,下面我們就來具體分析下,希望能對需要的朋友有幫助。過戶在房產過戶中,與繼承相關的有三種,分別是法…

計算機在生物學研究領域的認識,阮曉鋼——北京工業大學——主要研究領域涉及:控制科學與工程,人工智能與認知科學,機器人學與機器人技術,計算機應用技術,生物醫學工程與生物信息學。...

2007 年度:[1] On-line adaptive control for inverted pendulum balancing based on feedback-error-learning. Neurocomputing, 70 (4-6): 770-776 JAN 2007.[2] A tabu based neural network learning algorithm. Neurocomputing, 70 (4-6): 875-882 JAN 2007.20…

wedo2.0編程模塊介紹_福特福克斯TCM重新編程操作

適用范圍支持車型/年款:新福克斯 2011 – 2018 1.6L/2.0L DPS6變速箱 車型嘉年華 2013 1.5L DPS6變速箱 車型翼博 2013 – 2016 1.5L DPS6變速箱 車型功能介紹升級ECU版本或者對空白ECU寫入數據, PAD Ⅲ請使用有線連接進行編程, 測試時保證車輛電瓶電壓充足條件要求…

全國計算機二級公共知識點,全國計算機二級公共基礎知識知識點

全國計算機二級公共基礎知識知識點公共基礎知識第一章 數據結構與算法1.1 算法1.1.1 算法的基本概念1、算法的基本特征可行性、確定性、有窮性、擁有足夠的情報所謂算法,是一組嚴謹地定義運算順序的規則,并且每一個規則都是有效的,且是明確的…

中計算散度的函數_梯度、散度、旋度

一、麥克斯韋基于四元數觀點導出散度與旋度已知的最早的關于散度和旋度的描述都來自麥克斯韋1873年的《A Treatise on Electricity and Magnetism》(電磁通論)一書。因此,為了探明散度和旋度的物理意義,有必要回到那本1873年的專著…