'08.강의수강일지'에 해당되는 글 23건

  1. 2023.01.27 #4주차
  2. 2023.01.27 #4주차 colab사이트에서 github에 저장하기
  3. 2023.01.20 #4주차_5 1
  4. 2023.01.09 1일차
  5. 2023.01.08 #4주차_4
  6. 2023.01.08 #4주차_3 데이터베이스 – 쓰기
  7. 2023.01.07 #4주차_2_서버리스 운영을 위해 파이어베이스 1
  8. 2023.01.06 #4주차_1_API호출
  9. 2023.01.06 #3주차_2
  10. 2023.01.05 #3주차_1
  11. 2022.12.30 #2주차 강의 1
  12. 2022.12.30 #4주차
  13. 2022.12.30 #2주차
  14. 2022.12.30 #2주차
  15. 2022.12.29 #2주차_3
  16. 2022.12.28 #2주차_2 1
  17. 2022.12.28 #2주차_1
  18. 2022.12.26 #1주차
  19. 2022.12.26 #3주차 강의
  20. 2022.12.23 #2주차 강의

스파르타코딩클럽_직장인을_위한_실전_데이터분석___4주차.pdf
2.80MB

 

>>4주차<<

https://colab.research.google.com/drive/169up4Qk7z_g1n-jxwZapjyryScWLg9U6#scrollTo=JdiHTPPIXAbv

 

https://teamsparta.notion.site/_-4-9e244b669ffb40f1a2057fa06ef40df8

 

1. 문제 해결을 위해 가설을 세울 수 있다

2. 가설을 데이터 기반으로 검증 할수 있다.

3. 그래프를 그려 인사이트를 쉽게 찾을 수 있다.

4. 분석한 데이터 결과를 기반으로 의사 결정을 할 수 있다.

 

>>github계정연결<<

1.colab사이트에서 github계정연결을 한다.

2.github.comColab.ipynb 저장소를 README.md 파일과 함께 생성

3.Colab에서 파일 > github에 사본저장으로 저장하여 반영한다.

4.깃저장소에 데이터파일 업로드를 할 때 세션이 사라지면 데이터도 삭제된다.

세션별로 다시 업로드해야한다.

 

# 한글폰트 설치 : 런타임에서 재실행을 해야 적용된다.

!sudo apt-get install -y fonts-nanum

!sudo fc-cache -fv

!rm ~/.cache/matplotlib rf

 

 

 

'08.강의수강일지 > 03.직장인을 위한 실전 데이터 분석' 카테고리의 다른 글

#4주차 colab사이트에서 github에 저장하기  (0) 2023.01.27
#2주차  (0) 2022.12.30
#2주차  (0) 2022.12.30
#1주차  (0) 2022.12.26
Posted by 봄날의차

1.colab사이트에서 github계정연결을 한다.

2.github.comColab.ipynb 저장소를 README.md 파일과 함께 생성

3.Colab에서 파일 > github에 사본저장으로 저장하여 반영한다.

4.깃저장소에 데이터파일 업로드를 할 때 세션이 사라지면 데이터도 삭제된다.

세션별로 다시 업로드해야한다.

 

# 한글폰트 설치 : 런타임에서 재실행을 해야 적용된다.

!sudo apt-get install -y fonts-nanum

!sudo fc-cache -fv

!rm ~/.cache/matplotlib rf

 

 

'08.강의수강일지 > 03.직장인을 위한 실전 데이터 분석' 카테고리의 다른 글

#4주차  (0) 2023.01.27
#2주차  (0) 2022.12.30
#2주차  (0) 2022.12.30
#1주차  (0) 2022.12.26
Posted by 봄날의차

애드몹 설치후 소스에 적용에는 실패했다.

그래서 애드몹설치 후 소스 추가 직전 값에 한해 적용 후 반영하고 마무리 했다.

과제 제출용 ㅜㅜ

 

https://github.com/sensewake/sparta-myhoneytip-yak 

 

애드몹관련

1.설치

2.설정 추가시 관련 파일

MainPage.js

app.json

import React,{useState,useEffect} from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView, Platform} from 'react-native';

const main = 'https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png'
import data from '../data.json';
import Card from '../components/Card';
import Loading from '../components/Loading';
import { StatusBar } from 'expo-status-bar';
import * as Location from "expo-location";
import axios from "axios"
import {firebase_db} from "../firebaseConfig"

// addMob 에러가 나서 주석처리함 
// import {
//   setTestDeviceIDAsync,
//   AdMobBanner,
//   AdmobInterstitial,
//   PublisherBanner,
//   AdmobBanner
// } from 'expo-ads-admob' ;

export default function MainPage({navigation,route}) {
  //useState 사용법
	//[state,setState] 에서 state는 이 컴포넌트에서 관리될 상태 데이터를 담고 있는 변수
  //setState는 state를 변경시킬때 사용해야하는 함수

  //모두 다 useState가 선물해줌
  //useState()안에 전달되는 값은 state 초기값
  const [state,setState] = useState([])
  const [cateState,setCateState] = useState([])
  //날씨 데이터 상태관리 상태 생성!
  const [weather, setWeather] = useState({
    temp : 0,
    condition : ''
  })

	//하단의 return 문이 실행되어 화면이 그려진다음 실행되는 useEffect 함수
  //내부에서 data.json으로 부터 가져온 데이터를 state 상태에 담고 있음
  const [ready,setReady] = useState(true)

  useEffect(()=>{
    navigation.setOptions({
      title:'나만의 꿀팁'
    })  
		//뒤의 1000 숫자는 1초를 뜻함
    //1초 뒤에 실행되는 코드들이 담겨 있는 함수
    setTimeout(()=>{
        firebase_db.ref('/tip').once('value').then((snapshot) => {
          console.log("파이어베이스에서 데이터 가져왔습니다!!")
          let tip = snapshot.val();
          
          setState(tip)
          setCateState(tip)
          getLocation()
          setReady(false)
        });
        // getLocation()
        // setState(data.tip)
        // setCateState(data.tip)
        // setReady(false)
    },1000)
 
    
  },[])

  const getLocation = async () => {
    //수많은 로직중에 에러가 발생하면
    //해당 에러를 포착하여 로직을 멈추고,에러를 해결하기 위한 catch 영역 로직이 실행
    try {
      //자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await
      await Location.requestForegroundPermissionsAsync();
      const locationData= await Location.getCurrentPositionAsync();
      // console.log(locationData)
      // console.log(locationData['coords']['latitude'])
      // console.log(locationData['coords']['longitude'])
      const latitude = locationData['coords']['latitude']
      const longitude = locationData['coords']['longitude']
      const API_KEY = "cfc258c75e1da2149c33daffd07a911d";
      const result = await axios.get(
        `http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`
      );

      console.log(result);
      const temp = result.data.main.temp; 
      const condition = result.data.weather[0].main  

      //오랜만에 복습해보는 객체 리터럴 방식으로 딕셔너리 구성하기!!
      //잘 기억이 안난다면 1주차 강의 6-5를 다시 복습해보세요!
      setWeather({
        temp,condition
      })

    } catch (error) {
      //혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다
      Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");
    }
  }

  const category = (cate) => {
    if(cate == "전체보기"){
        //전체보기면 원래 꿀팁 데이터를 담고 있는 상태값으로 다시 초기화
        setCateState(state)
    }else{
        setCateState(state.filter((d)=>{
            return d.category == cate
        }))
    }
}

  //data.json 데이터는 state에 담기므로 상태에서 꺼내옴
  // let tip = state.tip;
  let todayWeather = 10 + 17;
  let todayCondition = "흐림"
  //return 구문 밖에서는 슬래시 두개 방식으로 주석
  return ready ? <Loading/> :  (
    /*
      return 구문 안에서는 {슬래시 + * 방식으로 주석
    */

    <ScrollView style={styles.container}>
      <StatusBar style="light" />
      {/* <Text style={styles.title}>나만의 꿀팁</Text> */}
      <Text style={styles.weather}>오늘의 날씨: {weather.temp + '°C   ' + weather.condition} </Text>
       <TouchableOpacity style={styles.aboutButton} onPress={()=>{navigation.navigate('AboutPage')}}>
          <Text style={styles.aboutButtonText}>소개 페이지</Text>
        </TouchableOpacity>
      <Image style={styles.mainImage} source={{uri:main}}/>
      <ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>
      <TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('전체보기')}}><Text style={styles.middleButtonTextAll}>전체보기</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton01} onPress={()=>{category('생활')}}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton02} onPress={()=>{category('재테크')}}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton03} onPress={()=>{category('반려견')}}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton04} onPress={()=>{navigation.navigate('LikePage')}}><Text style={styles.middleButtonText}>꿀팁 찜</Text></TouchableOpacity>
      </ScrollView>
      <View style={styles.cardContainer}>
         {/* 하나의 카드 영역을 나타내는 View */}
         {
          cateState.map((content,i)=>{
            return (<Card content={content} key={i} navigation={navigation}/>)
          })
        }        
      </View>
      {/* addMob 에러가 나서 주석처리함 
        ios : ca-app-pub-5469890461499544/4062593422
        android : ca-app-pub-5469890461499544/6195626693
      */}
      {
      /* addMob 에러가 나서 주석처리함 
        Platform.OS === 'ios' ? (
                <AdMobBanner
                  bannerSize="fullBanner" 
                  servePersonalizedAds={true}
                  adUnitID="ca-app-pub-5469890461499544/4062593422" 
                  style={styles.banner}
                />
            ):(
                <AdMobBanner
                  bannerSize="fullBanner" 
                  servePersonalizedAds={true}
                  adUnitID="ca-app-pub-5469890461499544/6195626693" 
                  style={styles.banner}
                />
            )
      */
      }   
    </ScrollView>)
}

const styles = StyleSheet.create({
  container: {
    //앱의 배경 색
    backgroundColor: '#fff',
  },
  title: {
    //폰트 사이즈
    fontSize: 20,
    //폰트 두께
    fontWeight: '700',
    //위 공간으로 부터 이격
    marginTop:50,
    //왼쪽 공간으로 부터 이격
    marginLeft:20
  },
weather:{
    alignSelf:"flex-end",
    paddingRight:20
  },
  mainImage: {
    //컨텐츠의 넓이 값
    width:'90%',
    //컨텐츠의 높이 값
    height:200,
    //컨텐츠의 모서리 구부리기
    borderRadius:10,
    marginTop:20,
    //컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)
    //각 속성의 값들은 공식문서에 고대로~ 나와 있음
    alignSelf:"center"
  },
  middleContainer:{
    marginTop:20,
    marginLeft:10,
    height:60
  },
  middleButtonAll: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#20b2aa",
    borderColor:"deeppink",
    borderRadius:15,
    margin:7
  },
  middleButton01: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#fdc453",
    borderColor:"deeppink",
    borderRadius:15,
    margin:7
  },
  middleButton02: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#fe8d6f",
    borderRadius:15,
    margin:7
  },
  middleButton03: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#9adbc5",
    borderRadius:15,
    margin:7
  },
  middleButton04: {
    width:100,
    height:50,
    padding:15,
    backgroundColor:"#f886a8",
    borderRadius:15,
    margin:7
  },
  middleButtonText: {
    color:"#fff",
    fontWeight:"700",
    //텍스트의 현재 위치에서의 정렬 
    textAlign:"center"
  },
  middleButtonTextAll: {
    color:"#fff",
    fontWeight:"700",
    //텍스트의 현재 위치에서의 정렬 
    textAlign:"center"
  },
  cardContainer: {
    marginTop:10,
    marginLeft:10
  },
  aboutButton: {
    backgroundColor:"pink",
    width:100,
    height:40,
    borderRadius:10,
    alignSelf:"flex-end",
    marginRight:20,
    marginTop:10
  },
  aboutButtonText: {
    color:"#fff",
    textAlign:"center",
    marginTop:10
  },
  banner: {
    width:"100%",
    height:100
  }


});

##app.json

    
    "ios": {
      "supportsTablet": true, 
      "buildNumber": "1.0.0",
      "bundleIdentifier": "com.myhoneytip.yak", 
      "config": {
        "googleMobileAdsAppId": "ca-app-pub-5469890461499544/4062593422" 
      }
    },
    "android": {
      "package": "com.myhoneytip.yak", 
      "versionCode": 1,
      "config": {
        "googleMobileAdsAppId": "ca-app-pub-5469890461499544/6195626693" 
      }
    },

{
  "expo": {
    "name": "sparta-myhoneytip-yak",
    "slug": "sparta-myhoneytip-yak",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],    
    "web": {
      "favicon": "./assets/favicon.png"
    },
    "ios": {
      "supportsTablet": true 
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      }
    },    
    "plugins": [
      "expo-build-properties"
    ],
    "extra": {
      "eas": {
        "projectId": "a8adca49-bd03-4e61-acc9-a4b030a97d98"
      }
    }
  }
}

그냥 이대로 반영 후 마무리 했다.

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_4  (0) 2023.01.08
#4주차_3 데이터베이스 – 쓰기  (0) 2023.01.08
#4주차_2_서버리스 운영을 위해 파이어베이스  (1) 2023.01.07
#4주차_1_API호출  (0) 2023.01.06
#3주차_2  (0) 2023.01.06
Posted by 봄날의차

Gmail - [파스-타 전문가 교육] 2023년 파스-타(PaaS-TA) 전문가 1차 교육 대상자로 선정되셨습니다.pdf
0.27MB
2023년 파스-타 전문교육 입과 안내_1차.pdf
0.06MB

 

Posted by 봄날의차

 

1.4주차_3.hwp
0.02MB

ScrollView 에선 alignItems:"center" 라는 스타일을 사용하면 에러가 난다.

12. [파이어베이스] 리얼타임 데이터베이스 쓰기

expo-application 공식문서

https://docs.expo.dev/versions/latest/sdk/application/#api

 

쓰기를 위해 uniqueId를 부여하기 위한 작업...?

expo install expo-application

 

uniqueIdisIOSios, apple인지 종류에 따라 어떻게 변하는 지 확인한다.

>> 소스 <<

import * as Application from 'expo-application';

const isIOS = Platform.OS === 'ios';

 

let uniqueId;

if(isIOS){

let iosId = await Application.getIosIdForVendorAsync();

uniqueId = iosId

}else{

uniqueId = Application.androidId

}

 

console.log(uniqueId)

 

DetailPage.js

#찜하기 함수

const like = async()=>{

// like 방 안에

// 특정 사용자 방안에

// 특정 찜 데이터 아이디 방안에

// 특정 찜 데이터 몽땅 저장!

// 찜 데이터 방 > 사용자 방 > 어떤 찜인지 아이디

let userUniqueId;

if(isIOS){

let iosId = await Application.getIosIdForVendorAsync();

userUniqueId = iosId

}else{

userUniqueId = await Application.androidId

}

console.log(userUniqueId)

//저장을 하는 함수는 firebaseset 함수이다.

firebase_db.ref('/like/'+ userUniqueId +'/'+tip.idx).set(tip, frunction(error){

console.log(error)

Alert.alert("찜 완료!")

});

}

 

 

 

