diff --git a/assignments/shell/AddUsers/addUsers.sh b/assignments/shell/AddUsers/addUsers.sh index 731563e..9778fbd 100644 --- a/assignments/shell/AddUsers/addUsers.sh +++ b/assignments/shell/AddUsers/addUsers.sh @@ -1,4 +1,4 @@ -# +#!/bin/bash # # useradd # chpasswd @@ -6,4 +6,4 @@ # chmod # edquota # - +#echo diff --git a/assignments/shell/AddUsers/addUsers.sh~ b/assignments/shell/AddUsers/addUsers.sh~ new file mode 100644 index 0000000..7eec03f --- /dev/null +++ b/assignments/shell/AddUsers/addUsers.sh~ @@ -0,0 +1,9 @@ +#!/bin/bash +# +# useradd +# chpasswd +# chown +# chmod +# edquota +# + diff --git a/experiments/gcc-1-hello-world/abc b/experiments/gcc-1-hello-world/abc new file mode 100755 index 0000000..bf033e5 Binary files /dev/null and b/experiments/gcc-1-hello-world/abc differ diff --git a/experiments/gcc-1-hello-world/main.c b/experiments/gcc-1-hello-world/main.c index abfd4b3..923f713 100644 --- a/experiments/gcc-1-hello-world/main.c +++ b/experiments/gcc-1-hello-world/main.c @@ -2,5 +2,6 @@ int main(void) { printf("Hello world!\n"); + printf("another Hello world!\n"); return 0; } diff --git a/experiments/gcc-1-hello-world/main.c~ b/experiments/gcc-1-hello-world/main.c~ new file mode 100644 index 0000000..abfd4b3 --- /dev/null +++ b/experiments/gcc-1-hello-world/main.c~ @@ -0,0 +1,6 @@ +#include + +int main(void) { + printf("Hello world!\n"); + return 0; +} diff --git a/experiments/gcc-2-multi-source/calculator.c b/experiments/gcc-2-multi-source/calculator.c index 391fc7f..cc9b6de 100644 --- a/experiments/gcc-2-multi-source/calculator.c +++ b/experiments/gcc-2-multi-source/calculator.c @@ -1,5 +1,5 @@ #include "include/calculator.h" - +#include int sum(int x, int y) { return x + y; } @@ -13,5 +13,10 @@ int multiply(int x, int y) { } int divide(int x, int divisor) { + if(divisor != 0) return x / divisor; + else{ + printf("error:divisor can not be 0\n"); + return -1; + } } diff --git a/experiments/gcc-2-multi-source/calculator.c~ b/experiments/gcc-2-multi-source/calculator.c~ new file mode 100644 index 0000000..58fd295 --- /dev/null +++ b/experiments/gcc-2-multi-source/calculator.c~ @@ -0,0 +1,22 @@ +#include "include/calculator.h" + +int sum(int x, int y) { + return x + y; +} + +int subtract(int x, int y) { + return x - y; +} + +int multiply(int x, int y) { + return x * y; +} + +int divide(int x, int divisor) { + if(divisor != 0) + return x / divisor; + else{ + echo("error:divisor can not be 0\n"); + return -1; + } +} diff --git a/experiments/gcc-2-multi-source/main.c b/experiments/gcc-2-multi-source/main.c index bdbb5b9..966798e 100644 --- a/experiments/gcc-2-multi-source/main.c +++ b/experiments/gcc-2-multi-source/main.c @@ -1,5 +1,5 @@ #include - +#include "include/calculator.h" int main(void) { int x, y; diff --git a/experiments/gcc-2-multi-source/main.c~ b/experiments/gcc-2-multi-source/main.c~ new file mode 100644 index 0000000..bdbb5b9 --- /dev/null +++ b/experiments/gcc-2-multi-source/main.c~ @@ -0,0 +1,12 @@ +#include + +int main(void) { + int x, y; + + x = 2; + y = 3; + + printf("%d + %d = %d\n", x, y, sum(2, 3)); + + return 0; +} diff --git a/experiments/gcc-3-real-project/Makefile b/experiments/gcc-3-real-project/Makefile old mode 100644 new mode 100755 diff --git a/experiments/gcc-3-real-project/calculator.c b/experiments/gcc-3-real-project/calculator.c index 391fc7f..d6b9faa 100644 --- a/experiments/gcc-3-real-project/calculator.c +++ b/experiments/gcc-3-real-project/calculator.c @@ -1,4 +1,5 @@ #include "include/calculator.h" +#include int sum(int x, int y) { return x + y; @@ -13,5 +14,10 @@ int multiply(int x, int y) { } int divide(int x, int divisor) { + if(divisor != 0) return x / divisor; + else{ + printf("error:divisor can not be 0\n"); + return -1; + } } diff --git a/experiments/gcc-3-real-project/calculator.c~ b/experiments/gcc-3-real-project/calculator.c~ new file mode 100644 index 0000000..ee59454 --- /dev/null +++ b/experiments/gcc-3-real-project/calculator.c~ @@ -0,0 +1,22 @@ +#include "include/calculator.h" +#include"include.h" +int sum(int x, int y) { + return x + y; +} + +int subtract(int x, int y) { + return x - y; +} + +int multiply(int x, int y) { + return x * y; +} + +int divide(int x, int divisor) { + if(divisor != 0) + return x / divisor; + else{ + printf("error:divisor can not be 0\n"); + return -1; + } +} diff --git a/experiments/gcc-3-real-project/main b/experiments/gcc-3-real-project/main new file mode 100755 index 0000000..d16f1ec Binary files /dev/null and b/experiments/gcc-3-real-project/main differ diff --git a/experiments/gcc-3-real-project/main.c~ b/experiments/gcc-3-real-project/main.c~ new file mode 100644 index 0000000..6798996 --- /dev/null +++ b/experiments/gcc-3-real-project/main.c~ @@ -0,0 +1,14 @@ +#include + +#include "include/calculator.h" + +int main(void) { + int x, y; + + x = 2; + y = 3; + + printf("%d - %d = %d\n", x, y, subtract(2, 3)); + + return 0; +} diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/Makefile" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/Makefile" new file mode 100755 index 0000000..0531065 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/Makefile" @@ -0,0 +1,9 @@ +main:main.o calculator.o + gcc main.o calculator.o -o main +main.o:main.c + gcc -c main.c +calculator.o:calculator.c + gcc -c calculator.c + +clean: + rm main *.o diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c" new file mode 100644 index 0000000..facf66c --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c" @@ -0,0 +1,9 @@ +#include "include/calculator.h" + + +int compare(int a,int b){ + if(a>b) + return 1; + else + return 0; +} diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c~" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c~" new file mode 100644 index 0000000..cce2b11 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/calculator.c~" @@ -0,0 +1,9 @@ +#include "include/calculator.h" + + +bool compare(int a,int b){ + if(a>b) + return true; + else + return false; +} diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h" new file mode 100644 index 0000000..220d1a5 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h" @@ -0,0 +1,6 @@ +#ifndef _CALC_H +#define _CALC_H + +int compare(int a,int b); + +#endif //_CALC_H diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h~" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h~" new file mode 100644 index 0000000..c664dc7 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/include/calculator.h~" @@ -0,0 +1,6 @@ +#ifndef _CALC_H +#define _CALC_H + +bool compare(int a,int b); + +#endif //_CALC_H diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main" new file mode 100755 index 0000000..294fdab Binary files /dev/null and "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main" differ diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c" new file mode 100644 index 0000000..94ff2d9 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c" @@ -0,0 +1,14 @@ +#include + +#include "include/calculator.h" + +int main(void) { + int x,y; + x=3,y=2; + printf("x>2:"); + if(compare(x,y)>0) + printf("true\n"); + else + printf("false\n"); + return 0; +} diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c~" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c~" new file mode 100644 index 0000000..5bc6fc2 --- /dev/null +++ "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/main.c~" @@ -0,0 +1,10 @@ +#include + +#include "include/calculator.h" + +int main(void) { + int x,y; + x=3,y=2; + printf("x>2:",compare(x,y)>0?printf("true\n"):printf("false\n")); + return 0; +} diff --git "a/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/wo~" "b/experiments/\347\234\237\345\256\236\347\232\204C\351\241\271\347\233\256/wo~" new file mode 100644 index 0000000..e69de29 diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/Makefile" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/Makefile" new file mode 100644 index 0000000..121d85a --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/Makefile" @@ -0,0 +1,36 @@ +result:main array calculator + gcc main.o array.o calculator.o -o result + +main: main_clean main.c + gcc -c -O0 main.c +main_optimize: main_clean main.c + gcc -c -O2 main.c +main_clean: + if [ -e main.o ] ; then rm main.o ; fi + + +calculator:calculator.c + gcc -c calculator.c + +array: array_clean array.c + gcc -c -O0 array.c +array_optimize: array_clean array.c + gcc -c -O2 array.c +array_clean: + if [ -e array.o ] ; then rm array.o ; fi + + +release: main_optimize array_optimize calculator + gcc main.o array.o -o release + +diff: result release + ./result + ./release + +clean: + if [ -e result ] ; then rm result ; fi + + if [ -e release ] ; then rm release ; fi + + rm *.o + diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c" new file mode 100644 index 0000000..8ea86ba --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c" @@ -0,0 +1,35 @@ +#include + +#include "include/array.h" + +#define VECTOR_LENGTH 2048 + +void array_get(int arrayX[VECTOR_LENGTH][VECTOR_LENGTH],int arrayY[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2){ + int i,j; + for(i = 0 ; i < n1 ; i ++ ) + for(j = 0 ; j < m1; j++ ) + scanf("%d",&arrayX[i][j]); + for(i = 0 ; i < n2 ; i ++ ) + for(j = 0 ; j < m2; j++ ) + scanf("%d",&arrayY[i][j]); +} + +void array_multiply(int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], int vector_b[VECTOR_LENGTH][VECTOR_LENGTH], int vector_c[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2){ + if(m1!=n2){ + printf("Error!\n"); + return ; + } + int i,j,k; + for(i = 0 ;i < n1; i ++) + for(k = 0 ;k < m2 ; k++) + vector_c[i][k] = 0; + for(i = 0 ; i < n1; i++) + for(j = 0 ; j < m1 ;j++) + for(k = 0;k < m2 ; k++) + vector_c[i][k] += vector_a[i][j]*vector_b[j][k]; +} + + + + + diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c~" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c~" new file mode 100644 index 0000000..56a5784 --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/array.c~" @@ -0,0 +1,35 @@ +#include + +#include "include/array.h" + +#define VECTOR_LENGTH 2048 + +void array_get(int arrayX[VECTOR_LENGTH][VECTOR_LENGTH],int arrayY[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2){ + int i,j; + for(i = 0 ; i < n1 ; i ++ ) + for(j = 0 ; j < m1; j++ ) + scanf("%d",&arrayX[i][j]); + for(i = 0 ; i < n2 ; i ++ ) + for(j = 0 ; j < m2; j++ ) + scanf("%d",&arrayY[i][j]); +} + +void array_multiply(int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], int vector_b[VECTOR_LENGTH][VECTOR_LENGTH], int vector_c[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2){ + if(m1!=n2){ + printf("Error!\n"); + return ; + } + int i,j,k; + for(i = 0 ;i < n1; i ++) + for(k = 0 ;k < m2 ; k++) + vector_c[[i][k] = 0; + for(i = 0 ; i < n1; i++) + for(j = 0 ; j < m1 ;j++) + for(k = 0;k < m2 ; k++) + vector_c[i][k] += vector_a[i][j]*vector_b[j][k]; +} + + + + + diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/calculator.c" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/calculator.c" new file mode 100644 index 0000000..391fc7f --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/calculator.c" @@ -0,0 +1,17 @@ +#include "include/calculator.h" + +int sum(int x, int y) { + return x + y; +} + +int subtract(int x, int y) { + return x - y; +} + +int multiply(int x, int y) { + return x * y; +} + +int divide(int x, int divisor) { + return x / divisor; +} diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h" new file mode 100644 index 0000000..e096be4 --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h" @@ -0,0 +1,8 @@ +#ifndef _ARRAY_H +#define _ARRAY_H +#define VECTOR_LENGTH 2048 +void array_get(int arrayX[VECTOR_LENGTH][VECTOR_LENGTH],int arrayY[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2); + +void array_multiply(int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], int vector_b[VECTOR_LENGTH][VECTOR_LENGTH], int vector_c[VECTOR_LENGTH][VECTOR_LENGTH],int n1,int m1,int n2,int m2); + +#endif diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h~" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h~" new file mode 100644 index 0000000..c15879b --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/array.h~" @@ -0,0 +1,8 @@ +#ifndef _ARRAY_H +#define _ARRAY_H +#define VECTOR_LENGTH 2048 +void array_get(int arrayX[VECTOR_LENGTH][VECTOR_LENGTH],int arrayY[VECTOR_LENGTH][VECTOR_LENGTH]); + +void array_multiply(int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], int vector_b[VECTOR_LENGTH][VECTOR_LENGTH], int vector_c[VECTOR_LENGTH][VECTOR_LENGTH]); + +#endif diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/calculator.h" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/calculator.h" new file mode 100644 index 0000000..a5e00e3 --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/include/calculator.h" @@ -0,0 +1,9 @@ +#ifndef _CALC_H +#define _CALC_H + +int sum(int x, int y); +int subtract(int x, int y); +int multiply(int x, int y); +int divide(int x, int divisor); + +#endif //_CALC_H diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c" new file mode 100644 index 0000000..b9f5cfa --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c" @@ -0,0 +1,36 @@ +#include +#include + +#include "include/calculator.h" + +#include "include/array.h" + +#define VECTOR_LENGTH 2048 + +int n1,m1,n2,m2; + +int main(void) { + + int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], vector_b[VECTOR_LENGTH][VECTOR_LENGTH], vector_c[VECTOR_LENGTH][VECTOR_LENGTH]; + + double time_start, time_end; + + scanf("%d%d%d%d",&n1,&m1,&n2,&m2); + + array_get(vector_a,vector_b,n1,m1,n2,m2); + + time_start = clock(); + + array_multiply(vector_a, vector_b, vector_c,n1,m1,n2,m2); + + time_end = clock(); + + //array_print(vector_c, VECTOR_LENGTH); + + printf("Time used: %10.9f\n", (double) ( (time_end - time_start) / 1000.0) ); + + return 0; +} + + + diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c~" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c~" new file mode 100644 index 0000000..242a682 --- /dev/null +++ "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/main.c~" @@ -0,0 +1,36 @@ +#include +#include + +#include "include/calculator.h" + +#include "include/array.h" + +#define VECTOR_LENGTH 2048 + +int n1,m1,n2,m2; + +int main(void) { + + int vector_a[VECTOR_LENGTH][VECTOR_LENGTH], vector_b[VECTOR_LENGTH][VECTOR_LENGTH], vector_c[VECTOR_LENGTH][VECTOR_LENGTH]; + + double time_start, time_end; + + scanf("%d%d%d%d",&n1,&m1,&n2,&m2); + + array_get(vector_a,vector_b); + + time_start = clock(); + + array_multiply(vector_a, vector_b, vector_c); + + time_end = clock(); + + //array_print(vector_c, VECTOR_LENGTH); + + printf("Time used: %10.9f\n", (double) ( (time_end - time_start) / 1000.0) ); + + return 0; +} + + + diff --git "a/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/result" "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/result" new file mode 100755 index 0000000..f2bf03d Binary files /dev/null and "b/experiments/\347\274\226\350\257\221\345\231\250\344\274\230\345\214\226\344\275\234\344\270\232/result" differ diff --git a/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt b/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt index 3b095d0..59a899e 100644 --- a/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt +++ b/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt @@ -1,48 +1,50 @@ b -1 -00:00:00,000 --> 00:00:04,950 -[MUSIC PLAYING] STEFAN RITTER: Hi guys. - -2 -00:00:04,950 --> 00:00:07,770 -I'm Stefan, and I'm working on multiple projects at the moment. - -3 -00:00:07,770 --> 00:00:12,240 -One is buzzr.io, one is fitguru.org, and one is pickfeed.io. - -4 -00:00:12,240 --> 00:00:17,830 -And today I'm going to talk about how I use a common code base to pivot to all these different ideas. - -5 -00:00:17,830 --> 00:00:23,300 -While working on different startup ideas, I quickly realized there are common parts to each idea. -当研究不同的创业想法时,我很快意识到他们有共同的部分。 -6 -00:00:23,300 --> 00:00:29,320 -So I created an abstraction called emptyApp, which combines these five features that I singled out. - -7 -00:00:29,320 --> 00:00:52,720 -The five features are a landing page with an email sign up so you can go online right away and start collecting emails from people who are interested, a client-agnostic API server that doesn't care if the front-end is a web app or a mobile app, and then a front-end app, which for me usually is the web app, since I think the web is the biggest [INAUDIBLE] platform, and then a user model, since you need to save your users. -这五个特性是一个电子邮件注册的网页,这样你就可以立即上网,开始收集感兴趣的人的电子邮件,用一个API服务器(不在乎前端是一个移动web应用程序或应用程序与否),然后前端应用程序,这对我来说通常是web应用程序,因为我觉得网络是最大的[全场寂静]平台,然后一个用户模型,因为您需要保存你的用户。 - -8 -00:00:52,720 --> 00:00:57,560 -And the fifth thing would be a login authentication scheme with Twitter, Facebook, G+, or email. - -9 -00:00:57,560 --> 00:01:02,550 -Let's look at the five features in emptyApp as they come from the repo when your freshly install it. - -10 -00:01:02,550 --> 00:01:12,710 -So this is emptyApp's landing page where you can collect users' email addresses who might be interested until you launch. -所以这是emptyapp着陆页,在这里您可以收集用户的电子邮件地址的人会感兴趣,直到你发射。 - -11 -00:01:12,710 --> 00:01:24,640 +1 +00:00:00,000 --> 00:00:04,950 +[MUSIC PLAYING] STEFAN RITTER: Hi guys. +[背景音乐] STEFAN RITTER: 大家好。 + +2 +00:00:04,950 --> 00:00:07,770 +I'm Stefan, and I'm working on multiple projects at the moment. +我叫斯蒂芬,此时我在工作。 + +3 +00:00:07,770 --> 00:00:12,240 +One is buzzr.io, one is fitguru.org, and one is pickfeed.io. + +4 +00:00:12,240 --> 00:00:17,830 +And today I'm going to talk about how I use a common code base to pivot to all these different ideas. + +5 +00:00:17,830 --> 00:00:23,300 +While working on different startup ideas, I quickly realized there are common parts to each idea. +当研究不同的创业想法时,我很快意识到他们有共同的部分。 +6 +00:00:23,300 --> 00:00:29,320 +So I created an abstraction called emptyApp, which combines these five features that I singled out. + +7 +00:00:29,320 --> 00:00:52,720 +The five features are a landing page with an email sign up so you can go online right away and start collecting emails from people who are interested, a client-agnostic API server that doesn't care if the front-end is a web app or a mobile app, and then a front-end app, which for me usually is the web app, since I think the web is the biggest [INAUDIBLE] platform, and then a user model, since you need to save your users. +这五个特性是一个电子邮件注册的网页,这样你就可以立即上网,开始收集感兴趣的人的电子邮件,用一个API服务器(不在乎前端是一个移动web应用程序或应用程序与否),然后前端应用程序,这对我来说通常是web应用程序,因为我觉得网络是最大的[全场寂静]平台,然后一个用户模型,因为您需要保存你的用户。 + +8 +00:00:52,720 --> 00:00:57,560 +And the fifth thing would be a login authentication scheme with Twitter, Facebook, G+, or email. + +9 +00:00:57,560 --> 00:01:02,550 +Let's look at the five features in emptyApp as they come from the repo when your freshly install it. + +10 +00:01:02,550 --> 00:01:12,710 +So this is emptyApp's landing page where you can collect users' email addresses who might be interested until you launch. +所以这是emptyapp着陆页,在这里您可以收集用户的电子邮件地址的人会感兴趣,直到你发射。 + +11 +00:01:12,710 --> 00:01:24,640 So if you just enter an email address here, you can link it up to a Mailchimp list and collect email addresses that way. 不会翻译 A @@ -60,268 +62,268 @@ B B A A - - -12 -00:01:24,640 --> 00:01:29,530 -But then emptyApp also gives you real login functionality. -但是emptyApp也赋予了你真正的登录功能 - -13 -00:01:29,530 --> 00:01:42,980 -So for example, if we try to log on like this, this user doesn't exist. - -14 -00:01:42,980 --> 00:01:45,660 -So obviously we get an error message. - -15 -00:01:45,660 --> 00:01:56,210 -But then if we go to Join, we can create this user. -(但是如果我们加入,就能创建这个用户.) - -16 -00:01:56,210 --> 00:01:58,340 -And then now you're logged in. - -17 -00:01:58,340 --> 00:02:04,130 -So if we try to go back to the homepage, emptyApp will automatically log you back in. - -18 -00:02:04,130 --> 00:02:06,950 -And you're landing on the logged in home page. - -19 -00:02:06,950 --> 00:02:09,474 -There's also a logged out future. - -20 -00:02:09,474 --> 00:02:13,680 -So you can just log out again, and you're back logged out on the home page. - -21 -00:02:13,680 --> 00:02:18,010 -And then, of course, you can do all this as well with all the social media logins. - -22 -00:02:18,010 --> 00:02:19,426 -So here we have Twitter activated. - -23 -00:02:19,426 --> 00:02:27,857 -And then we log back in. - -24 -00:02:27,857 --> 00:02:30,440 -All right, now I'm going to show you these features in action. -没关系,我现在示范一下。 - -25 -00:02:30,440 --> 00:02:40,450 -So if we go to buzzr.io, you can see when you first land on the app there's a landing page. -所以如果我们去buzzr.io,你可以看到你第一次打开app的页面 - -26 -00:02:40,450 --> 00:02:46,400 -But then over here you see we have links to the Join, links to the Login. - -27 -00:02:46,400 --> 00:02:48,945 -And once we're here, we can log in with our user account. -一旦我们加入,我们可以用自己的用户名登录。 - -28 -00:02:48,945 --> 00:02:58,700 -我们登陆登录使用的主页。 -And we land on the logged in home page. - -29 -00:02:58,700 --> 00:03:02,930 -All right, now let me show you what the emptyApp looks like on GitHub. - -30 -00:03:02,930 --> 00:03:14,862 -So if you go to my username, stefanritter/emptyapp-- so there's a link right here so you can download and clone the app. - -31 -00:03:14,862 --> 00:03:17,070 -There are little instructions on how to do the setup. -这里有一些如何安装的说明。 - -32 -00:03:17,070 --> 00:03:25,920 -So it comes with a Grunt file, as well as scripts to do the testing and a supervisor script to watch for server changes. - -33 -00:03:25,920 --> 00:03:34,930 -So if you download the app, and then you want to start it, what you do is you CD into the emptyApp directory. - -34 -00:03:34,930 --> 00:03:37,960 -And then you just run the start script. + + +12 +00:01:24,640 --> 00:01:29,530 +But then emptyApp also gives you real login functionality. +但是emptyApp也赋予了你真正的登录功能 + +13 +00:01:29,530 --> 00:01:42,980 +So for example, if we try to log on like this, this user doesn't exist. + +14 +00:01:42,980 --> 00:01:45,660 +So obviously we get an error message. + +15 +00:01:45,660 --> 00:01:56,210 +But then if we go to Join, we can create this user. +(但是如果我们加入,就能创建这个用户.) + +16 +00:01:56,210 --> 00:01:58,340 +And then now you're logged in. + +17 +00:01:58,340 --> 00:02:04,130 +So if we try to go back to the homepage, emptyApp will automatically log you back in. + +18 +00:02:04,130 --> 00:02:06,950 +And you're landing on the logged in home page. + +19 +00:02:06,950 --> 00:02:09,474 +There's also a logged out future. + +20 +00:02:09,474 --> 00:02:13,680 +So you can just log out again, and you're back logged out on the home page. + +21 +00:02:13,680 --> 00:02:18,010 +And then, of course, you can do all this as well with all the social media logins. + +22 +00:02:18,010 --> 00:02:19,426 +So here we have Twitter activated. + +23 +00:02:19,426 --> 00:02:27,857 +And then we log back in. + +24 +00:02:27,857 --> 00:02:30,440 +All right, now I'm going to show you these features in action. +没关系,我现在示范一下。 + +25 +00:02:30,440 --> 00:02:40,450 +So if we go to buzzr.io, you can see when you first land on the app there's a landing page. +所以如果我们去buzzr.io,你可以看到你第一次打开app的页面 + +26 +00:02:40,450 --> 00:02:46,400 +But then over here you see we have links to the Join, links to the Login. + +27 +00:02:46,400 --> 00:02:48,945 +And once we're here, we can log in with our user account. +一旦我们加入,我们可以用自己的用户名登录。 + +28 +00:02:48,945 --> 00:02:58,700 +我们登陆登录使用的主页。 +And we land on the logged in home page. + +29 +00:02:58,700 --> 00:03:02,930 +All right, now let me show you what the emptyApp looks like on GitHub. + +30 +00:03:02,930 --> 00:03:14,862 +So if you go to my username, stefanritter/emptyapp-- so there's a link right here so you can download and clone the app. + +31 +00:03:14,862 --> 00:03:17,070 +There are little instructions on how to do the setup. +这里有一些如何安装的说明。 + +32 +00:03:17,070 --> 00:03:25,920 +So it comes with a Grunt file, as well as scripts to do the testing and a supervisor script to watch for server changes. + +33 +00:03:25,920 --> 00:03:34,930 +So if you download the app, and then you want to start it, what you do is you CD into the emptyApp directory. + +34 +00:03:34,930 --> 00:03:37,960 +And then you just run the start script. 然后你就可以运行你的开始脚本了。 - -35 -00:03:37,960 --> 00:03:43,870 -And what it will do is start all the tests, the Grunt watching. - -36 -00:03:43,870 --> 00:03:52,140 -And from that point on, you can demo the app on your local host. - -37 -00:03:52,140 --> 00:03:56,130 -It's a MongoDB database, so the whole app is written in JavaScript. - -38 -00:03:56,130 --> 00:03:58,460 -All my apps are written 100% in JavaScript. - -39 -00:03:58,460 --> 00:04:03,120 -Because you can use JavaScript on the front-end, on the back-end, as well as to talk to your database. - -40 -00:04:03,120 --> 00:04:05,570 -So there's less mental overhead. - -41 -00:04:05,570 --> 00:04:08,410 -For the database, I use MongoDB. -对于数据库,我使用MongoDB - -42 -00:04:08,410 --> 00:04:16,779 -MongoDB is schemaless, so you can change fields on models very quickly, which is very important when you're pivoting between extreme different ideas. - -43 -00:04:16,779 --> 00:04:20,589 -For the front-end, I use AngularJS, which has awesome dependency injection. - -44 -00:04:20,589 --> 00:04:27,310 -So it's very easy to throw around features within your app-- also, again, important when you're changing and pivoting ideas. -所以抛去特征是非常容易的,后面的不懂了。。。 - -45 -00:04:27,310 --> 00:04:33,870 -And then for the server, I use Happy.js, which is a server built specifically for being an API server. -[zhe ge mei you han yu.] - -46 -00:04:33,870 --> 00:04:38,810 -So it's very great to be a front-end-agnostic server back-end. - -47 -00:04:38,810 --> 00:04:39,860 -This is the Grunt task. + +35 +00:03:37,960 --> 00:03:43,870 +And what it will do is start all the tests, the Grunt watching. + +36 +00:03:43,870 --> 00:03:52,140 +And from that point on, you can demo the app on your local host. + +37 +00:03:52,140 --> 00:03:56,130 +It's a MongoDB database, so the whole app is written in JavaScript. + +38 +00:03:56,130 --> 00:03:58,460 +All my apps are written 100% in JavaScript. + +39 +00:03:58,460 --> 00:04:03,120 +Because you can use JavaScript on the front-end, on the back-end, as well as to talk to your database. + +40 +00:04:03,120 --> 00:04:05,570 +So there's less mental overhead. + +41 +00:04:05,570 --> 00:04:08,410 +For the database, I use MongoDB. +对于数据库,我使用MongoDB + +42 +00:04:08,410 --> 00:04:16,779 +MongoDB is schemaless, so you can change fields on models very quickly, which is very important when you're pivoting between extreme different ideas. + +43 +00:04:16,779 --> 00:04:20,589 +For the front-end, I use AngularJS, which has awesome dependency injection. + +44 +00:04:20,589 --> 00:04:27,310 +So it's very easy to throw around features within your app-- also, again, important when you're changing and pivoting ideas. +所以抛去特征是非常容易的,后面的不懂了。。。 + +45 +00:04:27,310 --> 00:04:33,870 +And then for the server, I use Happy.js, which is a server built specifically for being an API server. +[zhe ge mei you han yu.] + +46 +00:04:33,870 --> 00:04:38,810 +So it's very great to be a front-end-agnostic server back-end. + +47 +00:04:38,810 --> 00:04:39,860 +This is the Grunt task. 这是Grunt的任务。 - -48 -00:04:39,860 --> 00:04:46,610 -The Grunt task just watches for file changes and checks the code and tells you if something's wrong and runs all your tests. -我看不懂,不会翻译。 - -49 -00:04:46,610 --> 00:04:51,710 -This is the Karma tab, which runs all the front-end tasks. -这是Karma标签,它执行所有的前置任务. - -50 -00:04:51,710 --> 00:04:57,970 -And then this is the Server tab, which watches for changes in server code and restarts the server if it finds any. -然后,这是....不懂了 - -51 -00:04:57,970 --> 00:05:01,870 -This is what the folder structure looks like of the code. - -52 -00:05:01,870 --> 00:05:04,364 -There are three main folders for you to watch out for. - -53 -00:05:04,364 --> 00:05:07,870 -There is the Client folder, the Server folder, and the Test folder. - -54 -00:05:07,870 --> 00:05:11,187 -It's quite self explanatory what each includes. - -55 -00:05:11,187 --> 00:05:15,270 -But it's important to point out that the client and the server are completely separate. - -56 -00:05:15,270 --> 00:05:23,085 -So this is the client-agnostic API server I talked about previously where the client could be, in this case, an AngularJS app. -所以这是客户无关的API服务器我谈到以前在客户的可能,在这种情况下,一个AngularJS应用。 - -57 -00:05:23,085 --> 00:05:29,330 -But it could also just be an iOS app or an Android app that talks to your server. -但是只有在ios或Android系统上与你的服务器相交互 - -58 -00:05:29,330 --> 00:05:43,710 -And so what happens is if you change something here, Grunt will monitor the change, and then build the front-end code again and inject it into the server. -所以如果你改动了这儿的什么,Grunt会监视变动,然后重建前端代码,把它添加到服务器里。 - -59 -00:05:43,710 --> 00:05:47,232 -So the server will serve the updated app for you. - -60 -00:05:47,232 --> 00:05:49,440 -So the other thing we talked about is the user model. - -61 -00:05:49,440 --> 00:05:56,710 -So if you look into the Server folder, you can see it comes with just one model, which is the user. -所以如果你看看服务器文件夹,你可以看到它只是一个模型,这是用户的。 - -62 -00:05:56,710 --> 00:06:03,239 -The user model comes with just the basic things you need, like username, display name, email, [INAUDIBLE], and passwords. - -63 -00:06:03,239 --> 00:06:04,780 -The controllers are also very simple. - -64 -00:06:04,780 --> 00:06:09,550 -Their authentication controller handles all the login stuff that we previously looked at. -在他们的身份验证控制器处理完所以东西之前,我们就看着。 - -65 -00:06:09,550 --> 00:06:14,400 -There's a feed controller that simply serves the logged in homepage. - -66 -00:06:14,400 --> 00:06:16,670 -There's also a little bonus here. - -67 -00:06:16,670 --> 00:06:18,970 -For real time chatting, there's a Socket.IO set up. - -68 -00:06:18,970 --> 00:06:29,580 -So under Config, there's a little Socket.IO setup where you can then send real time messages back and forth to your clients. - -69 -00:06:29,580 --> 00:06:33,559 -And so this is how I use my common code base to create all these different ideas. - -70 -00:06:33,559 --> 00:06:34,850 -You can check it out on GitHub. - -71 -00:06:34,850 --> 00:06:37,670 -It's on my user name, and then the repo is called emptyApp. - -72 -00:06:37,670 --> 00:06:39,510 -Thanks for watching. + +48 +00:04:39,860 --> 00:04:46,610 +The Grunt task just watches for file changes and checks the code and tells you if something's wrong and runs all your tests. +我看不懂,不会翻译。 + +49 +00:04:46,610 --> 00:04:51,710 +This is the Karma tab, which runs all the front-end tasks. +这是Karma标签,它执行所有的前置任务. + +50 +00:04:51,710 --> 00:04:57,970 +And then this is the Server tab, which watches for changes in server code and restarts the server if it finds any. +然后,这是....不懂了 + +51 +00:04:57,970 --> 00:05:01,870 +This is what the folder structure looks like of the code. + +52 +00:05:01,870 --> 00:05:04,364 +There are three main folders for you to watch out for. + +53 +00:05:04,364 --> 00:05:07,870 +There is the Client folder, the Server folder, and the Test folder. + +54 +00:05:07,870 --> 00:05:11,187 +It's quite self explanatory what each includes. + +55 +00:05:11,187 --> 00:05:15,270 +But it's important to point out that the client and the server are completely separate. + +56 +00:05:15,270 --> 00:05:23,085 +So this is the client-agnostic API server I talked about previously where the client could be, in this case, an AngularJS app. +所以这是客户无关的API服务器我谈到以前在客户的可能,在这种情况下,一个AngularJS应用。 + +57 +00:05:23,085 --> 00:05:29,330 +But it could also just be an iOS app or an Android app that talks to your server. +但是只有在ios或Android系统上与你的服务器相交互 + +58 +00:05:29,330 --> 00:05:43,710 +And so what happens is if you change something here, Grunt will monitor the change, and then build the front-end code again and inject it into the server. +所以如果你改动了这儿的什么,Grunt会监视变动,然后重建前端代码,把它添加到服务器里。 + +59 +00:05:43,710 --> 00:05:47,232 +So the server will serve the updated app for you. + +60 +00:05:47,232 --> 00:05:49,440 +So the other thing we talked about is the user model. + +61 +00:05:49,440 --> 00:05:56,710 +So if you look into the Server folder, you can see it comes with just one model, which is the user. +所以如果你看看服务器文件夹,你可以看到它只是一个模型,这是用户的。 + +62 +00:05:56,710 --> 00:06:03,239 +The user model comes with just the basic things you need, like username, display name, email, [INAUDIBLE], and passwords. + +63 +00:06:03,239 --> 00:06:04,780 +The controllers are also very simple. + +64 +00:06:04,780 --> 00:06:09,550 +Their authentication controller handles all the login stuff that we previously looked at. +在他们的身份验证控制器处理完所以东西之前,我们就看着。 + +65 +00:06:09,550 --> 00:06:14,400 +There's a feed controller that simply serves the logged in homepage. + +66 +00:06:14,400 --> 00:06:16,670 +There's also a little bonus here. + +67 +00:06:16,670 --> 00:06:18,970 +For real time chatting, there's a Socket.IO set up. + +68 +00:06:18,970 --> 00:06:29,580 +So under Config, there's a little Socket.IO setup where you can then send real time messages back and forth to your clients. + +69 +00:06:29,580 --> 00:06:33,559 +And so this is how I use my common code base to create all these different ideas. + +70 +00:06:33,559 --> 00:06:34,850 +You can check it out on GitHub. + +71 +00:06:34,850 --> 00:06:37,670 +It's on my user name, and then the repo is called emptyApp. + +72 +00:06:37,670 --> 00:06:39,510 +Thanks for watching. diff --git a/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt~ b/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt~ index 1d8082c..8e81d36 100644 --- a/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt~ +++ b/final-test/git_workflow/How I- Use a common code repo to pivot quickly.srt~ @@ -1,287 +1,328 @@ -1 -00:00:00,000 --> 00:00:04,950 -[MUSIC PLAYING] STEFAN RITTER: Hi guys. - -2 -00:00:04,950 --> 00:00:07,770 -I'm Stefan, and I'm working on multiple projects at the moment. - -3 -00:00:07,770 --> 00:00:12,240 -One is buzzr.io, one is fitguru.org, and one is pickfeed.io. - -4 -00:00:12,240 --> 00:00:17,830 -And today I'm going to talk about how I use a common code base to pivot to all these different ideas. - -5 -00:00:17,830 --> 00:00:23,300 -While working on different startup ideas, I quickly realized there are common parts to each idea. - -6 -00:00:23,300 --> 00:00:29,320 -So I created an abstraction called emptyApp, which combines these five features that I singled out. - -7 -00:00:29,320 --> 00:00:52,720 -The five features are a landing page with an email sign up so you can go online right away and start collecting emails from people who are interested, a client-agnostic API server that doesn't care if the front-end is a web app or a mobile app, and then a front-end app, which for me usually is the web app, since I think the web is the biggest [INAUDIBLE] platform, and then a user model, since you need to save your users. - -8 -00:00:52,720 --> 00:00:57,560 -And the fifth thing would be a login authentication scheme with Twitter, Facebook, G+, or email. - -9 -00:00:57,560 --> 00:01:02,550 -Let's look at the five features in emptyApp as they come from the repo when your freshly install it. - -10 -00:01:02,550 --> 00:01:12,710 -So this is emptyApp's landing page where you can collect users' email addresses who might be interested until you launch. - -11 -00:01:12,710 --> 00:01:24,640 -So if you just enter an email address here, you can link it up to a Mailchimp list and collect email addresses that way. - -12 -00:01:24,640 --> 00:01:29,530 -But then emptyApp also gives you real login functionality. - -13 -00:01:29,530 --> 00:01:42,980 -So for example, if we try to log on like this, this user doesn't exist. - -14 -00:01:42,980 --> 00:01:45,660 -So obviously we get an error message. - -15 -00:01:45,660 --> 00:01:56,210 -But then if we go to Join, we can create this user. - -16 -00:01:56,210 --> 00:01:58,340 -And then now you're logged in. - -17 -00:01:58,340 --> 00:02:04,130 -So if we try to go back to the homepage, emptyApp will automatically log you back in. - -18 -00:02:04,130 --> 00:02:06,950 -And you're landing on the logged in home page. - -19 -00:02:06,950 --> 00:02:09,474 -There's also a logged out future. - -20 -00:02:09,474 --> 00:02:13,680 -So you can just log out again, and you're back logged out on the home page. - -21 -00:02:13,680 --> 00:02:18,010 -And then, of course, you can do all this as well with all the social media logins. - -22 -00:02:18,010 --> 00:02:19,426 -So here we have Twitter activated. - -23 -00:02:19,426 --> 00:02:27,857 -And then we log back in. - -24 -00:02:27,857 --> 00:02:30,440 -All right, now I'm going to show you these features in action. - -25 -00:02:30,440 --> 00:02:40,450 -So if we go to buzzr.io, you can see when you first land on the app there's a landing page. - -26 -00:02:40,450 --> 00:02:46,400 -But then over here you see we have links to the Join, links to the Login. - -27 -00:02:46,400 --> 00:02:48,945 -And once we're here, we can log in with our user account. - -28 -00:02:48,945 --> 00:02:58,700 -And we land on the logged in home page. - -29 -00:02:58,700 --> 00:03:02,930 -All right, now let me show you what the emptyApp looks like on GitHub. - -30 -00:03:02,930 --> 00:03:14,862 -So if you go to my username, stefanritter/emptyapp-- so there's a link right here so you can download and clone the app. - -31 -00:03:14,862 --> 00:03:17,070 -There are little instructions on how to do the setup. - -32 -00:03:17,070 --> 00:03:25,920 -So it comes with a Grunt file, as well as scripts to do the testing and a supervisor script to watch for server changes. - -33 -00:03:25,920 --> 00:03:34,930 -So if you download the app, and then you want to start it, what you do is you CD into the emptyApp directory. - -34 -00:03:34,930 --> 00:03:37,960 -And then you just run the start script. - -35 -00:03:37,960 --> 00:03:43,870 -And what it will do is start all the tests, the Grunt watching. - -36 -00:03:43,870 --> 00:03:52,140 -And from that point on, you can demo the app on your local host. - -37 -00:03:52,140 --> 00:03:56,130 -It's a MongoDB database, so the whole app is written in JavaScript. - -38 -00:03:56,130 --> 00:03:58,460 -All my apps are written 100% in JavaScript. - -39 -00:03:58,460 --> 00:04:03,120 -Because you can use JavaScript on the front-end, on the back-end, as well as to talk to your database. - -40 -00:04:03,120 --> 00:04:05,570 -So there's less mental overhead. - -41 -00:04:05,570 --> 00:04:08,410 -For the database, I use MongoDB. - -42 -00:04:08,410 --> 00:04:16,779 -MongoDB is schemaless, so you can change fields on models very quickly, which is very important when you're pivoting between extreme different ideas. - -43 -00:04:16,779 --> 00:04:20,589 -For the front-end, I use AngularJS, which has awesome dependency injection. - -44 -00:04:20,589 --> 00:04:27,310 -So it's very easy to throw around features within your app-- also, again, important when you're changing and pivoting ideas. - -45 -00:04:27,310 --> 00:04:33,870 -And then for the server, I use Happy.js, which is a server built specifically for being an API server. - -46 -00:04:33,870 --> 00:04:38,810 -So it's very great to be a front-end-agnostic server back-end. - -47 -00:04:38,810 --> 00:04:39,860 -This is the Grunt task. - -48 -00:04:39,860 --> 00:04:46,610 -The Grunt task just watches for file changes and checks the code and tells you if something's wrong and runs all your tests. - -49 -00:04:46,610 --> 00:04:51,710 -This is the Karma tab, which runs all the front-end tasks. - -50 -00:04:51,710 --> 00:04:57,970 -And then this is the Server tab, which watches for changes in server code and restarts the server if it finds any. - -51 -00:04:57,970 --> 00:05:01,870 -This is what the folder structure looks like of the code. - -52 -00:05:01,870 --> 00:05:04,364 -There are three main folders for you to watch out for. - -53 -00:05:04,364 --> 00:05:07,870 -There is the Client folder, the Server folder, and the Test folder. - -54 -00:05:07,870 --> 00:05:11,187 -It's quite self explanatory what each includes. - -55 -00:05:11,187 --> 00:05:15,270 -But it's important to point out that the client and the server are completely separate. - -56 -00:05:15,270 --> 00:05:23,085 -So this is the client-agnostic API server I talked about previously where the client could be, in this case, an AngularJS app. - -57 -00:05:23,085 --> 00:05:29,330 -But it could also just be an iOS app or an Android app that talks to your server. - -58 -00:05:29,330 --> 00:05:43,710 -And so what happens is if you change something here, Grunt will monitor the change, and then build the front-end code again and inject it into the server. - -59 -00:05:43,710 --> 00:05:47,232 -So the server will serve the updated app for you. - -60 -00:05:47,232 --> 00:05:49,440 -So the other thing we talked about is the user model. - -61 -00:05:49,440 --> 00:05:56,710 -So if you look into the Server folder, you can see it comes with just one model, which is the user. - -62 -00:05:56,710 --> 00:06:03,239 -The user model comes with just the basic things you need, like username, display name, email, [INAUDIBLE], and passwords. - -63 -00:06:03,239 --> 00:06:04,780 -The controllers are also very simple. - -64 -00:06:04,780 --> 00:06:09,550 -Their authentication controller handles all the login stuff that we previously looked at. - -65 -00:06:09,550 --> 00:06:14,400 -There's a feed controller that simply serves the logged in homepage. - -66 -00:06:14,400 --> 00:06:16,670 -There's also a little bonus here. - -67 -00:06:16,670 --> 00:06:18,970 -For real time chatting, there's a Socket.IO set up. - -68 -00:06:18,970 --> 00:06:29,580 -So under Config, there's a little Socket.IO setup where you can then send real time messages back and forth to your clients. - -69 -00:06:29,580 --> 00:06:33,559 -And so this is how I use my common code base to create all these different ideas. - -70 -00:06:33,559 --> 00:06:34,850 -You can check it out on GitHub. - -71 -00:06:34,850 --> 00:06:37,670 -It's on my user name, and then the repo is called emptyApp. - -72 -00:06:37,670 --> 00:06:39,510 -Thanks for watching. +b +1 +00:00:00,000 --> 00:00:04,950 +[MUSIC PLAYING] STEFAN RITTER: Hi guys. + +2 +00:00:04,950 --> 00:00:07,770 +I'm Stefan, and I'm working on multiple projects at the moment. +我叫斯蒂芬,此时我在工作。 + +3 +00:00:07,770 --> 00:00:12,240 +One is buzzr.io, one is fitguru.org, and one is pickfeed.io. + +4 +00:00:12,240 --> 00:00:17,830 +And today I'm going to talk about how I use a common code base to pivot to all these different ideas. + +5 +00:00:17,830 --> 00:00:23,300 +While working on different startup ideas, I quickly realized there are common parts to each idea. +当研究不同的创业想法时,我很快意识到他们有共同的部分。 +6 +00:00:23,300 --> 00:00:29,320 +So I created an abstraction called emptyApp, which combines these five features that I singled out. + +7 +00:00:29,320 --> 00:00:52,720 +The five features are a landing page with an email sign up so you can go online right away and start collecting emails from people who are interested, a client-agnostic API server that doesn't care if the front-end is a web app or a mobile app, and then a front-end app, which for me usually is the web app, since I think the web is the biggest [INAUDIBLE] platform, and then a user model, since you need to save your users. +这五个特性是一个电子邮件注册的网页,这样你就可以立即上网,开始收集感兴趣的人的电子邮件,用一个API服务器(不在乎前端是一个移动web应用程序或应用程序与否),然后前端应用程序,这对我来说通常是web应用程序,因为我觉得网络是最大的[全场寂静]平台,然后一个用户模型,因为您需要保存你的用户。 + +8 +00:00:52,720 --> 00:00:57,560 +And the fifth thing would be a login authentication scheme with Twitter, Facebook, G+, or email. + +9 +00:00:57,560 --> 00:01:02,550 +Let's look at the five features in emptyApp as they come from the repo when your freshly install it. + +10 +00:01:02,550 --> 00:01:12,710 +So this is emptyApp's landing page where you can collect users' email addresses who might be interested until you launch. +所以这是emptyapp着陆页,在这里您可以收集用户的电子邮件地址的人会感兴趣,直到你发射。 + +11 +00:01:12,710 --> 00:01:24,640 +So if you just enter an email address here, you can link it up to a Mailchimp list and collect email addresses that way. +不会翻译 +A +A +A +B +B +B +B +B +B +B +B +B +B +A +A + + +12 +00:01:24,640 --> 00:01:29,530 +But then emptyApp also gives you real login functionality. +但是emptyApp也赋予了你真正的登录功能 + +13 +00:01:29,530 --> 00:01:42,980 +So for example, if we try to log on like this, this user doesn't exist. + +14 +00:01:42,980 --> 00:01:45,660 +So obviously we get an error message. + +15 +00:01:45,660 --> 00:01:56,210 +But then if we go to Join, we can create this user. +(但是如果我们加入,就能创建这个用户.) + +16 +00:01:56,210 --> 00:01:58,340 +And then now you're logged in. + +17 +00:01:58,340 --> 00:02:04,130 +So if we try to go back to the homepage, emptyApp will automatically log you back in. + +18 +00:02:04,130 --> 00:02:06,950 +And you're landing on the logged in home page. + +19 +00:02:06,950 --> 00:02:09,474 +There's also a logged out future. + +20 +00:02:09,474 --> 00:02:13,680 +So you can just log out again, and you're back logged out on the home page. + +21 +00:02:13,680 --> 00:02:18,010 +And then, of course, you can do all this as well with all the social media logins. + +22 +00:02:18,010 --> 00:02:19,426 +So here we have Twitter activated. + +23 +00:02:19,426 --> 00:02:27,857 +And then we log back in. + +24 +00:02:27,857 --> 00:02:30,440 +All right, now I'm going to show you these features in action. +没关系,我现在示范一下。 + +25 +00:02:30,440 --> 00:02:40,450 +So if we go to buzzr.io, you can see when you first land on the app there's a landing page. +所以如果我们去buzzr.io,你可以看到你第一次打开app的页面 + +26 +00:02:40,450 --> 00:02:46,400 +But then over here you see we have links to the Join, links to the Login. + +27 +00:02:46,400 --> 00:02:48,945 +And once we're here, we can log in with our user account. +一旦我们加入,我们可以用自己的用户名登录。 + +28 +00:02:48,945 --> 00:02:58,700 +我们登陆登录使用的主页。 +And we land on the logged in home page. + +29 +00:02:58,700 --> 00:03:02,930 +All right, now let me show you what the emptyApp looks like on GitHub. + +30 +00:03:02,930 --> 00:03:14,862 +So if you go to my username, stefanritter/emptyapp-- so there's a link right here so you can download and clone the app. + +31 +00:03:14,862 --> 00:03:17,070 +There are little instructions on how to do the setup. +这里有一些如何安装的说明。 + +32 +00:03:17,070 --> 00:03:25,920 +So it comes with a Grunt file, as well as scripts to do the testing and a supervisor script to watch for server changes. + +33 +00:03:25,920 --> 00:03:34,930 +So if you download the app, and then you want to start it, what you do is you CD into the emptyApp directory. + +34 +00:03:34,930 --> 00:03:37,960 +And then you just run the start script. +然后你就可以运行你的开始脚本了。 + +35 +00:03:37,960 --> 00:03:43,870 +And what it will do is start all the tests, the Grunt watching. + +36 +00:03:43,870 --> 00:03:52,140 +And from that point on, you can demo the app on your local host. + +37 +00:03:52,140 --> 00:03:56,130 +It's a MongoDB database, so the whole app is written in JavaScript. + +38 +00:03:56,130 --> 00:03:58,460 +All my apps are written 100% in JavaScript. + +39 +00:03:58,460 --> 00:04:03,120 +Because you can use JavaScript on the front-end, on the back-end, as well as to talk to your database. + +40 +00:04:03,120 --> 00:04:05,570 +So there's less mental overhead. + +41 +00:04:05,570 --> 00:04:08,410 +For the database, I use MongoDB. +对于数据库,我使用MongoDB + +42 +00:04:08,410 --> 00:04:16,779 +MongoDB is schemaless, so you can change fields on models very quickly, which is very important when you're pivoting between extreme different ideas. + +43 +00:04:16,779 --> 00:04:20,589 +For the front-end, I use AngularJS, which has awesome dependency injection. + +44 +00:04:20,589 --> 00:04:27,310 +So it's very easy to throw around features within your app-- also, again, important when you're changing and pivoting ideas. +所以抛去特征是非常容易的,后面的不懂了。。。 + +45 +00:04:27,310 --> 00:04:33,870 +And then for the server, I use Happy.js, which is a server built specifically for being an API server. +[zhe ge mei you han yu.] + +46 +00:04:33,870 --> 00:04:38,810 +So it's very great to be a front-end-agnostic server back-end. + +47 +00:04:38,810 --> 00:04:39,860 +This is the Grunt task. +这是Grunt的任务。 + +48 +00:04:39,860 --> 00:04:46,610 +The Grunt task just watches for file changes and checks the code and tells you if something's wrong and runs all your tests. +我看不懂,不会翻译。 + +49 +00:04:46,610 --> 00:04:51,710 +This is the Karma tab, which runs all the front-end tasks. +这是Karma标签,它执行所有的前置任务. + +50 +00:04:51,710 --> 00:04:57,970 +And then this is the Server tab, which watches for changes in server code and restarts the server if it finds any. +然后,这是....不懂了 + +51 +00:04:57,970 --> 00:05:01,870 +This is what the folder structure looks like of the code. + +52 +00:05:01,870 --> 00:05:04,364 +There are three main folders for you to watch out for. + +53 +00:05:04,364 --> 00:05:07,870 +There is the Client folder, the Server folder, and the Test folder. + +54 +00:05:07,870 --> 00:05:11,187 +It's quite self explanatory what each includes. + +55 +00:05:11,187 --> 00:05:15,270 +But it's important to point out that the client and the server are completely separate. + +56 +00:05:15,270 --> 00:05:23,085 +So this is the client-agnostic API server I talked about previously where the client could be, in this case, an AngularJS app. +所以这是客户无关的API服务器我谈到以前在客户的可能,在这种情况下,一个AngularJS应用。 + +57 +00:05:23,085 --> 00:05:29,330 +But it could also just be an iOS app or an Android app that talks to your server. +但是只有在ios或Android系统上与你的服务器相交互 + +58 +00:05:29,330 --> 00:05:43,710 +And so what happens is if you change something here, Grunt will monitor the change, and then build the front-end code again and inject it into the server. +所以如果你改动了这儿的什么,Grunt会监视变动,然后重建前端代码,把它添加到服务器里。 + +59 +00:05:43,710 --> 00:05:47,232 +So the server will serve the updated app for you. + +60 +00:05:47,232 --> 00:05:49,440 +So the other thing we talked about is the user model. + +61 +00:05:49,440 --> 00:05:56,710 +So if you look into the Server folder, you can see it comes with just one model, which is the user. +所以如果你看看服务器文件夹,你可以看到它只是一个模型,这是用户的。 + +62 +00:05:56,710 --> 00:06:03,239 +The user model comes with just the basic things you need, like username, display name, email, [INAUDIBLE], and passwords. + +63 +00:06:03,239 --> 00:06:04,780 +The controllers are also very simple. + +64 +00:06:04,780 --> 00:06:09,550 +Their authentication controller handles all the login stuff that we previously looked at. +在他们的身份验证控制器处理完所以东西之前,我们就看着。 + +65 +00:06:09,550 --> 00:06:14,400 +There's a feed controller that simply serves the logged in homepage. + +66 +00:06:14,400 --> 00:06:16,670 +There's also a little bonus here. + +67 +00:06:16,670 --> 00:06:18,970 +For real time chatting, there's a Socket.IO set up. + +68 +00:06:18,970 --> 00:06:29,580 +So under Config, there's a little Socket.IO setup where you can then send real time messages back and forth to your clients. + +69 +00:06:29,580 --> 00:06:33,559 +And so this is how I use my common code base to create all these different ideas. + +70 +00:06:33,559 --> 00:06:34,850 +You can check it out on GitHub. + +71 +00:06:34,850 --> 00:06:37,670 +It's on my user name, and then the repo is called emptyApp. + +72 +00:06:37,670 --> 00:06:39,510 +Thanks for watching.