<TouchableOpacity style={styles.button} onPress={()=>like()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

체크 : 목록성일 경우의 찜함수 고민

 

>>찜하기 페이지를 보여주기 위한 선작업<<

StackNavigator.js 에 페이지 추가

<Stack.Screen name="LikePage" component={LikePage}/>

 

>>LikePage.js<< 찜목록 보여주기

 

 

찜삭제

https://firebase.google.com/docs/reference/js/v8/firebase.database.Reference?authuser=2#remove

 

1.LikePage.js에서 페이지상세로 넘길 때 tip, setTip [상태관리함수] 까지 함께 넘겨줘야 해제가 가능하다.

return (

<ScrollView style={styles.container}>

{

tip.map((content,i)=>{

return(<LikeCard key={i} content={content} navigation={navigation} tip={tip} setTip={setTip}/>)

})

}

</ScrollView>

)

2.LikeCard 에서 필요한 데이터를 받아야한다.

export default function LikeCard({content,navigation, tip, setTip}){

import React from 'react';

import {Alert, View, Image, Text, StyleSheet,TouchableOpacity, Platform} from 'react-native'

//찜해제를 위한 추가코드

import {firebase_db} from "../firebaseConfig";

const isIOS = Platform.OS === "ios";

import * as Application from "expo-application";

 

//MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용

export default function LikeCard({content,navigation, tip, setTip}){

 

const detail = ()=>{

navigation.navigate('DetailPage',{idx:content.idx})

}

 

//찜해제를 위한 추가코드

const remove = async(cidx)=> {

let userUniqueId;

if(isIOS){

let iosId = await Application.getIosIdForVendorAsync();

userUniqueId = iosId

}else{

userUniqueId = await Application.androidId

}

 

console.log(userUniqueId)

firebase_db.ref('/like/'+userUniqueId + '/'+cidx).remove().then(function(){

Alert.alert("삭제완료");

//내가 찜 해제 버튼을 누른 카드 idx를 가지고

//찜페이지의 찜데이터를 조회해서

//찜해제를 원하는 카드를 제외한 새로운 찜 데이터(리스트 형태!)를 만든다.

let result = tip.filter((data,i)=>{

return data.idx !== cidx

})

//이렇게 만들었으면!

//LigePage로 부터 넘겨 받은 tip(찜 상태 데이터)

//filter 함수로 새롭게 만든 찜 데이터를 구성한다.

console.log(result)

setTip(result) //상태변경

 

})

}

 

return(

//카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity를 사용

<View style={styles.card}>

<Image style={styles.cardImage} source={{uri:content.image}}/>

<View style={styles.cardText}>

<Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>

<Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>

<Text style={styles.cardDate}>{content.date}</Text>

<View style={styles.buttonGroup}>

<TouchableOpacity style={styles.button} onPress={()=>detail()}><Text style={styles.buttonText}>자세히보기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>remove(content.idx)}><Text style={styles.buttonText}>찜해제</Text></TouchableOpacity>

</View>

</View>

</View>

)

}

 

const styles = StyleSheet.create({

 

card:{

flex:1,

flexDirection:"row",

margin:10,

borderBottomWidth:0.5,

borderBottomColor:"#eee",

paddingBottom:10

},

cardImage: {

flex:1,

width:100,

height:100,

borderRadius:10,

},

cardText: {

flex:2,

flexDirection:"column",

marginLeft:10,

},

cardTitle: {

fontSize:20,

fontWeight:"700"

},

cardDesc: {

fontSize:15

},

cardDate: {

fontSize:10,

color:"#A6A6A6",

},

buttonGroup: {

flexDirection:"row",

},

button:{

width:90,

marginTop:20,

marginRight:10,

marginLeft:10,

padding:10,

borderWidth:1,

borderColor:'deeppink',

borderRadius:7

},

buttonText:{

color:'deeppink',

textAlign:'center'

}

 

});

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_5  (1) 2023.01.20
#4주차_3 데이터베이스 – 쓰기  (0) 2023.01.08
#4주차_2_서버리스 운영을 위해 파이어베이스  (1) 2023.01.07
#4주차_1_API호출  (0) 2023.01.06
#3주차_2  (0) 2023.01.06
Posted by 봄날의차

스파르타코딩클럽_앱개발_종합반_4주차.pdf
16.51MB

 

 

 

ScrollView 에선 alignItems:"center" 라는 스타일을 사용하면 에러가 난다.

 

exp://192.168.0.13:19000 

 

12. [파이어베이스] 리얼타임 데이터베이스 쓰기

firebaseConfig.js 의  데이터 베이스 설정

 

expo-application 공식문서

https://docs.expo.dev/versions/latest/sdk/application/#api

 

쓰기를 위해 uniqueId를 부여하기 위한 작업...?

expo install expo-application

 

uniqueIdisIOSios, apple인지 종류에 따라 어떻게 변하는 지 확인한다.

>> 소스 <<

import * as Application from 'expo-application';

const isIOS = Platform.OS === 'ios';

 

let uniqueId;

if(isIOS){

    let iosId = await Application.getIosIdForVendorAsync();

    uniqueId = iosId

}else{

    uniqueId = Application.androidId

}

 

console.log(uniqueId)

 

#찜하기 함수

const like = async()=>{

    // like 방 안에

    // 특정 사용자 방안에

    // 특정 찜 데이터 아이디 방안에

    // 특정 찜 데이터 몽땅 저장!

    // 찜 데이터 방 > 사용자 방 > 어떤 찜인지 아이디

let userUniqueId;

if(isIOS){

    let iosId = await Application.getIosIdForVendorAsync();

    userUniqueId = iosId

}else{

    userUniqueId = await Application.androidId

}

console.log(userUniqueId)

//저장을 하는 함수는 firebaseset 함수이다.

firebase_db.ref('/like/'+ userUniqueId +'/'+tip.idx).set(tip, frunction(error){

    console.log(error)

    Alert.alert("찜 완료!")

});

}

firebasedatabase >  Realtime Database 에 저장된 값 조회 

 

DetailPage안의 팁 찜하기 버튼에 링크걸기

<TouchableOpacity style={styles.button} onPress={()=>like()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

체크 : 목록성일 경우의 찜함수 고민

 

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_5  (1) 2023.01.20
#4주차_4  (0) 2023.01.08
#4주차_2_서버리스 운영을 위해 파이어베이스  (1) 2023.01.07
#4주차_1_API호출  (0) 2023.01.06
#3주차_2  (0) 2023.01.06
Posted by 봄날의차

>>서버리스 운영을 위해 파이어베이스에 앱 등록<<

1.파이어리스에서 프로젝트 생성

sparta-myhoneytip-yak-b0472

프로젝트 생성

sparta-myhoneytip-yak

 

https://console.firebase.google.com/project/sparta-myhoneytip-yak-b0472/overview?hl=ko

 

신청해 주셔서 감사합니다. 나중에 알림 구독에서 업데이트를 관리할 수 있습니다.

sparta-myhoneytip-yak

앱에 Firebase를 추가하여 시작하기

 

앱 등록 후 로컬에서 파이어베이스와 연결을 위한 작업을 한다.

프로젝트 폴더에서 진행

2.설치

expo install firebase

 

3.firebaseConfig.js 생성

import firebase from "firebase/compat/app";

 

// 사용할 파이어베이스 서비스 주석을 해제합니다 //

//import "firebase/compat/auth";

import "firebase/compat/database";

//import "firebase/compat/firestore";

//import "firebase/compat/functions";

import "firebase/compat/storage";

 

// Initialize Firebase

// 파이어베이스 사이트에서 봤던 연결정보를 여기에 가져옵니다 //연결 key

const firebaseConfig = {

apiKey: "AIzaSyBKG2xY91x23W8PF1231k5OUJ5kHSKYQeNWUw",

authDomain: "sparta-psytest-gun.firebaseapp.com",

databaseURL: "https://sparta-psytest-gun.firebaseio.com",

projectId: "sparta-psytest-gun",

storageBucket: "sparta-psytest-gun.appspot.com",

messagingSenderId: "781790378482",

appId: "1:78179037128482:web:ddbca53309f67b947136b",

measurementId: "G-3F5L9F3340Q3"

};

 

>>왼쪽 메뉴에서 database 생성<<

https://console.firebase.google.com/project/sparta-myhoneytip-yak-b0472/database/sparta-myhoneytip-yak-b0472-default-rtdb/data/~2Ftip~2F3

 

로그인 - Google 계정

이메일 또는 휴대전화

accounts.google.com

//YAK : databaseURL 생성후 추가 

 

const firebaseConfig = {
  apiKey: "AIzaSyAkFWtAPvcajuV2-uiJMo-5lhWsbae91eg",
  authDomain: "sparta-myhoneytip-yak-b0472.firebaseapp.com",
  projectId: "sparta-myhoneytip-yak-b0472",
  databaseURL: "https://sparta-myhoneytip-yak-b0472-default-rtdb.asia-southeast1.firebasedatabase.app/",
  storageBucket: "sparta-myhoneytip-yak-b0472.appspot.com",
  messagingSenderId: "354873355002",
  appId: "1:354873355002:web:c070c149af0798c7b97743",
  measurementId: "G-T14SPVDEXN"

};

//사용 방법입니다.

//파이어베이스 연결에 혹시 오류가 있을 경우를 대비한 코드로 알아두면 됩니다.

if (!firebase.apps.length) {

firebase.initializeApp(firebaseConfig);

}

export const firebase_db = firebase.database()

 

4.Storage

빌드 > Storage 시작

아시아 노스 3? 선택해서 시작함

images 폴더 생성

 

https://console.firebase.google.com/project/sparta-myhoneytip-yak-b0472/storage/sparta-myhoneytip-yak-b0472.appspot.com/files

 

로그인 - Google 계정

이메일 또는 휴대전화

accounts.google.com

 

5.Realtime Database

NoSql

지역을 하나 선택해서 만들기 한다.

생성 후 const firebaseConfig 에 실시간 데이터베이스 생성시의 주소를 추가 한다.

https://sparta-myhoneytip-yak-b0472-default-rtdb.asia-southeast1.firebasedatabase.app/

 

tip이 들어 있는 데이터베이스 주소

https://sparta-myhoneytip-yak-b0472-default-rtdb.asia-southeast1.firebasedatabase.app/tip

 

6.실시간데이터베이스 규칙을 모두 true로 변경해야 공개가된다.

 

>>0107<<

https://console.firebase.google.com/project/sparta-myhoneytip-yak-b0472/database/sparta-myhoneytip-yak-b0472-default-rtdb/data?hl=ko

 

깃 작업 참고

https://nevertrustbrutus.tistory.com/153

 

>>코드 리뷰 <<

1) 상단에서 import data from "../data.json"; 로 필요 데이터를 가져왔습니다.

2)

//꿀팁 데이터를 관리하는 상태입니다.

const [state, setState] = useState([])

//선택한 카테고리에 맞는 문제 데이터를 저장하고 관리하는 상태입니다.

const [cateState, setCateState] = useState([])

: cateState 값이 변경되면 화면이 재로드된다.

3)

useEffect 에서 데이터를 실제 상태관리 하기 시작합니다.

useEffect(()=>{

navigation.setOptions({

title:'나만의 꿀팁'

})

setTimeout(()=>{

getLocation()

setState(tip)

setCateState(tip)

setReady(true)

},1000)

},[])

 

>>리얼 타임 데이터 베이스를 생성하면서 부터 고유한 DB 주소를 갖게됩니다.

디비URL 

https://sparta-myhoneytip.firebaseio.com/

 

위와 같은 주소에 리얼타임 데이터베이스가 생성되었는데요!

이 고유 주소에 tip 이란 방에 꿀팁들이 저장되었습니다

 

https://sparta-myhoneytip.firebaseio.com/tip

 

>>https://sparta-myhoneytip.firebaseio.com/ 과 같은 기본 주소가 생략되어 있습니다.

firebase_db.ref('/tip').once('value').then((snapshot) => {

let tip = snapshot.val();

})

:firebase_db.ref('/tip').once('value').then((snapshot) => {})

 

이 코드는 서버리스를 이용하여 데이터베이스를 조회하기 위해,

파이어베이스 측에서 정해놓은 API 사용방법입니다. 따라서 우린 공식 문서 그대로 사용 방법을 적용해야 합니다.

 

조회한 데이터는 snapshot 부분에 담겨서 {} 내부에서 사용할 수 있는데, 그 중 실제 우리에게 필요한 데이터는 snapshot.val()로 가져와 변수에 담아 사용합니다.

 

>>firebaseConfig.js<<

//외부에서 firebase 데이터를 사용하기 위해 내보내고 있다.

export const firebase_db = firebase.database()

 

>>MainPage.js<<

import {firebase_db} from “../firebaseConfig”

 

firebase_db데이터 조회하기 위해 import 한다.

 

useEffect(()=> 안에서 데이터 호출하는 부분 수정을 할 수 있다.

// getLocation()

// setState(data.tip)

// setCateState(data.tip)

// setReady(false)

==> 이렇게 수정할 수 있다.

==> ref('/tip') :

https://sparta-myhoneytip-yak-b0472-default-rtdb.asia-southeast1.firebasedatabase.app/tip

: snapshot은 일반적으로 데이터 가져올 때 쓰는 변수

 

setTimeout(()=>{

firebase_db.ref('/tip').once('value').then((snapshot) => {

console.log("파이어베이스에서 데이터 가져왔습니다!!")

let tip = snapshot.val();

 

setState(tip)

setCateState(tip)

getLocation()

setReady(false)

});

// getLocation()

// setState(data.tip)

// setCateState(data.tip)

// setReady(false)

},1000)

 

Card.js에서 DetailPage.js 전달 데이터로 idx 넘겨주기

 

>>Card.js<<

import React from 'react';

import {View, Image, Text, StyleSheet,TouchableOpacity} from 'react-native'

 

//MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용

export default function Card({content,navigation}){

return(

//카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity를 사용

<TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage',{idx:content.idx})}}>

<Image style={styles.cardImage} source={{uri:content.image}}/>

<View style={styles.cardText}>

<Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>

<Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>

<Text style={styles.cardDate}>{content.date}</Text>

</View>

</TouchableOpacity>

)

}

const styles = StyleSheet.create({

 

card:{

flex:1,

flexDirection:"row",

margin:10,

borderBottomWidth:0.5,

borderBottomColor:"#eee",

paddingBottom:10

},

cardImage: {

flex:1,

width:100,

height:100,

borderRadius:10,

},

cardText: {

flex:2,

flexDirection:"column",

marginLeft:10,

},

cardTitle: {

fontSize:20,

fontWeight:"700"

},

cardDesc: {

fontSize:15

},

cardDate: {

fontSize:10,

color:"#A6A6A6",

}

});

 

>>DetailPage.js<<

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert,Share } from 'react-native';

import * as Linking from 'expo-linking';

import {firebase_db} from "../firebaseConfig"

 

export default function DetailPage({navigation,route}) {

 

// 데이터 없을 경우의 에러 방지용 데이터 

const [tip, setTip] = useState({

"idx":9,

"category":"재테크",

"title":"렌탈 서비스 금액 비교해보기",

"image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",

"desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 등 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는 분들이 늘어나고 있는데요. 다만, 이런 렌탈 서비스 이용이 하나둘 늘어나다 보면 그 금액은 겉잡을 수 없이 불어나게 됩니다. 특히, 렌탈 서비스는 빌려주는 물건의 관리비용까지 포함된 것이기에 생각만큼 저렴하지 않습니다. 직접 관리하며 사용할 수 있는 물건이 있는지 살펴보고, 렌탈 서비스 항목에서 제외해보세요. 렌탈 비용과 구매 비용, 관리 비용을 여러모로 비교해보고 고민해보는 것이 좋습니다. ",

"date":"2020.09.09"

})

 

useEffect(()=>{

console.log(route)

navigation.setOptions({

title:route.params.title,

headerStyle: {

backgroundColor: '#000',

shadowColor: "#000",

},

headerTintColor: "#fff",

})

//setTip(route.params)

//넘어온 데이터는 route.params에 들어 있습니다.

const { idx } = route.params;

firebase_db.ref('/tip/'+idx).once('value').then((snapshot) => {

let tip = snapshot.val();

setTip(tip)

});

},[])

 

const popup = () => {

Alert.alert("팝업!!")

}

 

const share = () => {

Share.share({

message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,

});

}

 

const link = () => {

Linking.openURL("https://spartacodingclub.kr")

}

return (

// ScrollView에서의 flex 숫자는 의미가 없습니다. 정확히 보여지는 화면을 몇등분 하지 않고

// 화면에 넣은 컨텐츠를 모두 보여주려 스크롤 기능이 존재하기 때문입니다.

// 여기선 내부의 컨텐츠들 영역을 결정짓기 위해서 height 값과 margin,padding 값을 적절히 잘 이용해야 합니다.

<ScrollView style={styles.container}>

<Image style={styles.image} source={{uri:tip.image}}/>

<View style={styles.textContainer}>

<Text style={styles.title}>{tip.title}</Text>

<Text style={styles.desc}>{tip.desc}</Text>

<View style={styles.buttonGroup}>

<TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>share()}><Text style={styles.buttonText}>팁 공유하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>link()}><Text style={styles.buttonText}>외부 링크</Text></TouchableOpacity>

</View>

 

</View>

 

</ScrollView>

 

)

}

 

const styles = StyleSheet.create({

container:{

backgroundColor:"#000"

},

image:{

height:400,

margin:10,

marginTop:40,

borderRadius:20

},

textContainer:{

padding:20,

justifyContent:'center',

alignItems:'center'

},

title: {

fontSize:20,

fontWeight:'700',

color:"#eee"

},

desc:{

marginTop:10,

color:"#eee"

},

buttonGroup: {

flexDirection:"row",

},

button:{

width:90,

marginTop:20,

marginRight:10,

marginLeft:10,

padding:10,

borderWidth:1,

borderColor:'deeppink',

borderRadius:7

},

buttonText:{

color:'#fff',

textAlign:'center'

}

})

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_4  (0) 2023.01.08
#4주차_3 데이터베이스 – 쓰기  (0) 2023.01.08
#4주차_1_API호출  (0) 2023.01.06
#3주차_2  (0) 2023.01.06
#3주차_1  (0) 2023.01.05
Posted by 봄날의차

스파르타코딩클럽_앱개발_종합반_4주차.pdf
14.92MB

>>API이용유형<<

1.주소,도메인을이용해서 API 호출

2.서버가 만들어 놓은 도구, 함수를 통해서 API호출 하고 값을 받는 방법

 

날씨API

https://openweathermap.org/api

 

Expo에선 역시나 그렇듯 쉽게 현재 위치 데이터를 얻게 해주는 도구를 제공

공식문서 : https://docs.expo.dev/versions/latest/sdk/location/

 

1.위치 데이터를 얻게 해주는 도구 설치

C:\Users\user\OneDrive\바탕화면\01.sparta_study\sparta-myhoneytip-yak

설치

expo install expo-location

 

2.MainPage

1) lib 추가

import * as Location from "expo-location";

2) 함수 호출

useEffect(()=>{

getLocation

})

3) 함수 정의

const getLocation = async () => {

//수많은 로직중에 에러가 발생하면

//해당 에러를 포착하여 로직을 멈추고,에러를 해결하기 위한 catch 영역 로직이 실행

try {

//자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await

await Location.requestForegroundPermissionsAsync();

const locationData= await Location.getCurrentPositionAsync();

console.log(locationData)

 

} catch (error) {

//혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다

Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");

}

}

 

 

 

 

 

# 모든 자바스크립트

npm axios로 검색한다.

모든 자바스크립트 도구들은 npm에 저장되어 있다.

 

1.도메인 형식의 API를 사용을 위한 도구설치

서버가 제공하는 도메인 형식의 API를 사용하려면, 사용을 위한 도구가 필요합니다. 이를 axios 라고 부릅니다.

yarn add axios

 

2.날씨 API가 주는 데이터 : 도메일호출 방식의 API호출이므로 axios를 설치한다.

https://openweathermap.org/current

 

3.MainPage

1)lib 추가

import axios from "axios“

 

2) 함수 호출

무료키 발급받은 것 : API_KEY = "cfc258c75e1da2149c33daffd07a911d";

const getLocation = async () => {

//수많은 로직중에 에러가 발생하면

//해당 에러를 포착하여 로직을 멈추고,에러를 해결하기 위한 catch 영역 로직이 실행

try {

//자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await

await Location.requestForegroundPermissionsAsync();

const locationData= await Location.getCurrentPositionAsync();

console.log(locationData)

console.log(locationData['coords']['latitude'])

console.log(locationData['coords']['longitude'])

const latitude = locationData['coords']['latitude']

const longitude = locationData['coords']['longitude']

const API_KEY = "cfc258c75e1da2149c33daffd07a911d";

const result = await axios.get(

`http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`

);

 

console.log(result)

 

} catch (error) {

//혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다

Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");

}

}

 

await : 순수대로 실행하라는 의미

get : 스트링으로 값을 받아온다.

 

import axios from "axios“

....

try {

//자바스크립트 함수의 실행순서를 고정하기 위해 쓰는 async,await

await Location.requestForegroundPermissionsAsync();

const locationData= await Location.getCurrentPositionAsync();

console.log(locationData)

console.log(locationData['coords']['latitude'])

console.log(locationData['coords']['longitude'])

const latitude = locationData['coords']['latitude']

const longitude = locationData['coords']['longitude']

const API_KEY = "cfc258c75e1da2149c33daffd07a911d";

const result = await axios.get(

`http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`

);

 

console.log(result)

const temp = result.data.main.temp;

const condition = result.data.weather[0].main

 

console.log(temp)

console.log(condition)

 

//오랜만에 복습해보는 객체 리터럴 방식으로 딕셔너리 구성하기!!

//잘 기억이 안난다면 1주차 강의 6-5를 다시 복습해보세요!

setWeather({

temp,condition

})

 

} catch (error) {

//혹시나 위치를 못가져올 경우를 대비해서, 안내를 준비합니다

Alert.alert("위치를 찾을 수가 없습니다.", "앱을 껏다 켜볼까요?");

}

}

....

<Text style={styles.weather}>오늘의 날씨: {weather.temp + '°C ' + weather.condition} </Text>

>>날씨 API 조회<<

1)lib 추가

import axios from "axios“

 

2) //날씨 데이터 상태관리 상태 생성!

const [weather, setWeather] = useState({

temp : 0,

condition : ''

})

 

3) API 호출 및 상태관리

await Location.requestForegroundPermissionsAsync();

const locationData= await Location.getCurrentPositionAsync();

 

const latitude = locationData['coords']['latitude']

const longitude = locationData['coords']['longitude']

const API_KEY = "cfc258c75e1da2149c33daffd07a911d";

const result = await axios.get(

`http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${API_KEY}&units=metric`

);

 

const temp = result.data.main.temp;

const condition = result.data.weather[0].main

 

setWeather({

temp,condition

})

 

4) 페이지에 뿌려주기

<Text style={styles.weather}>오늘의 날씨: {weather.temp + '°C ' + weather.condition} </Text>

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_3 데이터베이스 – 쓰기  (0) 2023.01.08
#4주차_2_서버리스 운영을 위해 파이어베이스  (1) 2023.01.07
#3주차_2  (0) 2023.01.06
#3주차_1  (0) 2023.01.05
#2주차 강의  (1) 2022.12.30
Posted by 봄날의차

페이지 이동하기

MainPage.js에서 카드버튼을 누르면 Card.js 꿀팁 상세 페이지 DetailPage.js로 이동

Stack.screen에 등록된 모든 페이지 컴포넌트들은 navigationroute라는 딕셔너리(객체)를 속성으로 넘겨받아 사용할 수 있다.

 

//navigation 객체가 가지고 있는 두 함수(setOptionsnavigate)

//해당 페이지의 제목을 설정할 수 있음

navigation.setOptions({

title:'나만의 꿀팁'

})

//Stack.screen에서 name 속성으로 정해준 이름을 지정해주면 해당 페이지로 이동하는 함수

navigation.navigate("DetailPage")

 

//name 속성을 전달해주고, 두 번째 인자로 딕셔너리 데이터를 전달해주면, Detail 페이지에서

//두번째 인자로 전달된 딕셔너리 데이터를 route 딕셔너리로 로 받을 수 있음

navigation.navigate("DetailPage",{

title: title

})

//전달받은 데이터를 받는 route 딕셔너리

//비구조 할당 방식으로 routeparams 객체 키로 연결되어 전달되는 데이터를 꺼내 사용

//navigate 함수로 전달되는 딕셔너리 데이터는 다음과 같은 모습이기 때문입니다.

/*

{

route : {

params :{

title:title

}

}

}

*/

const { title} = route.params;

 

- 비구조할당방식

title에 데이터 할당 : route.params

navigate(“”,{title:title[route.params지정]})

 

 

1.MainPage.js

 

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

 

const main = 'https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png'

import data from '../data.json';

import Card from '../components/Card';

import Loading from '../components/Loading';

import { StatusBar } from 'expo-status-bar';

 

 

/*

MainPage()

MainPage({navigation,route})

-StackNavigator.js 에서 <Stack.Screen name="MainPage" component={MainPage}/> 식으로 정의해서 할당한다.

: Stack.Screen 에서 컴포넌트화 되면서 navigation route를 사용할 수 있게 된다.

MainPage안에서 비구조 할당방식으로 navigation route를 바로 받아서 사용할 수 있다.

MainPage({navigation,route})

*/

export default function MainPage({navigation,route}) {

//useState 사용법

//[state,setState] 에서 state는 이 컴포넌트에서 관리될 상태 데이터를 담고 있는 변수

//setStatestate를 변경시킬때 사용해야하는 함수

 

//모두 다 useState가 선물해줌

//useState()안에 전달되는 값은 state 초기값

const [state,setState] = useState([])

const [cateState,setCateState] = useState([])

 

//하단의 return 문이 실행되어 화면이 그려진다음 실행되는 useEffect 함수

//화면실행 후 가장 먼저 실행될 코드를 정의한다.

//내부에서 data.json으로 부터 가져온 데이터를 state 상태에 담고 있음

const [ready,setReady] = useState(true)

 

useEffect(()=>{

 

//뒤의 1000 숫자는 1초를 뜻함

//1초 뒤에 실행되는 코드들이 담겨 있는 함수

setTimeout(()=>{

//헤더의 타이틀 변경

navigation.setOptions({

title:'나만의 꿀팁'

})

setState(data.tip)

setCateState(data.tip)

setReady(false)

},1000)

 

 

},[])

 

const category = (cate) => {

if(cate == "전체보기"){

//전체보기면 원래 꿀팁 데이터를 담고 있는 상태값으로 다시 초기화

setCateState(state)

}else{

setCateState(state.filter((d)=>{

return d.category == cate

}))

}

}

 

//data.json 데이터는 state에 담기므로 상태에서 꺼내옴

// let tip = state.tip;

let todayWeather = 10 + 17;

let todayCondition = "흐림"

//return 구문 밖에서는 슬래시 두개 방식으로 주석

return ready ? <Loading/> : (

/*

return 구문 안에서는 {슬래시 + * 방식으로 주석

*/

 

<ScrollView style={styles.container}>

<StatusBar style="light" />

{/* <Text style={styles.title}>나만의 꿀팁</Text> */}

<Text style={styles.weather}>오늘의 날씨: {todayWeather + '°C ' + todayCondition} </Text>

<Image style={styles.mainImage} source={{uri:main}}/>

<ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>

<TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('전체보기')}}><Text style={styles.middleButtonTextAll}>전체보기</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton01} onPress={()=>{category('생활')}}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton02} onPress={()=>{category('재테크')}}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton03} onPress={()=>{category('반려견')}}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton04} onPress={()=>{category('꿀팁 찜')}}><Text style={styles.middleButtonText}>꿀팁 찜</Text></TouchableOpacity>

</ScrollView>

<View style={styles.cardContainer}>

{/* 하나의 카드 영역을 나타내는 View */}

{

cateState.map((content,i)=>{

return (<Card content={content} key={i} navigation={navigation}/>)

})

}

 

</View>

 

</ScrollView>)

}

 

const styles = StyleSheet.create({

container: {

//앱의 배경 색

backgroundColor: '#fff',

},

title: {

//폰트 사이즈

fontSize: 20,

//폰트 두께

fontWeight: '700',

//위 공간으로 부터 이격

marginTop:50,

//왼쪽 공간으로 부터 이격

marginLeft:20

},

weather:{

alignSelf:"flex-end",

paddingRight:20

},

mainImage: {

//컨텐츠의 넓이 값

width:'90%',

//컨텐츠의 높이 값

height:200,

//컨텐츠의 모서리 구부리기

borderRadius:10,

marginTop:20,

//컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)

//각 속성의 값들은 공식문서에 고대로~ 나와 있음

alignSelf:"center"

},

middleContainer:{

marginTop:20,

marginLeft:10,

height:60

},

middleButtonAll: {

width:100,

height:50,

padding:15,

backgroundColor:"#20b2aa",

borderColor:"deeppink",

borderRadius:15,

margin:7

},

middleButton01: {

width:100,

height:50,

padding:15,

backgroundColor:"#fdc453",

borderColor:"deeppink",

borderRadius:15,

margin:7

},

middleButton02: {

width:100,

height:50,

padding:15,

backgroundColor:"#fe8d6f",

borderRadius:15,

margin:7

},

middleButton03: {

width:100,

height:50,

padding:15,

backgroundColor:"#9adbc5",

borderRadius:15,

margin:7

},

middleButton04: {

width:100,

height:50,

padding:15,

backgroundColor:"#f886a8",

borderRadius:15,

margin:7

},

middleButtonText: {

color:"#fff",

fontWeight:"700",

//텍스트의 현재 위치에서의 정렬

textAlign:"center"

},

middleButtonTextAll: {

color:"#fff",

fontWeight:"700",

//텍스트의 현재 위치에서의 정렬

textAlign:"center"

},

cardContainer: {

marginTop:10,

marginLeft:10

},

 

 

});

 

2.Card.js

 

import React from 'react';

import {View, Image, Text, StyleSheet,TouchableOpacity} from 'react-native'

 

//MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용

export default function Card({content,navigation}){

return(

//카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity를 사용

<TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage')}}>

<Image style={styles.cardImage} source={{uri:content.image}}/>

<View style={styles.cardText}>

<Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>

<Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>

<Text style={styles.cardDate}>{content.date}</Text>

</View>

</TouchableOpacity>

)

}

 

 

const styles = StyleSheet.create({

 

card:{

flex:1,

flexDirection:"row",

margin:10,

borderBottomWidth:0.5,

borderBottomColor:"#eee",

paddingBottom:10

},

cardImage: {

flex:1,

width:100,

height:100,

borderRadius:10,

},

cardText: {

flex:2,

flexDirection:"column",

marginLeft:10,

},

cardTitle: {

fontSize:20,

fontWeight:"700"

},

cardDesc: {

fontSize:15

},

cardDate: {

fontSize:10,

color:"#A6A6A6",

}

});

 

3.DetailPage.js

 

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert } from 'react-native';

 

export default function DetailPage({navigation,route}) {

 

//초기 컴포넌트의 상태값을 설정

//state, setState 뿐 아니라 이름을 마음대로 지정할 수 있음!

const [tip, setTip] = useState({

"idx":9,

"category":"재테크",

"title":"렌탈 서비스 금액 비교해보기",

"image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",

"desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 등 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는 분들이 늘어나고 있는데요. 다만, 이런 렌탈 서비스 이용이 하나둘 늘어나다 보면 그 금액은 겉잡을 수 없이 불어나게 됩니다. 특히, 렌탈 서비스는 빌려주는 물건의 관리비용까지 포함된 것이기에 생각만큼 저렴하지 않습니다. 직접 관리하며 사용할 수 있는 물건이 있는지 살펴보고, 렌탈 서비스 항목에서 제외해보세요. 렌탈 비용과 구매 비용, 관리 비용을 여러모로 비교해보고 고민해보는 것이 좋습니다. ",

"date":"2020.09.09"

})

 

useEffect(()=>{

console.log(route)

 

//Card.js에서 navigation.navigate 함수를 쓸때 두번째 인자로 content를 넘겨줬죠?

//content는 딕셔너리 그 자체였으므로 route.params에 고대~로 남겨옵니다.

//, route.params content!

 

navigation.setOptions({

//setOptions로 페이지 타이틀도 지정 가능하고

title:route.params.title,

//StackNavigator에서 작성했던 옵션을 다시 수정할 수도 있습니다.

headerStyle: {

backgroundColor: '#000',

shadowColor: "#000",

},

headerTintColor: "#fff",

})

setTip(route.params)

},[])

 

const popup = () => {

Alert.alert("팝업!!")

}

return (

// ScrollView에서의 flex 숫자는 의미가 없습니다. 정확히 보여지는 화면을 몇등분 하지 않고

// 화면에 넣은 컨텐츠를 모두 보여주려 스크롤 기능이 존재하기 때문입니다.

// 여기선 내부의 컨텐츠들 영역을 결정짓기 위해서 height 값과 margin,padding 값을 적절히 잘 이용해야 합니다.

<ScrollView style={styles.container}>

<Image style={styles.image} source={{uri:tip.image}}/>

<View style={styles.textContainer}>

<Text style={styles.title}>{tip.title}</Text>

<Text style={styles.desc}>{tip.desc}</Text>

<TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

</View>

 

</ScrollView>

 

)

}

 

const styles = StyleSheet.create({

container:{

backgroundColor:"#000"

},

image:{

height:400,

margin:10,

marginTop:40,

borderRadius:20

},

textContainer:{

padding:20,

justifyContent:'center',

alignItems:'center'

},

title: {

fontSize:20,

fontWeight:'700',

color:"#eee"

},

desc:{

marginTop:10,

color:"#eee"

},

button:{

width:100,

marginTop:20,

padding:10,

borderWidth:1,

borderColor:'deeppink',

borderRadius:7

},

buttonText:{

color:'#fff',

textAlign:'center'

}

})

 

 

>> 페이지 이동 <<

1.데이터 가지고 페이지 이동하기

버튼 카드에서 사용한 함수에 두 번째 인자로 딕셔너리를 넘겨주면, 이동한 페이지에서 넘겨준 데이터를 받을 수 있다.

 

// 딕셔너리로 정의되어 여러 페이지를 정의한다.

navigation.navigate(“Detail”, {

title:title

})

 

2.card.js : Card에서 DetailPage로 이동할 때, MainPage로부터 넘겨받은 content도 넘길 수 있다.

: 함수 및 데이터 할당

 

import React from 'react';

import {View, Image, Text, StyleSheet,TouchableOpacity} from 'react-native'

 

//MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용

export default function Card({content,navigation}){

return(

//카드 자체가 버튼역할로써 누르게되면 상세페이지로 넘어가게끔 TouchableOpacity를 사용

<TouchableOpacity style={styles.card} onPress={()=>{navigation.navigate('DetailPage',content)}}>

<Image style={styles.cardImage} source={{uri:content.image}}/>

<View style={styles.cardText}>

<Text style={styles.cardTitle} numberOfLines={1}>{content.title}</Text>

<Text style={styles.cardDesc} numberOfLines={3}>{content.desc}</Text>

<Text style={styles.cardDate}>{content.date}</Text>

</View>

</TouchableOpacity>

)

}

const styles = StyleSheet.create({

card:{

flex:1,

flexDirection:"row",

margin:10,

borderBottomWidth:0.5,

borderBottomColor:"#eee",

paddingBottom:10

},

cardImage: {

flex:1,

width:100,

height:100,

borderRadius:10,

},

cardText: {

flex:2,

flexDirection:"column",

marginLeft:10,

},

cardTitle: {

fontSize:20,

fontWeight:"700"

},

cardDesc: {

fontSize:15

},

cardDate: {

fontSize:10,

color:"#A6A6A6",

}

});

 

3.DetailPage.js

 

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert } from 'react-native';

 

export default function DetailPage({navigation,route}) {

 

//초기 컴포넌트의 상태값을 설정

//state, setState 뿐 아니라 이름을 마음대로 지정할 수 있음!

const [tip, setTip] = useState({

"idx":9,

"category":"재테크",

"title":"렌탈 서비스 금액 비교해보기",

"image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",

"desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 등 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는

"date":"2020.09.09.“

})

 

 

useEffect(()=>{

console.log(route)

//Card.js에서 navigation.navigate 함수를 쓸때 두번째 인자로 content를 넘겨줬죠?

//content는 딕셔너리 그 자체였으므로 route.params에 고대~로 남겨옵니다.

//, route.params content!

 

navigation.setOptions({

//setOptions로 페이지 타이틀도 지정 가능하고

title:route.params.title,

//StackNavigator에서 작성했던 옵션을 다시 수정할 수도 있습니다.

headerStyle: {

backgroundColor: '#000',

shadowColor: "#000",

},

headerTintColor: "#fff",

})

setTip(route.params)

},[])

 

const popup = () => {

Alert.alert("팝업!!")

}

const share = () => {

Share.share({

message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,

});

}

return (

// ScrollView에서의 flex 숫자는 의미가 없습니다. 정확히 보여지는 화면을 몇등분 하지 않고

// 화면에 넣은 컨텐츠를 모두 보여주려 스크롤 기능이 존재하기 때문입니다.

// 여기선 내부의 컨텐츠들 영역을 결정짓기 위해서 height 값과 margin,padding 값을 적절히 잘 이용해야 합니다.

<ScrollView style={styles.container}>

<Image style={styles.image} source={{uri:tip.image}}/>

<View style={styles.textContainer}>

<Text style={styles.title}>{tip.title}</Text>

<Text style={styles.desc}>{tip.desc}</Text>

<View style={styles.buttonGroup}>

<TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>share()}><Text style={styles.buttonText}>팁 공유하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>link()}><Text style={styles.buttonText}>외부 링크</Text></TouchableOpacity>

</View>

</View>

</ScrollView>

)

}

 

const styles = StyleSheet.create({

container:{

backgroundColor:"#000"

},

image:{

height:400,

margin:10,

marginTop:40,

borderRadius:20

},

textContainer:{

padding:20,

justifyContent:'center',

alignItems:'center'

},

title: {

fontSize:20,

fontWeight:'700',

color:"#eee“

},

desc:{

marginTop:10,

color:"#eee"

},

button:{

width:100,

marginTop:20,

padding:10,

borderWidth:1,

borderColor:'deeppink',

borderRadius:7

},

buttonText:{

color:'#fff',

textAlign:'center'

}

})

 

 

1. DetailPage 컴포넌트가 useState에 들어 있는 데이터 가지고 화면에 그려짐(return 함수실행)

2. 화면에 다 그려진후, useEffect 함수 실행

3. useEffect에서 상태값 변경 이벤트가 실행되면 변경된 데이터 가지고 다시 return 실행

4. 변경된 데이터를 가지고 화면에 DetailPage가 다시 그려짐.

 

리액트 네이티브에서 화면이 변경되는 시점은 컴포넌트의 상태값이 변경될 때이다.

처음에는, 어떠한 데이터를 보여주는 컴포넌트라면, 무조건 초기값을 의미없는 값이더라도 넣고 시작한다!

또는! 우리가 한번 배웠떤 Loading.js를 이용하여 데이터가 준비가 되면 로딩 화면을 치우고, 본 화면을 보여준다

 

 

앱에서 외부 링크를 여는 방법 : 사이트 연결이외에도 전화걸기 등의 기능이 있다.

>>Linking<<

설치 : expo install expo-linking

버튼에 연결 시킨 기능을 통해 외부 링크를 핸드폰에 있는 기본 브라우저로 열어봅니다.

expo 에서 제공해주는 도구를 설치 한다음, 해당 도구를 상단에 가져와 준비해야 합니다

 

import * as Linking from 'expo-linking';

 

 

DetailPage.js

 

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, ScrollView,TouchableOpacity,Alert,Share } from 'react-native';

import * as Linking from 'expo-linking';

export default function DetailPage({navigation,route}) {

const [tip, setTip] = useState({

"idx":9,

"category":"재테크",

"title":"렌탈 서비스 금액 비교해보기",

"image": "https://storage.googleapis.com/sparta-image.appspot.com/lecture/money1.png",

"desc":"요즘은 정수기, 공기 청정기, 자동차나 장난감 등 다양한 대여서비스가 활발합니다. 사는 것보다 경제적이라고 생각해 렌탈 서비스를 이용하는

"date":"2020.09.09.“

})

useEffect(()=>{

console.log(route)

navigation.setOptions({

title:route.params.title,

headerStyle: {

backgroundColor: '#000',

shadowColor: "#000",

},

headerTintColor: "#fff",

})

setTip(route.params)

},[])

const popup = () => {

Alert.alert("팝업!!")

}

const share = () => {

Share.share({

message:`${tip.title} \n\n ${tip.desc} \n\n ${tip.image}`,

});

}

const link = () => {

Linking.openURL("https://spartacodingclub.kr")

}

return (

// ScrollView에서의 flex 숫자는 의미가 없습니다. 정확히 보여지는 화면을 몇등분 하지 않고

// 화면에 넣은 컨텐츠를 모두 보여주려 스크롤 기능이 존재하기 때문입니다.

// 여기선 내부의 컨텐츠들 영역을 결정짓기 위해서 height 값과 margin,padding 값을 적절히 잘 이용해야 합니다.

<ScrollView style={styles.container}>

<Image style={styles.image} source={{uri:tip.image}}/>

<View style={styles.textContainer}>

<Text style={styles.title}>{tip.title}</Text>

<Text style={styles.desc}>{tip.desc}</Text>

<View style={styles.buttonGroup}>

<TouchableOpacity style={styles.button} onPress={()=>popup()}><Text style={styles.buttonText}>팁 찜하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>share()}><Text style={styles.buttonText}>팁 공유하기</Text></TouchableOpacity>

<TouchableOpacity style={styles.button} onPress={()=>link()}><Text style={styles.buttonText}>외부 링크</Text></TouchableOpacity>

</View>

</View>

</ScrollView>

)

}

const styles = StyleSheet.create({

container:{

backgroundColor:"#000"

},

image:{

height:400,

margin:10,

marginTop:40,

borderRadius:20

},

textContainer:{

padding:20,

justifyContent:'center',

alignItems:'center'

},

title: {

fontSize:20,

fontWeight:'700',

color:"#eee"

},

desc:{

marginTop:10,

color:"#eee"

},

buttonGroup: {

flexDirection:"row",

},

button:{

width:90,

marginTop:20,

marginRight:10,

marginLeft:10,

padding:10,

borderWidth:1,

borderColor:'deeppink',

borderRadius:7

},

buttonText:{

color:'#fff',

textAlign:'center'

}

})

>>과제1<<

1.StackNavigator.js

import AboutPage from '../pages/AboutPage';

<Stack.Screen name="AboutPage" component={AboutPage}/> 추가

2.MainPage 에 버튼 추가

<TouchableOpacity style={styles.middleButton05} onPress={()=>{navigation.navigate('AboutPage')}}>

<Text style={styles.middleButtonText}>소개페이지</Text>

</TouchableOpacity>

3.링크연결 : AboutPage

const link = () => {

Linking.openURL("https://sensewake.tistory.com/285")

}

 

<TouchableOpacity style={styles.button} onPress={()=>link()}>

 

>>찜상태<<

Componet 폴더에 LikeCard.js : 데이터베이스 연결전까지

Pages 폴더에 LikePage.js

 

1.StackNavigator.js import, Stack.Screen

import LikePage from '../pages/LikePage';

 

2.LinckedCard.js

/MainPage로 부터 navigation 속성을 전달받아 Card 컴포넌트 안에서 사용

 

3.MainPage 에 버튼 추가

      <ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>
        <TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('전체보기')}}><Text style={styles.middleButtonTextAll}>전체보기</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton01} onPress={()=>{category('생활')}}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton02} onPress={()=>{category('재테크')}}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton03} onPress={()=>{category('반려견')}}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>
        <TouchableOpacity style={styles.middleButton04} onPress={()=>{navigation.navigate('LikePage')}}><Text style={styles.middleButtonText}>꿀팁 찜</Text></TouchableOpacity>
      </ScrollView>

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_2_서버리스 운영을 위해 파이어베이스  (1) 2023.01.07
#4주차_1_API호출  (0) 2023.01.06
#3주차_1  (0) 2023.01.05
#2주차 강의  (1) 2022.12.30
#2주차_3  (0) 2022.12.29
Posted by 봄날의차

스파르타코딩클럽_앱개발_종합반_3주차.zip
0.50MB
스파르타코딩클럽_앱개발_종합반_3주차.z01
19.53MB

리액트 네이티브는 리액트(React.js) 라이브러리 기반으로 만들어진 프레임워크 입니다. 그렇기 때문에

기본적인 구조는 리액트를 닯아 있습니다.

 

1) 컴포넌트(Component) : 정해진 엘리먼트들(요소)을 사용하여 만든 화면의 일부분

2) 상태(State) : 컴포넌트에서 데이터를 유지하고 관리하기 위한 유일한 방법 == 그냥 사용할 데이터!

3) 속성(Props) : 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달하는 방식 == 그냥 데이터 전달!

4) useEffect : 화면에 컴포넌트가 그려지면 처음 실행해야 하는 함수들을 모아두는 곳

 

편집기에서 시작은

 

C:\Users\user\OneDrive\바탕 화면\01.sparta_study\sparta-myhoneytip-yak>expo start

그 안의 프로젝트폴더에서 expo start 로 시작한다.

 

Expo SDK : https://docs.expo.dev/versions/latest/

react-navigation 공식문서 보러가기 : https://reactnavigation.org

 

>>StatusBar<<

1.C:\Users\user\OneDrive\바탕 화면\01.sparta_study\sparta-myhoneytip-yak

프로젝트 폴더안에서 expo 상태 바 설치

expo install expo-status-bar

2.import { StatusBar } from 'expo-status-bar'; 사용할 수 있다.

3.<StatusBar style="light" />

 

 

>>네비게이션<<

1.네비게이션 설치 코드

yarn add @react-navigation/native

1) expo start 상태라고 하면 ctrl+C로 중지시킨 후에

2) 해당 프로젝트 폴더안에서

3) 네비게이션 설치 코드를 실행한다.

yarn add @react-navigation/native

 

2.네비게이션 추가 설치코드

expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view

 

3.설치 : navigation

yarn add @react-navigation/stack

navigation 폴더

StackNavigator.js 생성

 

4.StackNavigator.js 스택 네비게이터

공식문서

https://reactnavigation.org/docs/stack-navigator/

 

스택 네비게이션은 컴포넌트에 페이지 기능을 부여해주고 컴포넌트에서 컴포넌트로 이동, 즉 페이지 이동을 가능하게 해준다.

컴포넌트를 페이지화 시키는 스택 네비게이션은 페이지로 컴포넌트를 감싸 페이지로 만들어 준다.

여러 페이지들을 책갈피 기능을 하는 스택 네비게이터에 등록시켜서 언제든지 페이지 이동이 가능하게 해준다.

페이지 : Stack.Screen

책갈피 : Stack.Navigator

 

적용 순서 1) 사용 준비

 

>>StackNavigator.js<<

// 적용 순서 1) 사용 준비 시작

import React from 'react';

//설치한 스택 네비게이션 라이브러리를 가져옵니다

import { createStackNavigator } from '@react-navigation/stack';

 

//페이지로 만든 컴포넌트들을 불러옵니다

import DetailPage from '../pages/DetailPage';

import MainPage from '../pages/MainPage';

 

//스택 네비게이션 라이브러리가 제공해주는 여러 기능이 담겨있는 객체를 사용합니다

//그래서 이렇게 항상 상단에 선언하고 시작하는게 규칙입니다!

const Stack = createStackNavigator();

// 적용 순서 1) 사용 준비 종료

 

 

// 적용 순서 2) 기본틀 시작

//리액트의 모~든 파일은 컴포넌트라 생각하고

//페이지 기능을 해주는 모든 기능이 담겨 있는 컴포넌트를 만든다 생각하세요!

const StackNavigator = () =>{

return (

/// 페이지 기능이 들어갈 곳

//컴포넌트들을 페이지처럼 여기게끔 해주는 기능을 하는 네비게이터 태그를 선언합니다.

//위에서 선언한 const Stack = createStackNavigator(); Stack 변수에 들어있는 태그를 꺼내 사용합니다.

//Stack.Navigator 태그 내부엔 페이지(화면)를 스타일링 할 수 있는 다양한 옵션들이 담겨 있습니다.

<Stack.Navigator

screenOptions={{

headerStyle: {

backgroundColor: "black",

borderBottomColor: "black",

shadowColor: "black",

height:100

},

headerTintColor: "#FFFFFF",

headerBackTitleVisible: false

}}

>

{/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 이 자체로 이제 페이지 기능을 합니다*/}

<Stack.Screen name="MainPage" component={MainPage}/>

<Stack.Screen name="DetailPage" component={DetailPage}/>

</Stack.Navigator>

)

}

export default StackNavigator;

// 적용 순서 2) 기본틀 종료

 

- StackNavigator에서 변경하는 것을 DetailPage navigation.setOptions({ }) 에서 선언 수정 해서 사용한다.

 

// 적용 순서 3) 스크린 옵션 시작

//컴포넌트들을 페이지처럼 여기게끔 해주는 기능을 하는 네비게이터 태그를 선언합니다.

//위에서 선언한 const Stack = createStackNavigator(); Stack 변수에 들어있는 태그를 꺼내 사용합니다.

//Stack.Navigator 태그 내부엔 페이지(화면)를 스타일링 할 수 있는 다양한 옵션들이 담겨 있습니다.

<Stack.Navigator

screenOptions={{

headerStyle: {

backgroundColor: "black",

borderBottomColor: "black",

shadowColor: "black",

height:100

},

headerTintColor: "#FFFFFF",

headerBackTitleVisible: false

}}

>

 

{/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣는다. 이 자체로 이제 페이지 기능을 한다*/}

<Stack.Screen name="MainPage" component={MainPage}/>

<Stack.Screen name="DetailPage" component={DetailPage}/>

</Stack.Navigator>

// 적용 순서 3) 스크린 옵션 종료

 

// 적용 순서 4) 페이지 연결 시작

{/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 이 자체로 이제 페이지 기능을 합니다*/}

<Stack.Screen name="MainPage" component={MainPage}/>

<Stack.Screen name="DetailPage" component={DetailPage}/>

// 적용 순서 4) 페이지 연결 종료

 

 

5.App.js

: index,html 과 같은 입구 페이지로 이 페이지에서 페이지 분기를 시킨다.

 

import React from 'react';

//이제 모든 페이지 컴포넌트들이 끼워져있는 책갈피를 메인에 둘예정이므로

//컴포넌트를 더이상 불러오지 않아도 됩니다.

// import MainPage from './pages/MainPage';

// import DetailPage from './pages/DetailPage';

import { StatusBar } from 'expo-status-bar';

 

//메인에 세팅할 네비게이션 도구들을 가져옵니다.

import {NavigationContainer} from '@react-navigation/native';

import StackNavigator from './navigation/StackNavigator'

 

export default function App() {

 

console.disableYellowBox = true;

 

return ( // 연결되어 있는 모든 페이지에 설정된다. 상단 상태바의 배경색이 블랙으로 지정된다.

<NavigationContainer>

<StatusBar style="black" />

<StackNavigator/>

</NavigationContainer>);

}

 

6.StackNavigator.js

: 헤더 스타일을 적절히 바꾸기 위해 다음과 같이 옵션 부분의 코드를 수정 한다.

 

import React from 'react';

//설치한 스택 네비게이션 라이브러리를 가져옵니다

import { createStackNavigator } from '@react-navigation/stack';

 

//페이지로 만든 컴포넌트들을 불러옵니다

import DetailPage from '../pages/DetailPage';

import MainPage from '../pages/MainPage';

 

//스택 네비게이션 라이브러리가 제공해주는 여러 기능이 담겨있는 객체를 사용합니다

//그래서 이렇게 항상 상단에 선언하고 시작하는게 규칙입니다!

const Stack = createStackNavigator();

 

 

const StackNavigator = () =>{

return (

 

//컴포넌트들을 페이지처럼 여기게끔 해주는 기능을 하는 네비게이터 태그를 선언합니다.

//위에서 선언한 const Stack = createStackNavigator(); Stack 변수에 들어있는 태그를 꺼내 사용합니다.

//Stack.Navigator 태그 내부엔 페이지(화면)를 스타일링 할 수 있는 다양한 옵션들이 담겨 있습니다.

<Stack.Navigator

screenOptions={{

headerStyle: {

backgroundColor: "white",

borderBottomColor: "white",

shadowColor: "white",

height:100

},

//헤더의 텍스트를 왼쪾에 둘지 가운데에 둘지를 결정

headerTitleAlign:'left',

headerTintColor: "#000",

headerBackTitleVisible: false

}}

>

 

{/* 컴포넌트를 페이지로 만들어주는 엘리먼트에 끼워 넣습니다. 이 자체로 이제 페이지 기능을 합니다*/}

{/* name에 해당 하는 부분이 페이지의 타이틀이 됩니다. */}

<Stack.Screen name="MainPage" component={MainPage}/>

<Stack.Screen name="DetailPage" component={DetailPage}/>

</Stack.Navigator>

)

}

 

export default StackNavigator;

 

 

7.MainPage.js 에서 title 변경 또는 삭제!

 

1.인자 {navigation,route} 추가

export default function MainPage() {

 

2.헤더 타이틀 변경

 

//헤더의 타이틀 변경

navigation.setOptions({

title:'나만의 꿀팁'

})

 

import React,{useState,useEffect} from 'react';

import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

 

const main = 'https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png'

import data from '../data.json';

import Card from '../components/Card';

import Loading from '../components/Loading';

import { StatusBar } from 'expo-status-bar';

export default function MainPage() {

//useState 사용법

//[state,setState] 에서 state는 이 컴포넌트에서 관리될 상태 데이터를 담고 있는 변수

//setStatestate를 변경시킬때 사용해야하는 함수

 

//모두 다 useState가 선물해줌

//useState()안에 전달되는 값은 state 초기값

const [state,setState] = useState([])

const [cateState,setCateState] = useState([])

 

//하단의 return 문이 실행되어 화면이 그려진다음 실행되는 useEffect 함수

//내부에서 data.json으로 부터 가져온 데이터를 state 상태에 담고 있음

const [ready,setReady] = useState(true)

 

useEffect(()=>{

 

//뒤의 1000 숫자는 1초를 뜻함

//1초 뒤에 실행되는 코드들이 담겨 있는 함수

setTimeout(()=>{

setState(data.tip)

setCateState(data.tip)

setReady(false)

},1000)

},[])

 

const category = (cate) => {

if(cate == "전체보기"){

//전체보기면 원래 꿀팁 데이터를 담고 있는 상태값으로 다시 초기화

setCateState(state)

}else{

setCateState(state.filter((d)=>{

return d.category == cate

}))

}

}

 

//data.json 데이터는 state에 담기므로 상태에서 꺼내옴

// let tip = state.tip;

let todayWeather = 10 + 17;

let todayCondition = "흐림"

//return 구문 밖에서는 슬래시 두개 방식으로 주석

return ready ? <Loading/> : (

/*

return 구문 안에서는 {슬래시 + * 방식으로 주석

*/

 

<ScrollView style={styles.container}>

<StatusBar style="light" />

{/* <Text style={styles.title}>나만의 꿀팁</Text> */}

<Text style={styles.weather}>오늘의 날씨: {todayWeather + '°C ' + todayCondition} </Text>

<Image style={styles.mainImage} source={{uri:main}}/>

<ScrollView style={styles.middleContainer} horizontal indicatorStyle={"white"}>

<TouchableOpacity style={styles.middleButtonAll} onPress={()=>{category('전체보기')}}><Text style={styles.middleButtonTextAll}>전체보기</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton01} onPress={()=>{category('생활')}}><Text style={styles.middleButtonText}>생활</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton02} onPress={()=>{category('재테크')}}><Text style={styles.middleButtonText}>재테크</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton03} onPress={()=>{category('반려견')}}><Text style={styles.middleButtonText}>반려견</Text></TouchableOpacity>

<TouchableOpacity style={styles.middleButton04} onPress={()=>{category('꿀팁 찜')}}><Text style={styles.middleButtonText}>꿀팁 찜</Text></TouchableOpacity>

</ScrollView>

<View style={styles.cardContainer}>

{/* 하나의 카드 영역을 나타내는 View */}

{

cateState.map((content,i)=>{

return (<Card content={content} key={i}/>)

})

}

 

</View>

 

</ScrollView>)

}

 

const styles = StyleSheet.create({

container: {

//앱의 배경 색

backgroundColor: '#fff',

},

title: {

//폰트 사이즈

fontSize: 20,

//폰트 두께

fontWeight: '700',

//위 공간으로 부터 이격

marginTop:50,

//왼쪽 공간으로 부터 이격

marginLeft:20

},

weather:{

alignSelf:"flex-end",

paddingRight:20

},

mainImage: {

//컨텐츠의 넓이 값

width:'90%',

//컨텐츠의 높이 값

height:200,

//컨텐츠의 모서리 구부리기

borderRadius:10,

marginTop:20,

//컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)

//각 속성의 값들은 공식문서에 고대로~ 나와 있음

alignSelf:"center"

},

middleContainer:{

marginTop:20,

marginLeft:10,

height:60

},

middleButtonAll: {

width:100,

height:50,

padding:15,

backgroundColor:"#20b2aa",

borderColor:"deeppink",

borderRadius:15,

margin:7

},

middleButton01: {

width:100,

height:50,

padding:15,

backgroundColor:"#fdc453",

borderColor:"deeppink",

borderRadius:15,

margin:7

},

middleButton02: {

width:100,

height:50,

padding:15,

backgroundColor:"#fe8d6f",

borderRadius:15,

margin:7

},

middleButton03: {

width:100,

height:50,

padding:15,

backgroundColor:"#9adbc5",

borderRadius:15,

margin:7

},

middleButton04: {

width:100,

height:50,

padding:15,

backgroundColor:"#f886a8",

borderRadius:15,

margin:7

},

middleButtonText: {

color:"#fff",

fontWeight:"700",

//텍스트의 현재 위치에서의 정렬

textAlign:"center"

},

middleButtonTextAll: {

color:"#fff",

fontWeight:"700",

//텍스트의 현재 위치에서의 정렬

textAlign:"center"

},

cardContainer: {

marginTop:10,

marginLeft:10

},

 

 

});

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#4주차_1_API호출  (0) 2023.01.06
#3주차_2  (0) 2023.01.06
#2주차 강의  (1) 2022.12.30
#2주차_3  (0) 2022.12.29
#2주차_2  (1) 2022.12.28
Posted by 봄날의차

[앱화면만들기]화면을 구성하는 엘리먼트들

view

text

ScrollView

 

StyleSheet, Text, View, Button, Alert, SafeAreaView

-styles.container를 감싸는 View 태그를 SageAreaView로 교체하여 열고 닫아 준다.

상태바 밑으로 화면이 위치한다.

-주석처리시 return 안에서도 {}를 사용한다.

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

 

-함수정의

export default function App() {

//화살표 함수 형식으로 함수를 정의하고

//jSX문법 안에서 사용할 수 있습니다

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

return (

<SafeAreaView style={styles.container}>  

<View style={styles.textContainer}>

<Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text>

{/* 버튼 onPress 속성에 일반 함수를 연결 할 수 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#f194ff"

/*

onPress={function(){

Alert.alert('팝업 알람입니다!!')

}}

*/

onPress={() => {customAlert()}}

/>

{/* ES6 문법으로 배웠던 화살표 함수로 연결 할 수도 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#FF0000"

/*

onPress={()=>{

Alert.alert('팝업 알람입니다!!')

}}*/

onPress={() => {customAlert()}}

/>

</View>

</SafeAreaView>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

},

textContainer: {

height:100,

margin:10,

},

textStyle: {

textAlign:"center"

},

});

 

2.ScrollView

 

3.customFunction

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

 

4.TouchableOpacity : onPress 이벤트 지정 할 수 있는 버튼

함수 호출시 함수명만 지정 한다.

 

return (

<ScrollView style={styles.container}>

<TouchableOpacity style={styles.textContainer} onPress={customAlert}>

<Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다1</Text>

</TouchableOpacity>

</ScrollView>

);

 

# Image

import React from 'react';

import { StyleSheet, Text, View, Image } from 'react-native';

//이렇게 상단에 가져와 사용할 이미지를 불러옵니다

import favicon from "./assets/favicon.png"

export default function App() {

return (

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={favicon}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 repeat | cover | contain

resizeMode={"contain"}

style={styles.imageStyle}

/>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

//혹시 미리 궁금하신 분들을 위해 언급하자면,

//justifyContentalignContent는 영역 안에 있는 콘텐츠들을 정렬합니다

justifyContent:"center",

alignContent:"center"

},

imageStyle: {

width:"100%",

height:"100%",

alignItems:"center",

justifyContent:"center"

}

});

 

 

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다

resizeMode={"cover"}

style={styles.imageStyle}

/>

</View>

 

 

## 01. flex ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

backgroundColor:"yellow"

}

});

 

다시말해 flex는 상대적입니다.

가장 최상위의 container 스타일을 가져가는 View 엘리먼트는 디바이스 전체 화면의 영역을 가져갑니다.

안 쪽의 containerOne 스타일이 부여된 View 엘리먼트는 전체를 3등분한 뒤 1/3을 가져가고 containerTwo 2/3를 가져갑니다.

 

 

## 01. flex justifyContent ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

<View style={styles.innerOne}>

</View>

<View style={styles.innerTwo}>

<Text>!!컨텐츠!!</Text>

</View>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

flexDirection:"row",

backgroundColor:"yellow"

},

innerOne: {

flex:1,

backgroundColor:"blue"

},

innerTwo: { //중복지정시 가장 나중에 지정된 건이 적용된다.

flex:4,

//justifyContent:"flex-start", //

justifyContent:"flex-end", //

//justifyContent:"center", //중간

backgroundColor:"orange"

}

});

 

참고사이트

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fmain.png?alt=media&token=8e5eb78d-19ee-4359-9209-347d125b322c

 

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fpizza.png?alt=media&token=1a099927-d818-45d4-b48a-7906fd0d2ad3

 

https://docs.expo.io/versions/v38.0.0/react-native/text/

 

 

## 

1) Expo 명령어 설치

2) 로컬에 Expo 계정 세팅

3) expo init 명령어로 기본 앱 생성

 

### 작업 후 테스트를 위한 작업

4) expo startExpo 앱 실행 : 터미널에서 실행한다.

5) 휴대폰에 설치한 Expo 클라이언트 앱으로 Expo 앱 실행

 

# numberOfLines #

<View style={styles.cardText}>

<Text style={styles.cardTitle}>먹다 남은 피자를 촉촉하게!</Text>

<Text style={styles.cardDesc} numberOfLines={3}>먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요. 이럴 경우

<Text style={styles.cardDate}>2020.09.09</Text>

</View>

 

텍스트가 영역에 맞게 3줄이 보여진 후 ...이 표시된다.

 

# image #

<Image style={styles.mainImage} source={{uri:main}}/>

 

uri : const main = “” 변수 처리하거나 “https:// ” 로 지정한다.

이미지는 styleswidth height를 지정해야 보여진다.

 

return 구문 안에서는 {슬래시 + * 방식으로 주석

ScrollView horizontal={"true"} : 가로로 스크롤된다.

버튼은 TouchableOpacity 로 구현 한다.

 

{/* 하나의 카드 영역을 나타내는 View */}

{/* numberOfLines={3} : 3 줄이 보여진다. */}

 

이미지는 스타일 속성을 지정해 줘야 보여진다.

<Image style={styles.mainImage} source={{uri:main}}/>

 

mainImage: {

//컨텐츠의 넓이 값

width:'90%',

//컨텐츠의 높이 값

height:200,

// 컨텐츠의 모서리 구부리기

borderRadius:10,

marginTop:20,

//컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)

//각 속성의 값들은 공식문서에 그대로 나와 있음

alignSelf:"center"

},

 

 

TouchableOpacity : 버튼이용태그 

 

## 

1.라이브러리 임포트

import React from 'react';

import main from './assets/main.png';

import { StyleSheet, Text, View, Image, TouchableOpacity, ScrollView} from 'react-native';

 

2.기본골격함수

 

export default function App() {

return ()

 

}

 

const styles = StyleSheet.create({})

 

- ScrollView 안에 ScrollView horizontal={true} 라고 하면 가로 스크롤이 세로 스크롤 영역에 들어오게 된다.

- card 영역

cardContainer

: View

-flex 영역

 

 

3.메인이미지

https://storage.googleapis.com/sparta-image.appspot.com/lecture/main.png

 

4.피자이미지

https://storage.googleapis.com/sparta-image.appspot.com/lecture/pizza.png

 

5.설명 desc

먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요. 이럴 경우 그릇에 물을 받아 전자레인지 안에서 130초에서 2분 정도 함께 돌려주면 촉촉하게 먹을 수 있습니다. 물이 전자레인지 안에서 수증기를 일으키고, 피자에 촉촉함을 더해줍니다.

 

전체적으로 레이어를 결정하는 태그는 View태그 임 text또한 View 태그안에 사용해야 함

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#3주차_2  (0) 2023.01.06
#3주차_1  (0) 2023.01.05
#2주차_3  (0) 2022.12.29
#2주차_2  (1) 2022.12.28
#2주차_1  (0) 2022.12.28
Posted by 봄날의차

내일배움단_엑셀보다_쉬운_SQL_-_4주차.pdf
0.85MB

 

select * from users u 
inner join orders o on u.user_id = o.user_id 
where o.payment_method = 'kakaopay'
;

select * from users u 
where user_id in (
select user_id from orders 
where payment_method = 'kakaopay'
)
;

select user_id from orders 
where payment_method = 'kakaopay'
;

# 평균값을 서브쿼리로 구하기 
 select c.checkin_id, 
c.user_id,
c.likes,
(
select avg(likes) from checkins c2
where user_id = c.user_id 
) as avg_likes_user
from checkins c
;

#from 절에서의 subquery
select pu.user_id, pu.point, a.avg_likes 
  from point_users pu 
inner join (
select user_id, round(avg(likes),1) as avg_likes from checkins 
group by user_id
) a on pu.user_id = a.user_id
;

  select user_id, round(avg(likes),1) as avg_likes 
    from checkins
group by user_id
  ;


#포인트 평균 조건으로 Subquery 연습해보기
select * from point_users pu
where pu.point > (select avg(pu2.point) from point_users pu2)
;

select avg(pu2.point) from point_users pu2
;
 
#이씨 성을 가진 유저의 포인트의 평균보다 큰 유저들의 데이터 추출하기
select * from point_users pu 
where pu.point > (
select round(avg(pu.point), 0) as avgPit from point_users pu 
inner join users u on pu.user_id = u.user_id 
where u.name = '이**'
 )
;

select * from point_users pu 
where pu.point > (
select avg(pu.point) from point_users pu
where user_id in (
select user_id from users where name = '이**'
 )
)
;

#[연습] checkins 테이블에 course_id별 평균 likes수 필드 우측에 붙여보기
select avg(likes) from checkins 
where course_id = '5f0ae408765dae0006002817'
;
select c.checkin_id, c.course_id, c.user_id, c.likes 
     , c2.title, 
   (
   select round(avg(c1.likes),1) from checkins c1
where c1.course_id = c.course_id
) as course_avg
  from checkins c 
 inner join courses c2 on c.course_id = c2.course_id 
;

select * from courses c2 
;

#From 절에 들어가는 Subquery 연습해보기
select c.title, b.cnt_checkins, a.cnt_total
, (b.cnt_checkins/a.cnt_total) as ratio 
from 
(
select course_id, count(*) as cnt_total from orders 
group by course_id
)a
inner join (
select course_id, count(distinct(user_id)) as cnt_checkins from checkins 
group by course_id
)b
on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id

#with절
with table1 as (
select course_id, count(distinct(user_id)) as cnt_checkins from checkins 
group by course_id
), table2 as (
select course_id, count(*) as cnt_total from orders 
group by course_id
)
 select c.title,
a.cnt_checkins,
b.cnt_total,
(a.cnt_checkins/b.cnt_total) as ratio
   from table1 a inner join table2 b on a.course_id = b.course_id 
  inner join courses c on a.course_id = c.course_id
  ;

#07.문자열 
#substring_index
select user_id, email
     , substring_index(email, '@', 1) as txt1 /* @를 기준으로 텍스트를 쪼개고, 그 중 처음 조각 출력 */
     , substring_index(email, '@', -1) as txt2 /* @를 기준으로 텍스트를 쪼개고, 그 중 마지막 조각 출력 */
from users u 
;

select order_no, created_at, substring(created_at,1,10) as date from orders
;
select substring(created_at,1,10) as date, count(*) as cnt_date from orders 
group by date
;

#08.Case 
select pu.point_user_id, pu.point, 
case
when pu.point > 10000 then '잘 하고 있어요!' 
else '조금 더 달려주세요!'
END as '구분'
from point_users pu
;


with table1 as (
select pu.point_user_id, pu.point, 
(case when pu.point > 10000 then '1만 이상' 
  when pu.point > 5000 then '5천 이상' 
  else '5천 미만!'
      END) as lv
from point_users pu
)
select a.lv, count(*) as cnt from table1 a
group by a.lv
;

select a.lv, count(*) as cnt from (
select pu.point_user_id, pu.point, 
(case when pu.point > 10000 then '1만 이상' 
  when pu.point > 5000 then '5천 이상' 
  else '5천 미만!'
      END) as lv
from point_users pu
) a
group by a.lv
;

select pu.point_user_id, pu.point, 
(case when pu.point > 10000 then '1만 이상' 
  when pu.point > 5000 then '5천 이상' 
  else '5천 미만!'
      END) as lv
from point_users pu
;

# 퀴즈 
select pu.user_id, pu.point,
   (case when point > 5000 then '잘 하고 있어요!'
        else '조금 만 더 화이팅!' end
        ) as msg 
  from point_users pu 
;

select pu.user_id, pu.point,
   (case when point > (select avg(point) from point_users pu2) then '잘 하고 있어요!'
        else '조금 만 더 화이팅!' end
        ) as msg 
  from point_users pu 
;

# [퀴즈] 이메일 도메인별 유저의 수 세어보기
select email, SUBSTRING_INDEX(email, '@', -1) as domain 
from users u 
;

select domain, count(*) from (
select email, SUBSTRING_INDEX(email, '@', -1) as domain 
from users u 
) a 
group by domain 
;

# [퀴즈] '화이팅'이 포함된 오늘의 다짐만 출력해보기
select * from checkins c
where comment like '%화이팅%'
;

# [퀴즈] 수강등록정보(enrolled_id)별 전체 강의 수와 들은 강의의 수 출력해보기
select enrolled_id, count(*) as done_cnt from enrolleds_detail
where done=1
group by enrolled_id 
;
select enrolled_id, count(*) as tot_cnt from enrolleds_detail
group by enrolled_id 
;
select a.enrolled_id, a.done_cnt, b.tot_cnt from (
select enrolled_id, count(*) as done_cnt from enrolleds_detail
where done=1
group by enrolled_id 
  ) a inner join (
   select enrolled_id, count(*) as tot_cnt from enrolleds_detail
group by enrolled_id    
  ) b on a.enrolled_id = b.enrolled_id
  ;

with table1 as (
select enrolled_id, count(*) as done_cnt from enrolleds_detail
where done=1
group by enrolled_id 
), table2 as (
   select enrolled_id, count(*) as tot_cnt from enrolleds_detail
group by enrolled_id    
)
select a.enrolled_id, a.done_cnt, b.tot_cnt, round(a.done_cnt/b.tot_cnt, 2) as ratio 
  from table1 a inner join table2 b on a.enrolled_id = b.enrolled_id
  ;
 
select enrolled_id,
   sum(done) as cnt_done,
   count(*) as cnt_total 
from enrolleds_detail ed 
group by enrolled_id
;  
 
  

'08.강의수강일지 > 02.엑셀보다 쉬운, SQL' 카테고리의 다른 글

#3주차 강의  (0) 2022.12.26
#2주차 강의  (0) 2022.12.23
엑셀보다 쉬운 SQL 1주차  (0) 2022.12.21
Posted by 봄날의차

https://colab.research.google.com/drive/11evecIRKCYy8R6m3cHOcIJWqMmXWMIJw#scrollTo=cVZYsBQhEhdN

 

Google Colaboratory Notebook

Run, share, and edit Python notebooks

colab.research.google.com

# 데이터분석 절차
# 1) 문제 정의 및 가설 설정하기  → 2) 데이터 분석 기본 세팅 하기  → 3) 데이터 분석하기  → 4) 분석 결과 시각화 하기  → 5) 최종 결론 내리기
# (1) Pandas 라이브러리 불러오기
# (2) 피마 인디언 당뇨병 파일 불러오기
# (3) 데이터 앞부분 확인 하기
# (4) 데이터가 null인 데이터 출력하기
# (5) 데이터가 null인 데이터 제거 하기
# (6) 상관관계 분석하기
# (7) Outcome 상관관계 계수가 1인 요소 제외하고 출력하기
# (8) matplotlib으로 시각화 하기
# (9) 바 그래프로 변경하기
 
import pandas as pd
diabetes = pd.read_table('diabetes.csv',sep=',')
diabetes.head()
 
print(diabetes.isnull().sum())
dianetes = diabetes.dropna()
corr = dianetes.corr(method='pearson')
corr = corr[corr.Outcome!=1]
corr
import matplotlib.pyplot as plt
corr['Outcome'].plot()
corr['Outcome'].plot.bar()
 
plot = corr['Outcome'].plot.bar()
plot
 
#x축 레이블 45도 회전하기
plot = corr['Outcome'].plot.bar()
plt.xticks(rotation=45)

 

'08.강의수강일지 > 03.직장인을 위한 실전 데이터 분석' 카테고리의 다른 글

#4주차  (0) 2023.01.27
#4주차 colab사이트에서 github에 저장하기  (0) 2023.01.27
#2주차  (0) 2022.12.30
#1주차  (0) 2022.12.26
Posted by 봄날의차

https://colab.research.google.com/drive/11evecIRKCYy8R6m3cHOcIJWqMmXWMIJw#scrollTo=cVZYsBQhEhdN

 

Google Colaboratory Notebook

Run, share, and edit Python notebooks

colab.research.google.com

# 데이터분석 절차
# 1) 문제 정의 및 가설 설정하기  → 2) 데이터 분석 기본 세팅 하기  → 3) 데이터 분석하기  → 4) 분석 결과 시각화 하기  → 5) 최종 결론 내리기
# (1) Pandas 라이브러리 불러오기
# (2) 피마 인디언 당뇨병 파일 불러오기
# (3) 데이터 앞부분 확인 하기
# (4) 데이터가 null인 데이터 출력하기
# (5) 데이터가 null인 데이터 제거 하기
# (6) 상관관계 분석하기
# (7) Outcome 상관관계 계수가 1인 요소 제외하고 출력하기
# (8) matplotlib으로 시각화 하기
# (9) 바 그래프로 변경하기
 
import pandas as pd
diabetes = pd.read_table('diabetes.csv',sep=',')
diabetes.head()
 
print(diabetes.isnull().sum())
dianetes = diabetes.dropna()
corr = dianetes.corr(method='pearson')
corr = corr[corr.Outcome!=1]
corr
import matplotlib.pyplot as plt
corr['Outcome'].plot()
corr['Outcome'].plot.bar()
 
plot = corr['Outcome'].plot.bar()
plot
 
#x축 레이블 45도 회전하기
plot = corr['Outcome'].plot.bar()
plt.xticks(rotation=45)

 

'08.강의수강일지 > 03.직장인을 위한 실전 데이터 분석' 카테고리의 다른 글

#4주차  (0) 2023.01.27
#4주차 colab사이트에서 github에 저장하기  (0) 2023.01.27
#2주차  (0) 2022.12.30
#1주차  (0) 2022.12.26
Posted by 봄날의차

2-4 [앱화면만들기]화면을 구성하는 엘리먼트들

 

view

text

ScrollView

 

StyleSheet, Text, View, Button, Alert, SafeAreaView

 

1.SafeAreaView

 

styles.container를 감싸는 View 태그를 SageAreaView로 교체하여 열고 닫아 준다.

상태바 밑으로 화면이 위치한다.

 

StyleSheet, Text, View, Button, Alert, View

 

 

 

 

주석처리시에도 {}를 사용한다.

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

import React from 'react';

import { StyleSheet, Text, View, Button, Alert, SafeAreaView } from 'react-native';

export default function App() {

//화살표 함수 형식으로 함수를 정의하고

//jSX문법 안에서 사용할 수 있습니다

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

return (

<SafeAreaView style={styles.container}>

<View style={styles.textContainer}>

<Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text>

{/* 버튼 onPress 속성에 일반 함수를 연결 할 수 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#f194ff"

/*

onPress={function(){

Alert.alert('팝업 알람입니다!!')

}}

*/

onPress={() => {customAlert()}}

/>

{/* ES6 문법으로 배웠던 화살표 함수로 연결 할 수도 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#FF0000"

/*

onPress={()=>{

Alert.alert('팝업 알람입니다!!')

}}*/

onPress={() => {customAlert()}}

/>

</View>

</SafeAreaView>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

},

textContainer: {

height:100,

margin:10,

},

textStyle: {

textAlign:"center"

},

});

 

2.ScrollView

 

3.customFunction

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

 

4.TouchableOpacity : onPress 이벤트 지정 할 수 있는 버튼

함수 호출시 함수명만 지정 한다.

 

return (

<ScrollView style={styles.container}>

<TouchableOpacity style={styles.textContainer} onPress={customAlert}>

<Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다1</Text>

</TouchableOpacity>

</ScrollView>

);

 

# Image

import React from 'react';

import { StyleSheet, Text, View, Image } from 'react-native';

//이렇게 상단에 가져와 사용할 이미지를 불러옵니다

import favicon from "./assets/favicon.png"

export default function App() {

return (

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={favicon}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 repeat | cover | contain

resizeMode={"contain"}

style={styles.imageStyle}

/>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

//혹시 미리 궁금하신 분들을 위해 언급하자면,

//justifyContentalignContent는 영역 안에 있는 콘텐츠들을 정렬합니다

justifyContent:"center",

alignContent:"center"

},

imageStyle: {

width:"100%",

height:"100%",

alignItems:"center",

justifyContent:"center"

}

});

 

 

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다

resizeMode={"cover"}

style={styles.imageStyle}

/>

</View>

 

 

## 01. flex ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

backgroundColor:"yellow"

}

});

 

다시말해 flex는 상대적입니다.

가장 최상위의 container 스타일을 가져가는 View 엘리먼트는 디바이스 전체 화면의 영역을 가져갑니다.

안 쪽의 containerOne 스타일이 부여된 View 엘리먼트는 전체를 3등분한 뒤 1/3을 가져가고 containerTwo 2/3를 가져갑니다.

 

 

## 01. flex justifyContent ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

<View style={styles.innerOne}>

</View>

<View style={styles.innerTwo}>

<Text>!!컨텐츠!!</Text>

</View>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

flexDirection:"row",

backgroundColor:"yellow"

},

innerOne: {

flex:1,

backgroundColor:"blue"

},

innerTwo: { //중복지정시 가장 나중에 지정된 건이 적용된다.

flex:4,

//justifyContent:"flex-start", //

justifyContent:"flex-end", //

//justifyContent:"center", //중간

backgroundColor:"orange"

}

});

 

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fmain.png?alt=media&token=8e5eb78d-19ee-4359-9209-347d125b322c

 

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fpizza.png?alt=media&token=1a099927-d818-45d4-b48a-7906fd0d2ad3

 

https://docs.expo.io/versions/v38.0.0/react-native/text/

 

 

1) Expo 명령어 설치

2) 로컬에 Expo 계정 세팅

3) expo init 명령어로 기본 앱 생성

 

### 작업 후 테스트를 위한 작업

4) expo startExpo 앱 실행 : 터미널에서 실행한다.

5) 휴대폰에 설치한 Expo 클라이언트 앱으로 Expo 앱 실행

 

# numberOfLines #

<View style={styles.cardText}>

<Text style={styles.cardTitle}>먹다 남은 피자를 촉촉하게!</Text>

<Text style={styles.cardDesc} numberOfLines={3}>먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요.
              이럴 경우 그릇에 물을 받아 전자레인 안에서 1분 30초에서 2분 정도 함께 돌려주면 촉촉하게 먹을 수 있습니다.
              물이 전자레인지 안에서 수증기를 일으키고, 피자에 촉촉함을 더해줍니다.

<Text style={styles.cardDate}>2020.09.09</Text>

</View>

 

텍스트가 영역에 맞게 3줄이 보여진 후 ...이 표시된다.

 

# image #

<Image style={styles.mainImage} source={{uri:main}}/>

 

uri : const main = “” 변수 처리하거나 “https:// ” 로 지정한다.

이미지는 styles에 width height를 지정해야 보여진다.

 

return 구문 안에서는 {슬래시 + * 방식으로 주석

ScrollView horizontal={"true"} : 가로로 스크롤된다.

버튼은 TouchableOpacity 로 구현 한다.

 

 

{/* 하나의 카드 영역을 나타내는 View */}

{/* numberOfLines={3} : 3 줄이 보여진다. */}

 

이미지는 스타일 속성을 지정해 줘야 보여진다.

<Image style={styles.mainImage} source={{uri:main}}/>

 

mainImage: {

//컨텐츠의 넓이 값

width:'90%',

//컨텐츠의 높이 값

height:200,

// 컨텐츠의 모서리 구부리기

borderRadius:10,

marginTop:20,

//컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)

//각 속성의 값들은 공식문서에 그대로 나와 있음

alignSelf:"center"

},

 

view

text

ScrollView

 

StyleSheet, Text, View, Button, Alert, SafeAreaView

 

1.SafeAreaView

 

styles.container를 감싸는 View 태그를 SageAreaView로 교체하여 열고 닫아 준다.

상태바 밑으로 화면이 위치한다.

 

StyleSheet, Text, View, Button, Alert, View

 

주석처리시에도 {}를 사용한다.

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

import React from 'react';

import { StyleSheet, Text, View, Button, Alert, SafeAreaView } from 'react-native';

export default function App() {

//화살표 함수 형식으로 함수를 정의하고

//jSX문법 안에서 사용할 수 있습니다

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

return (

<SafeAreaView style={styles.container}>

<View style={styles.textContainer}>

<Text style={styles.textStyle}>아래 버튼을 눌러주세요</Text>

{/* 버튼 onPress 속성에 일반 함수를 연결 할 수 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#f194ff"

/*

onPress={function(){

Alert.alert('팝업 알람입니다!!')

}}

*/

onPress={() => {customAlert()}}

/>

{/* ES6 문법으로 배웠던 화살표 함수로 연결 할 수도 있습니다. */}

<Button

style={styles.buttonStyle}

title="버튼입니다 "

color="#FF0000"

/*

onPress={()=>{

Alert.alert('팝업 알람입니다!!')

}}*/

onPress={() => {customAlert()}}

/>

</View>

</SafeAreaView>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

},

textContainer: {

height:100,

margin:10,

},

textStyle: {

textAlign:"center"

},

});

 

2.ScrollView

 

3.customFunction

const customAlert = () => {

Alert.alert("JSX 밖에서 함수 구현 가능!")

}

 

4.TouchableOpacity : onPress 이벤트 지정 할 수 있는 버튼

함수 호출시 함수명만 지정 한다.

 

return (

<ScrollView style={styles.container}>

<TouchableOpacity style={styles.textContainer} onPress={customAlert}>

<Text style={styles.textStyle}>영역을 충분히 갖는 텍스트 입니다1</Text>

</TouchableOpacity>

</ScrollView>

);

 

# Image

import React from 'react';

import { StyleSheet, Text, View, Image } from 'react-native';

//이렇게 상단에 가져와 사용할 이미지를 불러옵니다

import favicon from "./assets/favicon.png"

export default function App() {

return (

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={favicon}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다 repeat | cover | contain

resizeMode={"contain"}

style={styles.imageStyle}

/>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

//혹시 미리 궁금하신 분들을 위해 언급하자면,

//justifyContentalignContent는 영역 안에 있는 콘텐츠들을 정렬합니다

justifyContent:"center",

alignContent:"center"

},

imageStyle: {

width:"100%",

height:"100%",

alignItems:"center",

justifyContent:"center"

}

});

 

 

<View style={styles.container}>

{/*이미지 태그 soruce 부분에 가져온 미지 이름을 넣습니다 */}

<Image

source={{uri:'https://images.unsplash.com/photo-1424819827928-55f0c8497861?fit=crop&w=600&h=600%27'}}

// 사용설명서에 나와 있는 resizeMode 속성 값을 그대로 넣어 적용합니다

resizeMode={"cover"}

style={styles.imageStyle}

/>

</View>

 

 

## 01. flex ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

backgroundColor:"yellow"

}

});

 

다시말해 flex는 상대적입니다.

가장 최상위의 container 스타일을 가져가는 View 엘리먼트는 디바이스 전체 화면의 영역을 가져갑니다.

안 쪽의 containerOne 스타일이 부여된 View 엘리먼트는 전체를 3등분한 뒤 1/3을 가져가고 containerTwo 2/3를 가져갑니다.

 

 

## 01. flex justifyContent ##

import React from 'react';

import { StyleSheet, Text, View } from 'react-native';

export default function App() {

return (

<View style={styles.container}>

<View style={styles.containerOne}>

</View>

<View style={styles.containerTwo}>

<View style={styles.innerOne}>

</View>

<View style={styles.innerTwo}>

<Text>!!컨텐츠!!</Text>

</View>

</View>

</View>

);

}

const styles = StyleSheet.create({

container: {

flex:1

},

containerOne: {

flex:1,

backgroundColor:"red"

},

containerTwo:{

flex:2,

flexDirection:"row",

backgroundColor:"yellow"

},

innerOne: {

flex:1,

backgroundColor:"blue"

},

innerTwo: { //중복지정시 가장 나중에 지정된 건이 적용된다.

flex:4,

//justifyContent:"flex-start", //

justifyContent:"flex-end", //

//justifyContent:"center", //중간

backgroundColor:"orange"

}

});

 

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fmain.png?alt=media&token=8e5eb78d-19ee-4359-9209-347d125b322c

 

https://firebasestorage.googleapis.com/v0/b/sparta-image.appspot.com/o/lecture%2Fpizza.png?alt=media&token=1a099927-d818-45d4-b48a-7906fd0d2ad3

 

https://docs.expo.io/versions/v38.0.0/react-native/text/

 

 

1) Expo 명령어 설치

2) 로컬에 Expo 계정 세팅

3) expo init 명령어로 기본 앱 생성

 

### 작업 후 테스트를 위한 작업

4) expo startExpo 앱 실행 : 터미널에서 실행한다.

5) 휴대폰에 설치한 Expo 클라이언트 앱으로 Expo 앱 실행

 

# numberOfLines #

<View style={styles.cardText}>

<Text style={styles.cardTitle}>먹다 남은 피자를 촉촉하게!</Text>

<Text style={styles.cardDesc} numberOfLines={3}> 먹다 남은 피자는 수분이 날라가기 때문에 처음처럼 맛있게 먹을 수 없는데요.
              이럴 경우 그릇에 물을 받아 전자레인 안에서 1분 30초에서 2분 정도 함께 돌려주면 촉촉하게 먹을 수 있습니다.
              물이 전자레인지 안에서 수증기를 일으키고, 피자에 촉촉함을 더해줍니다.

<Text style={styles.cardDate}>2020.09.09</Text>

</View>

 

텍스트가 영역에 맞게 3줄이 보여진 후 ...이 표시된다.

 

# image #

<Image style={styles.mainImage} source={{uri:main}}/>

 

uri : const main = “” 변수 처리하거나 “https:// ” 로 지정한다.

이미지는 styleswidth height를 지정해야 보여진다.

 

return 구문 안에서는 {슬래시 + * 방식으로 주석

ScrollView horizontal={"true"} : 가로로 스크롤된다.

버튼은 TouchableOpacity 로 구현 한다.

 

 

{/* 하나의 카드 영역을 나타내는 View */}

{/* numberOfLines={3} : 3 줄이 보여진다. */}

 

 

 

이미지는 스타일 속성을 지정해 줘야 보여진다.

<Image style={styles.mainImage} source={{uri:main}}/>

 

mainImage: {

//컨텐츠의 넓이 값

width:'90%',

//컨텐츠의 높이 값

height:200,

// 컨텐츠의 모서리 구부리기

borderRadius:10,

marginTop:20,

//컨텐츠 자체가 앱에서 어떤 곳에 위치시킬지 결정(정렬기능)

//각 속성의 값들은 공식문서에 그대로 나와 있음

alignSelf:"center"

},

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#3주차_1  (0) 2023.01.05
#2주차 강의  (1) 2022.12.30
#2주차_2  (1) 2022.12.28
#2주차_1  (0) 2022.12.28
1~3일차강의정리  (1) 2022.12.21
Posted by 봄날의차

05. [앱 화면 만들기] JSX 문법

 

App.js : 진입파일

 

1.해당 프로젝트에서 VSCode 에디터열기

-확장 : Material Icon Theme 추가 설치

2.터미널 열기

3.expo start 로 열린 Expo 개발 도구 화면에서, 좌측의 QR 코드를 휴대폰 카메라로 비춘뒤, 여러분 휴대폰에 설치했던 Expo 클라이언트 앱을 실행시킵니다.

 

// return 문 밖의 문법확인 과 warning을 안보이게 하는 코드

LogBox.ignoreLogs(['Warning:...']);

 

// {} 필요한 라이브러리를 참조하겠다는 의미

import { StatusBar } from 'expo-status-bar';

 

//우리가 리액트, 리액트 네이티브, 엑스포 라이브러리에서 꺼내 사용할 기능들을

//이렇게 앞으로도 상단에 선언한다음 가져다 사용합니다.

import { StatusBar } from 'expo-status-bar';

import React from 'react';

import { StyleSheet, Text, View, LogBox } from 'react-native';

//App.js는 결국 App 함수를 내보내기 하고 있는 자바스크립트 파일입니다.

//이 함수는 무언가?를 반환하고 있는데 결국 화면을 반환하고 있습니다.

export default function App() {

//화면을 반환합니다.

//HTML 태그 같이 생긴 이 문법은 JSX라 불리우며 실제 화면을 그리는 문법입니다,

//이번 강의에서 자세히 다룹니다

// return 문 밖의 문법확인 과 warning을 안보이게 하는 코드

LogBox.ignoreLogs(['Warning:...']);

 

//return 안에 내용이 화면을 바꾼다.

//태그는 대문자로 시작한다.

//스타일은 정의할 때마다 const styles에 추가 해서 사용한다.

return (

<View style={styles.container}>

<Text style={styles.textStyle}>Open up App.js to start working on your app!!</Text>

<Text>스파르타 건희</Text>

<StatusBar style="dark" />

</View>

);

}

// styles 변수 이름 답게 화면을 그려주는,

//더 자세히는 JSX문법을 꾸며주는 내용을 담고 있습니다.

const styles = StyleSheet.create({

container: {

flex: 1,

backgroundColor: '#fff',

alignItems: 'center',

justifyContent: 'center',

},

textStyle:{

color:'green'

}

});

 

>>태그 공식사용설명서 API<<

https://docs.expo.io/versions/v38.0.0/react-native/view/

 

StatusBar Component Example

안에서 사용되는 태그 사용법을 확인해서 사용한다.

<StatusBar ... /> 인지 닫는 태그가 있는지

<Text style={styles.textStyle}>

StatusBar Visibility:{'\n'}

{hidden ? 'Hidden' : 'Visible'}

</Text>

 

>> jsx문법<<

1.상단에서 리액트 네이트브 도구에서 임포트하여 함수를 사용한다.

2.열고 닫는 태그쌍 또는 스스로 닫는 태그가 구분되어 사용된다.: API에서 사용방법 체크

3.모든 태그는 부모태그가 있다.

4.렌더링시 reutrn문은 소가로를 사용한다. return ()

5.주석은 return태그 안에서는 {/* */} 태그 밖에서는 //를 사용한다.

 

>>App.js<<

//우리가 리액트, 리액트 네이티브, 엑스포 라이브러리에서 꺼내 사용할 기능들을
//이렇게 앞으로도 상단에 선언한다음 가져다 사용합니다.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, LogBox } from 'react-native';
//App.js는 결국 App 함수를 내보내기 하고 있는 자바스크립트 파일입니다.
//이 함수는 무언가?를 반환하고 있는데 결국 화면을 반환하고 있습니다.
export default function App() {
//화면을 반환합니다.
//HTML 태그 같이 생긴 이 문법은 JSX라 불리우며 실제 화면을 그리는 문법입니다,
//이번 강의에서 자세히 다룹니다
// return 문 밖의 문법확인 과 warning을 안보이게 하는 코드
LogBox.ignoreLogs(['Warning:...']);

//return 안에 내용이 화면을 바꾼다.
//태그는 대문자로 시작한다.
return (
  <View style={styles.container}>
    <Text style={styles.textStyle}>Open up App.js to start working on your app!!</Text>
    <Text>스파르타 건희</Text>
    <StatusBar style="dark" />
  </View>
);
}
// styles 변수 이름 답게 화면을 그려주는,
//더 자세히는 JSX문법을 꾸며주는 내용을 담고 있습니다.
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  textStyle:{
    color:'green'
  }
});
 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#2주차 강의  (1) 2022.12.30
#2주차_3  (0) 2022.12.29
#2주차_1  (0) 2022.12.28
1~3일차강의정리  (1) 2022.12.21
스파르타코딩클럽_앱개발_종합반  (0) 2022.12.21
Posted by 봄날의차

 참고사이트 

https://expo.dev/accounts/sensewake/projects?create=true

 

Log In — Expo

Log in to your Expo account.

expo.dev

 

https://seopark.tistory.com/6

 

[VSCode] expo : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Users\사용자ID\AppData\Roaming\npm\expo.ps1

expo : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\\Users\\impor\\AppData\\Roaming\\npm\\expo.ps1 파일을 로드할 수 없습니다.

velog.io

>>visual studio code 한글언어팩

https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ko

 

>>expo 실행시 권한 에러가 나는 경우

https://seopark.tistory.com/6

 

Expo Go

(1) 개발 중인 앱을 쉽게 확인해주는 앱 제공 : 개발 테스트 배포 : 핸드폰에서 바로 확인 가능 : 핸드폰에 설치함

https://expo.io/signup

이메일주소 / 비번

 

Yarn

리액트 네이트브는 Yarn으로 자바스크립트 도구를 설치해야함

 

(2) Yarn

//도구를 가져와 설치하는 npm 의 설치 명령어 install

//컴퓨터 어디서든 설치하고 있는 도구를 사용할 수 있게 해주는 -g 옵션 명령어

npm install -g yarn

//설치가 완료된다음

yarn v

C:\>npm install -g yarn

npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

 

added 1 package, and audited 2 packages in 1s

 

found 0 vulnerabilities

npm notice

npm notice New major version of npm available! 8.11.0 -> 9.2.0

npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.2.0

npm notice Run npm install -g npm@9.2.0 to update!

npm notice

C:\>yarn -v

1.22.19

C:\>node -v

v16.16.0

 

01. 2주차 오늘 배울 내용

리액트 네이티브 앱 개발을 시작

1) 앱 개발 준비 - 리액트 네이티브(기술) & Expo(도구) 소개 및 설치

2) 앱 화면 만들기

3) 앱 필수 기초 지식 - 리액트 기초 다지기

 

[앱 개발 준비] 시작하는 리액트 네이티브 & Expo

리액트 네이티브 앱 개발을 더 편하고 쉽게 도와주는 Expo라는 도구로 앱 개발을 진행

[앱 화면 만들기] 리액트 네이티브에서 화면을 그리는 방법

리액트 네이티브 앱 개발에서 구역(레이아웃)을 잡는 문법 언어 : JSX

## JSX

JSX문법은 정말 간단하게, 화면의 구역을 잡을 때는 <View> 태그를,

글자를 쓸때는 <Text> 태그를 사용하라는 것처럼, 용도에 맞는 태그를 정해놨습니다.

그래서 우린 필요한 태그를 그때그때 꺼내서 사용하면 됩니다.

태그란 <>과 같이 꺽쇠로 표현하는 프로그래밍 문법을 뜻합니다! HTML들어보셨나요? HTML도 태그 문법이에요!

 

//잠시 살펴보는 JSX !!!

//이렇게 상단에서 사용할 엘리먼트를 react-native 라이브러리로부터 꺼내 사용합니다.

import { Text, View } from 'react-native';

<View>

<Text>Hello, I am {props.name}!</Text>

</View>

 

동시에 JSX 문법으로 영역을 잡은 뒤 이쁘게 꾸미는 방법도 배웁니다!

 

[&자바스크립트 ] 리액트 네이티브에서 자주 사용되는 자바스크립트!

리액트 네이티브로 앱을 제작 하다보면, 자주 사용되는 자바스크립트 문법이 다소 한정적이게 됩니다! 조건문도 우리가 알

고 있는 if 문보다는 좀더 간결하고 직관적인 조건문을 사용합니다.

물론 여러분들이 앞으로 앱 개발 공부를 더 진행하면서, 유려한 문법을 사용하여 멋지게 코드를 작성할 수 있겠지만!

결국 반복과 조건 정도의 주요 문법이 앱의 중요 로직들을 생성합니다. 따라서 이번 시간엔 자주 사용되는 자바스크립트 몇

가지를 앱 코드 상에서 연습합니다

 

02. [앱 개발 준비] 리액트 네이티브&Expo 소개

1) 리액트 네이티브 = 리액트(React) + 네이티브(Native)

-리액트 네이티브는 우리가 배운 자바스크립트 언어 하나로 안드로이드 앱과 iOS앱 두 가지 모두 만들어주는 라이브러리 입니다.

-안드로이드, iOS 앱을 만들 땐 자바&코틀린과 Swift라는 언어를 써야하는데, 그러면 언어 하나로 앱을 만들 수 있다는 취지에서 벗어나게 됩니다

더 쉽고 빠르고 정말 안드로이드,iOS 개발 언어를 잘 몰라도 리액트 네이티브 앱 개발을 수월하게 도와주는 도구가 존재합니다! Expo

 

2) Expo?

(1) 안드로이드&iOS 코드를 정말 몰라도 개발이 가능!

(2) 개발 중인 앱을 쉽게 확인해주는 앱 제공 : 개발 테스트 배포 : 핸드폰에서 바로 확인 가능

.Expo는 개발 중인 앱 테스트를 위한 Expo Go 을 제공해줍니다.

: 앱 마켓에 들어가서 Expo Go 검색

.IOS > https://apps.apple.com/app/apple-store/id982107779

.안드로이드 > https://play.google.com/store/apps/details?id=host.exp.exponent&referrer=www&pli=1

 

03. [앱 개발 준비] 리액트 네이티브 & Expo 설치하기

3) Node & NPM 설치

(1) NodeNPM

Node.js로 자바스크립트 개발 환경을 구축하고,

NPM으로 필요한 자바스크립트 앱 개발 도구들을 가져와 사용하는 모습이라 보면 됩니다.

 

(2) Yarn

-NPM과 같다.리액트 네이티브는 Yarn으로 자바스크립트 도구를 설치해야한다.NPM보다 조금 더 빠르

게 자바스크립트 도구를 내려 받을 수 있다.Yarn을 설치하려면 NPM을 설치해야한다.

//도구를 가져와 설치하는 npm 의 설치 명령어 install

//컴퓨터 어디서든 설치하고 있는 도구를 사용할 수 있게 해주는 -g 옵션 명령어

npm install -g yarn

//설치가 완료된다음

yarn v

 

sudo npm install -g yarn : 권한 에러시엔 sudo를 사용

node -v : node 설치 확인

v16.16.0

 

-yarnnpm 보다 가볍고 빠르게 자바스크립트 패키지를 관리 할 수 있게 해주는 자바스크립트 패키지 매니저 툴입니다.

각자의 장단점이 있지만, 우린 앞으로 패키지 관리자로 yarn을 좀 더 많이 사용하게 됩니다.

 

4) Expo 명령어 도구 설치

-노드(Node.js)와 노드 패키지 매니저(npm)까지 설치가 완료

-윈도우 사용자 설치 : npm install -g expo-cli

확인 : expo --version

6.0.8

 

윈도우 사용자 분들이 자주 겪는 에러!

[Windows] 윈도우를 사용하는데 expo init 또는 expo start 를 진행하니 expo : 이 시스템에서 스크립트를 실행할 수 없으므로

C:\Users\PC\AppData\Roaming\npm\expo.ps1 파일을 로드할 수 없습니다. 오류가 발생합니다. (영어 윈도우: expo : File

C:\Users\PC\AppData\Roaming\npm\expo.ps1 cannot be loaded because running script is disabled on this system. )

아래 동영상을 따라해 보세요! (FAQ 에 모두 수록!!)

https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7f233dd5-7920-4554-a435-705871419809/change_default_shell.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20221227%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221227T074106Z&X-Amz-Expires=86400&X-Amz-Signature=618e19654fa71ddf671e7f6018ba18e311b0bba53b9a2ec8b50339fb6e8bb95e&X-Amz-SignedHeaders=host&x-id=GetObject

 

npm install g expo-cli

 

npm: 노드 패키지 매니저 명령을 실행하겠다

install: 설치하겠다

-g: 컴퓨터 전역적으로 설치하겠다 == 어디서든지 -g 다음에 오는 명령어를 사용할 수 있게끔!

expo-cli: 설치 할 패키지 이름

따라서 우린 이 명령어 한 줄로, 여러분 컴퓨터 어디서든지 Expo를 사용할 수 있게끔 패키지를 전역적으로 설치했습니다.

 

YarnExpo : 큰 자바스크립트 도구

npm으로 전역 설치를 한다.

YarnExpo 프로젝트로 앱개발시에 만드는 프로젝트 방 안에서 사용하게 된다.

 

npm: 노드 패키지 매니저 명령을 실행하겠다

install: 설치하겠다

-g: 컴퓨터 전역적으로 설치하겠다 == 어디서든지 -g 다음에 오는 명령어를 사용할 수 있게끔!

expo-cli: 설치 할 패키지 이름 .expo-cli는 도구 다발이라 생각하면 됨

 

Expo를 설치 및 사용한다는 것은, Expo가 기본적으로 제공해주는 명령어들...

1) 프로젝트 생성,

2) 프로젝트 실행,

3) 프로젝트 빌드 등등의 여러 기능들을 사용 할 수 있다는 것을 뜻합니다.

 

5) Expo 가입 및 로컬에 Expo 계정 세팅

1) Expo 가입

[코드스니펫] Expo 가입 링크

https://expo.io/signup

2) 로컬에 Expo 계정 세팅

윈도우는 cmd

맥은 terminal에서 다음 명령어를 실행합니다

expo login

...

expo 이메일(또는 아이디), 패스워드 입력란이 차례로 나오고, 차례대로 입력하면 로그인 성공!

 

04. [앱 개발 준비] Expo 실행하기

$ expo start --help

Username/Email Address: ... sensewake@gmail.com

Password: ... **********

Success. You are now logged in as sensewake.

 

-여러분들이 만들기도 하고 연습도 할 작업 공간인 폴더 하나를 만들어주세요. 이름은 sparta-study

 

 

[코드스니펫] Expo 가입 링크

https://expo.io/signup

 

>>cmd

expo login

...

expo 이메일(또는 아이디), 패스워드 입력란이 차례로 나오고, 차례대로 입력하면 로그인 성공!

 

https://expo.dev/login

이메링 / 비번

 

C:\Users\user\Desktop\01.sparta_study> 터미널에서 실행함 g 전역

npm install -g expo-cli

 

>>expo start 에러<<

expo start : The expected package.json path: package.json does not exist 에러가 난다.

expo init sparta-myhoneytip-yak

init 과 패키지 생성함

C드라이브에 작업함 D드라이브엔 Expo 권한이 없음.expo init 도 권한없음에러가 난다.

 

1.expo init sparta-myhoneytip-영어이름

2.Choose a template: » blank

: 앱설치됨

Your project is ready!

 

## 터미널

expo start

expo go 실행

 

핸드폰에서 QR코드로 expo go를 실행한다.

 

확장 : Material Icon Theme

설치하면 아이콘 테마가 아래처럼 적용된다.

 

App.js

코드 수정하면 화면에 반영된다.

assets : 적용할 이미지 폴더

node_modules : download된 도구들이 위치한다.

 

1) Expo 명령어 설치

2) 로컬에 Expo 계정 세팅

3) expo init 명령어로 기본 앱 생성

4) expo startExpo 앱 실행

5) 휴대폰에 설치한 Expo 클라이언트 앱으로 Expo 앱 실행

 

https://expo.dev/accounts/sensewake/projects?create=true

 

Log In — Expo

Log in to your Expo account.

expo.dev

https://www.google.com/search?q=npm%5Cexpo.ps1+%ED%8C%8C%EC%9D%BC%EC%9D%84+%EB%A1%9C%EB%93%9C%ED%95%A0+%EC%88%98+%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.&rlz=1C1SQJL_koKR1037KR1037&oq=npm%5Cexpo.ps1+%ED%8C%8C%EC%9D%BC%EC%9D%84+%EB%A1%9C%EB%93%9C%ED%95%A0+%EC%88%98+%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.&aqs=chrome..69i57j69i58.1380j0j7&sourceid=chrome&ie=UTF-8

 

🔎 npm\expo.ps1 파일을 로드할 수 없습니다.: Google 검색

 

www.google.com

https://seopark.tistory.com/6

 

[VS Code] expo : 이 시스템에서 스크립트를 실행할 수 없으므로... 터미널 오류

터미널에 expo start라고 입력하였으나 스크립트 실행 권한이 제한되어 있는 상태이므로 오류가 발생하였다. 스크립트 실행 권한 변경 1. PowerShell 관리자 권한으로 실행 2. get-help Set-ExecutionPolicy 입

seopark.tistory.com

https://velog.io/@min-zi/VSCode-expo-%EC%9D%B4-%EC%8B%9C%EC%8A%A4%ED%85%9C%EC%97%90%EC%84%9C-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A5%BC-%EC%8B%A4%ED%96%89%ED%95%A0-%EC%88%98-%EC%97%86%EC%9C%BC%EB%AF%80%EB%A1%9C-CUsers%EC%82%AC%EC%9A%A9%EC%9E%90IDAppDataRoamingnpmexpo.ps1-%ED%8C%8C%EC%9D%BC%EC%9D%84-%EB%A1%9C%EB%93%9C%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4

 

[VSCode] expo : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\Users\사용자ID\AppData\Roaming\npm\expo.ps1

expo : 이 시스템에서 스크립트를 실행할 수 없으므로 C:\\Users\\impor\\AppData\\Roaming\\npm\\expo.ps1 파일을 로드할 수 없습니다.

velog.io

 

>>visual studio code 한글언어팩 

https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ko

 

>>expo 실행시 권한 에러가 나는 경우

https://seopark.tistory.com/6

 

Expo Go

(1) 개발 중인 앱을 쉽게 확인해주는 앱 제공 : 개발 테스트 배포 : 핸드폰에서 바로 확인 가능 : 핸드폰에 설치함

https://expo.io/signup

이메일 / 비번

 

Yarn

리액트 네이트브는 Yarn으로 자바스크립트 도구를 설치해야함

 

(2) Yarn

//도구를 가져와 설치하는 npm 의 설치 명령어 install

//컴퓨터 어디서든 설치하고 있는 도구를 사용할 수 있게 해주는 -g 옵션 명령어

npm install -g yarn

//설치가 완료된다음

yarn v

C:\>npm install -g yarn

npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

 

added 1 package, and audited 2 packages in 1s

 

found 0 vulnerabilities

npm notice

npm notice New major version of npm available! 8.11.0 -> 9.2.0

npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.2.0

npm notice Run npm install -g npm@9.2.0 to update!

npm notice

C:\>yarn -v

1.22.19

C:\>node -v

v16.16.0

 

01. 2주차 오늘 배울 내용

리액트 네이티브 앱 개발을 시작

1) 앱 개발 준비 - 리액트 네이티브(기술) & Expo(도구) 소개 및 설치

2) 앱 화면 만들기

3) 앱 필수 기초 지식 - 리액트 기초 다지기

 

[앱 개발 준비] 시작하는 리액트 네이티브 & Expo

리액트 네이티브 앱 개발을 더 편하고 쉽게 도와주는 Expo라는 도구로 앱 개발을 진행

[앱 화면 만들기] 리액트 네이티브에서 화면을 그리는 방법

리액트 네이티브 앱 개발에서 구역(레이아웃)을 잡는 문법 언어 : JSX

## JSX

JSX문법은 정말 간단하게, 화면의 구역을 잡을 때는 <View> 태그를,

글자를 쓸때는 <Text> 태그를 사용하라는 것처럼, 용도에 맞는 태그를 정해놨습니다.

그래서 우린 필요한 태그를 그때그때 꺼내서 사용하면 됩니다.

태그란 <>과 같이 꺽쇠로 표현하는 프로그래밍 문법을 뜻합니다! HTML들어보셨나요? HTML도 태그 문법이에요!

 

//잠시 살펴보는 JSX !!!

//이렇게 상단에서 사용할 엘리먼트를 react-native 라이브러리로부터 꺼내 사용합니다.

import { Text, View } from 'react-native';

<View>

<Text>Hello, I am {props.name}!</Text>

</View>

 

동시에 JSX 문법으로 영역을 잡은 뒤 이쁘게 꾸미는 방법도 배웁니다!

 

[&자바스크립트 ] 리액트 네이티브에서 자주 사용되는 자바스크립트!

리액트 네이티브로 앱을 제작 하다보면, 자주 사용되는 자바스크립트 문법이 다소 한정적이게 됩니다! 조건문도 우리가 알

고 있는 if 문보다는 좀더 간결하고 직관적인 조건문을 사용합니다.

물론 여러분들이 앞으로 앱 개발 공부를 더 진행하면서, 유려한 문법을 사용하여 멋지게 코드를 작성할 수 있겠지만!

결국 반복과 조건 정도의 주요 문법이 앱의 중요 로직들을 생성합니다. 따라서 이번 시간엔 자주 사용되는 자바스크립트 몇

가지를 앱 코드 상에서 연습합니다

 

02. [앱 개발 준비] 리액트 네이티브&Expo 소개

1) 리액트 네이티브 = 리액트(React) + 네이티브(Native)

-리액트 네이티브는 우리가 배운 자바스크립트 언어 하나로 안드로이드 앱과 iOS앱 두 가지 모두 만들어주는 라이브러리 입니다.

-안드로이드, iOS 앱을 만들 땐 자바&코틀린과 Swift라는 언어를 써야하는데, 그러면 언어 하나로 앱을 만들 수 있다는 취지에서 벗어나게 됩니다

더 쉽고 빠르고 정말 안드로이드,iOS 개발 언어를 잘 몰라도 리액트 네이티브 앱 개발을 수월하게 도와주는 도구가 존재합니다! Expo

 

2) Expo?

(1) 안드로이드&iOS 코드를 정말 몰라도 개발이 가능!

(2) 개발 중인 앱을 쉽게 확인해주는 앱 제공 : 개발 테스트 배포 : 핸드폰에서 바로 확인 가능

.Expo는 개발 중인 앱 테스트를 위한 Expo Go 을 제공해줍니다.

: 앱 마켓에 들어가서 Expo Go 검색

.IOS > https://apps.apple.com/app/apple-store/id982107779

.안드로이드 > https://play.google.com/store/apps/details?id=host.exp.exponent&referrer=www&pli=1

 

03. [앱 개발 준비] 리액트 네이티브 & Expo 설치하기

3) Node & NPM 설치

(1) NodeNPM

Node.js로 자바스크립트 개발 환경을 구축하고,

NPM으로 필요한 자바스크립트 앱 개발 도구들을 가져와 사용하는 모습이라 보면 됩니다.

 

(2) Yarn

-NPM과 같다.리액트 네이티브는 Yarn으로 자바스크립트 도구를 설치해야한다.NPM보다 조금 더 빠르

게 자바스크립트 도구를 내려 받을 수 있다.Yarn을 설치하려면 NPM을 설치해야한다.

//도구를 가져와 설치하는 npm 의 설치 명령어 install

//컴퓨터 어디서든 설치하고 있는 도구를 사용할 수 있게 해주는 -g 옵션 명령어

npm install -g yarn

//설치가 완료된다음

yarn v

 

sudo npm install -g yarn : 권한 에러시엔 sudo를 사용

node -v : node 설치 확인

v16.16.0

 

-yarnnpm 보다 가볍고 빠르게 자바스크립트 패키지를 관리 할 수 있게 해주는 자바스크립트 패키지 매니저 툴입니다.

각자의 장단점이 있지만, 우린 앞으로 패키지 관리자로 yarn을 좀 더 많이 사용하게 됩니다.

 

4) Expo 명령어 도구 설치

-노드(Node.js)와 노드 패키지 매니저(npm)까지 설치가 완료

-윈도우 사용자 설치 : npm install -g expo-cli

확인 : expo --version

6.0.8

 

윈도우 사용자 분들이 자주 겪는 에러!

[Windows] 윈도우를 사용하는데 expo init 또는 expo start 를 진행하니 expo : 이 시스템에서 스크립트를 실행할 수 없으므로

C:\Users\PC\AppData\Roaming\npm\expo.ps1 파일을 로드할 수 없습니다. 오류가 발생합니다. (영어 윈도우: expo : File

C:\Users\PC\AppData\Roaming\npm\expo.ps1 cannot be loaded because running script is disabled on this system. )

아래 동영상을 따라해 보세요! (FAQ 에 모두 수록!!)

https://s3.us-west-2.amazonaws.com/secure.notion-static.com/7f233dd5-7920-4554-a435-705871419809/change_default_shell.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20221227%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20221227T074106Z&X-Amz-Expires=86400&X-Amz-Signature=618e19654fa71ddf671e7f6018ba18e311b0bba53b9a2ec8b50339fb6e8bb95e&X-Amz-SignedHeaders=host&x-id=GetObject

 

npm install g expo-cli

 

npm: 노드 패키지 매니저 명령을 실행하겠다

install: 설치하겠다

-g: 컴퓨터 전역적으로 설치하겠다 == 어디서든지 -g 다음에 오는 명령어를 사용할 수 있게끔!

expo-cli: 설치 할 패키지 이름

따라서 우린 이 명령어 한 줄로, 여러분 컴퓨터 어디서든지 Expo를 사용할 수 있게끔 패키지를 전역적으로 설치했습니다.

 

YarnExpo : 큰 자바스크립트 도구

npm으로 전역 설치를 한다.

YarnExpo 프로젝트로 앱개발시에 만드는 프로젝트 방 안에서 사용하게 된다.

 

npm: 노드 패키지 매니저 명령을 실행하겠다

install: 설치하겠다

-g: 컴퓨터 전역적으로 설치하겠다 == 어디서든지 -g 다음에 오는 명령어를 사용할 수 있게끔!

expo-cli: 설치 할 패키지 이름 .expo-cli는 도구 다발이라 생각하면 됨

 

Expo를 설치 및 사용한다는 것은, Expo가 기본적으로 제공해주는 명령어들...

1) 프로젝트 생성,

2) 프로젝트 실행,

3) 프로젝트 빌드 등등의 여러 기능들을 사용 할 수 있다는 것을 뜻합니다.

 

5) Expo 가입 및 로컬에 Expo 계정 세팅

1) Expo 가입

[코드스니펫] Expo 가입 링크

https://expo.io/signup

2) 로컬에 Expo 계정 세팅

윈도우는 cmd

맥은 terminal에서 다음 명령어를 실행합니다

expo login

...

expo 이메일(또는 아이디), 패스워드 입력란이 차례로 나오고, 차례대로 입력하면 로그인 성공!

 

04. [앱 개발 준비] Expo 실행하기

$ expo start --help

Username/Email Address: ... sensewake@gmail.com

Password: ... **********

Success. You are now logged in as sensewake.

 

-여러분들이 만들기도 하고 연습도 할 작업 공간인 폴더 하나를 만들어주세요. 이름은 sparta-study

 

 

[코드스니펫] Expo 가입 링크

https://expo.io/signup

 

>>cmd

expo login

...

expo 이메일(또는 아이디), 패스워드 입력란이 차례로 나오고, 차례대로 입력하면 로그인 성공!

 

https://expo.dev/login

이메일 / 비번

 

C:\Users\user\Desktop\01.sparta_study> 터미널에서 실행함 g 전역

npm install -g expo-cli

 

>>expo start 에러<<

expo start : The expected package.json path: package.json does not exist 에러가 난다.

expo init sparta-myhoneytip-이름

init 과 패키지 생성함

C드라이브에 작업함 D드라이브엔 Expo 권한이 없음.expo init 도 권한없음에러가 난다.

 

 

1.expo init sparta-myhoneytip-영어이름

2.Choose a template: » blank

: 앱설치됨

Your project is ready!

 

터미널

expo start

핸드폰에서 QR코드로 expo go를 실행한다.

 

확장 : Material Icon Theme

설치하면 아이콘 테마가 아래처럼 적용된다.

 

App.js

코드 수정하면 화면에 반영된다.

assets : 적용할 이미지 폴더

node_modules : download된 도구들이 위치한다.

 

1) Expo 명령어 설치

2) 로컬에 Expo 계정 세팅

3) expo init 명령어로 기본 앱 생성

 

### 작업 후 테스트를 위한 작업

4) 터미널에서 expo startExpo 앱 실행

5) 휴대폰에 설치한 Expo 클라이언트 앱으로 Expo 앱 실행 : 터미널에생성된 QR코드로 실행한다.

 

'08.강의수강일지 > 01.앱개발 종합반' 카테고리의 다른 글

#2주차 강의  (1) 2022.12.30
#2주차_3  (0) 2022.12.29
#2주차_2  (1) 2022.12.28
1~3일차강의정리  (1) 2022.12.21
스파르타코딩클럽_앱개발_종합반  (0) 2022.12.21
Posted by 봄날의차

스파르타코딩클럽_직장인을_위한_실전_데이터분석___1주차.pdf
6.48MB

 

1.https://s3.ap-northeast-2.amazonaws.com/materials.spartacodingclub.kr/data/week1/exceltrain.csv

https://s3.ap-northeast-2.amazonaws.com/materials.spartacodingclub.kr/data/week1/diabetes.csv

 

데이터 다운로드

2.http://sheet.new/

1데이터를 다운 받은 후 sheet.new에서 구글 스프레드시트로 열어서 엑셀 분석을 할 수 있다.

 

http://sheet.new/ : 파일 가져오기 업로드 다운 받은 파일 업로드

 

3.부가기능

XLMiner Analysis Tool 설치

 

'08.강의수강일지 > 03.직장인을 위한 실전 데이터 분석' 카테고리의 다른 글

#4주차  (0) 2023.01.27
#4주차 colab사이트에서 github에 저장하기  (0) 2023.01.27
#2주차  (0) 2022.12.30
#2주차  (0) 2022.12.30
Posted by 봄날의차

내일배움단_엑셀보다_쉬운_SQL_-_3주차.pdf
1.71MB

SELECT * from users u 
left join point_users p on u.user_id = p.user_id 
;
SELECT * from users u 
inner join point_users p on u.user_id = p.user_id 
;
#03.Join 실습
select * from orders o
inner join users u on o.user_id = u.user_id 
;
select * from checkins c 
inner join users u
on c.user_id = u.user_id
;

select * from enrolleds e 
;
select * from courses c 
;
select * from enrolleds e 
inner join courses c on e.course_id = c.course_id 
;

select c2.course_id, c2.title, count(c2.title) as checkin_count from checkins c1 
inner join courses c2
on c1.course_id = c2.course_id 
group by c2.course_id, c2.title
;

select u.user_id , u.name , u.email , pu.`point`  from point_users pu 
inner join users u on pu.user_id = u.user_id 
order by pu.point desc
;

#1 payment_method
select * from point_users p
;
select * from orders o 
;
SELECT o.payment_method, round(avg(p.`point`),0) as avg_point 
from point_users p
inner join orders o on p.user_id = o.user_id 
group by o.payment_method 
;

#2 enrolleds users
select u.name, count(u.user_id) as cnt from enrolleds e 
inner join users u on e.user_id = u.user_id 
where is_registered = 0
group by name 
order by cnt desc
;

#3 courses enrolleds
select c.course_id, c.title, count(e.user_id) as ucnt  from courses c
inner join enrolleds e on c.course_id = e.course_id 
where e.is_registered = 0
group by c.course_id /*, c.title */
;

#4 courses checkins
select c2.course_id, c1.title, c2.week, count(c2.user_id) as cnt from courses c1 
inner join checkins c2 
on c1.course_id = c2.course_id 
group by c2.course_id, c2.week
order by c1.title, c2.week, cnt
;

#5 
select c1.title, c2.week
-- , count(o.user_id) as cnt 
, count(*) as cnt
from courses c1 inner join checkins c2 
on c1.course_id = c2.course_id 
inner join orders o 
/* on c2.course_id = o.course_id 
 *and c2.user_id = o.user_id 
 */
on c2.user_id = o.user_id 
where o.created_at >= '2020-08-01'
GROUP by c1.title, c2.week
order by c1.title, c2.week, cnt
;

#6 
## between A and B 
## A 는 포함 B는 미만 인 범위를 주의해야함 
## 범위 : A >= and B < 
select * 
  from users u 
  left join point_users p
    on u.user_id = p.user_id 
 where u.created_at between '2020-07-10' and '2020-07-20'
;

/*

2020-07-10 일포함 그 이상인 날짜를 조회하는데 2020-07-20 미만인 날짜로 2022-07-19까지의 데이터를 조회해 온다.

*/

select count(*) as tot_cnt
     , count(u.user_id) as tot_user_cnt
     , count(p.point_user_id) as pnt_user_cnt 
     , round(count(p.point_user_id) / count(u.user_id), 2) as ratio
  from users u 
  left join point_users p
    on u.user_id = p.user_id 
 where u.created_at between '2020-07-10' and '2020-07-20'
;  

#7 union 
select '8월' as month, c1.title, c2.week, count(*) as cnt from courses c1 
inner join checkins c2 on c1.course_id = c2.course_id 
inner join orders o on c2.user_id = o.user_id
where o.created_at >= '2020-08-01' 
group by c1.title, c2.week
order by c1.title, c2.week
;

#8 union 안에서는 order by가 안 먹는다.합친 후 정렬해야한다.
(
select '7월' as month, c.title, c2.week, count(*) as cnt from checkins c2 
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id 
where o.created_at < '2020-08-01'
group by c2.course_id, c2.week 
-- order by c2.course_id, c2.week
)
union all
(
select '8월' as month, c.title, c2.week, count(*) as cnt from checkins c2 
inner join courses c on c2.course_id = c.course_id
inner join orders o on o.user_id = c2.user_id 
where o.created_at > '2020-08-01'
group by c2.course_id, c2.week 
-- order by c2.course_id, c2.week
)

#9 과제
# 조건절에 넣어야하는 부분과 on 절에 넣어야 하는 필드 선택 구분 해야함.값이 달라진다.
select e1.enrolled_id , e1.user_id, count(*) as max_count
from enrolleds e1 
inner join enrolleds_detail e2 
on e1.enrolled_id = e2.enrolled_id 
where e2.done = 1
group by e1.enrolled_id , e1.user_id
order by max_count desc
;

'08.강의수강일지 > 02.엑셀보다 쉬운, SQL' 카테고리의 다른 글

#4주차  (0) 2022.12.30
#2주차 강의  (0) 2022.12.23
엑셀보다 쉬운 SQL 1주차  (0) 2022.12.21
Posted by 봄날의차

내일배움단_엑셀보다_쉬운_SQL_-_2주차.pdf
0.87MB

select name, count(*) from users
group by name;

select week, count(*) from checkins 
group by week ;

select week, count(*) from checkins 
where week = 1 ;

select week, min(likes) from checkins 
group by week
;

select week, max(likes) from checkins 
group by week
;

select week, round(avg(likes),1) from checkins 
group by week
;

select week, sum(likes) from checkins 
group by week
;

select * from checkins c 
where week = 3
;

select payment_method, count(*) from orders 
where course_title = "웹개발 종합반"
group by payment_method
order by count(*) desc
;

select payment_method, count(*) from orders 
group by payment_method
order by count(*) desc
;

select * from users 
-- order by email;
order by created_at desc 
;

#quis1
select payment_method, count(*) from orders 
where course_title = "앱개발 종합반"
group by payment_method
order by count(*) desc
;

#quis2
select * from users ;

select name, count(*) from users 
where email like '%@gmail.com'
group by name
;

#quis3
select * from courses ;
select * from checkins ;

select course_id, round(AVG(likes),1) from checkins
group by course_id
;

#과제
select * from orders limit 10
;
select payment_method, count(*) from orders o
where o.email like '%@naver.com' and o.course_title = '앱개발 종합반'
group by payment_method
;

'08.강의수강일지 > 02.엑셀보다 쉬운, SQL' 카테고리의 다른 글

#4주차  (0) 2022.12.30
#3주차 강의  (0) 2022.12.26
엑셀보다 쉬운 SQL 1주차  (0) 2022.12.21
Posted by 봄날의차