'웹 개발/Problems'에 해당되는 글 9건

  1. 2024.01.16 Decimal calculation in Javascript 1
  2. 2021.07.02 AWS s3 404 Not Found 에러
  3. 2021.06.02 삽질: axios , 삼항연산자, 두개이상의 경우의 수
  4. 2021.06.02 React img 태그 src={require()}
  5. 2021.04.28 윈도우에서 chmod 등 리눅스 명령어가 필요할 때
  6. 2021.04.28 문자열 안에 html 태그가 있고 그걸 적용 시키기
  7. 2021.03.19 HTTP CORS 여러개의 origin 관리하기
  8. 2021.03.19 Promise.all에서 오류

Decimal calculation in Javascript

웹 개발/Problems 2024. 1. 16. 02:10

자바스크립트를 이용해 실수의 연산을 하다보면 소수점이 이상하게 나타나는 경우가 있다. 컴퓨터는 기본적으로 이진수를 이용하기 때문에 실수를 다루는 방식은 컴퓨팅 언어마다 다르다. Javascript는 모든 숫자를 IEEE 754 표준을 따르는 배정밀도 64 비트 부동 소수점 형식으로 표현하며, 이 형식은 실수를 근사치로 저장한다.

따라서 0.6 / 0.2 와 같은 연산을 실행 해보면 3이 아닌 2.999999999996 와 같은 예측에서 벗어난 값이 나온다. 이를 해결하기 위해 실수를 정수로 바꾼 후에 연산을 하고 다시 원래 실수로 돌려놓는 방법을 사용한다.

function findMostDecimal(array: number[]): number {
    let maxDecimal = 0;
    let numberWithMostDecimals = array[0];

    for (let num of array) {
        let decimalCount = countDecimalPlaces(num);
        if (decimalCount > maxDecimal) {
            maxDecimal = decimalCount;
            numberWithMostDecimals = num;
        }
    }

    return numberWithMostDecimals;
}

먼저 실수들 중에서 가장 소수점 자리가 큰 실수를 알아낸다.

export function countDecimalPlaces_10(value: number): number {
    if (!isFinite(value)) return 0; //무한대나 NaN인 경우, 0을 반환
    let text = value.toString();
    let index = text.indexOf('.');
    if (index === -1) return 1; //소수점이 없는 경우, 1을 반환. (정수이므로)
    let decimalPart = text.substring(index + 1);
    return Math.pow(10, decimalPart.length);
}

실수를 정수로 바꾸기 위해 지수를 구한다.

 

export function operateDecimals(
    value1: number,
    value2: number,
    operation: Tadjuster_method,
) {
    const mostDecimal = findMostDecimal([value1, value2]);
    const factor = countDecimalPlaces_10(mostDecimal);
    const newValue1 = Math.floor(value1 * factor);
    const newValue2 = Math.floor(value2 * factor);
    let result;
    switch (operation) {
        case 'add':
            result = (newValue1 + newValue2) / factor;
            break;
        case 'subtract':
            result = (newValue1 - newValue2) / factor;
            break;
        case 'multiply':
            result = (newValue1 * newValue2) / (factor * factor);
            break;
        case 'divide':
            result = newValue1 / newValue2; // 나눗셈의 경우, factor로 나눌 필요 없음
            break;
        default:
            throw new Error('Invalid operation');
    }
    return result;
}

이렇게 정수로 바꾼다음 연산을 진행한 뒤 지수를 다시 나눠주면 원하는 값을 구할 수 있다.

:

AWS s3 404 Not Found 에러

웹 개발/Problems 2021. 7. 2. 00:20

로컬 호스트에서는 잘 작동하지만 s3에 배포하고 나서 특정 페이지에 접근하자 404 Not Found에러 페이지가 렌딩 되었다. 하필 소셜 로그인 페이지에서 에러가 발생하여 소셜로그인 하려먼 s3에서 다른 특별한 설정을 해야 하나 하고 고심 하고 있던 찰나, 한 유튜브 영상으로 s3 배포하는 과정을 시청하던중 

이 부분을 설정하는 것을 보았다. 왠지 이것 때문에 그럴 수 도 있겠다 싶어서 바로 기본값인 error.html에서 index.html로 바꾸자 에러가 해결되었다... 항상 주의 해야겠다.

:

삽질: axios , 삼항연산자, 두개이상의 경우의 수

웹 개발/Problems 2021. 6. 2. 20:19
import React, { useState, useEffect } from 'react';
import img from 'react';
import { Container } from './UserInfoMatchingDetailStyled.jsx';
const axios = require('axios');
const MatchingDetail = ({ participant }) => {
	let [userData, setUserData] = useState(null);
	let [tier, setTier] = useState('');
	let [kda, setKda] = useState(0);
	let [rank, setRank] = useState('');
	let [isLoading, setIsLoading] = useState(null);
	console.log('participant before useEffect: ', participant);
	useEffect(() => {
		console.log('participant: ');
		console.log(participant);
		if (participant) {
			setIsLoading(true);
			console.log('participant name: ');
			console.log(participant.summonerName);
			axios
				.get(
					`${
						process.env.REACT_APP_SERVER_URL
					}/utils/history?name=${'미키주일'}`,
				)
				.then((response) => {
					let data = response.data;
					let tempKda = 0;
					console.log('data: ');
					console.log(data);
					setTier(
						data.league_solo === undefined ? 'UNRANKED' : data.league_solo.tier,
					);
					setRank(data.league_solo === undefined ? '' : data.league_solo.rank);
					if (data.matches) {
						data.matches.forEach((match) => {
							tempKda += match.kda;
						});
						tempKda = tempKda / data.matches.length;
						console.log('tempKda before Math.floor: ');
						console.log(tempKda);
						tempKda = Math.floor(tempKda * 100) / 100;
						console.log('tempKda after Math.floor: ', tempKda);
						setKda(tempKda);
					}
					setIsLoading(false);
					setUserData(data);
				})
				.catch((err) => {
					console.log(err);
					setIsLoading(false);
				});
		}
	}, [participant]);
	// useEffect(() => {
	// 	if (userData.league_solo) {
	// 		console.log(userData);
	// 		setTier(userData.league_solo.tier);
	// 	}
	// }, [userData]);
	switch (isLoading) {
		case null: {
			return '';
		}
		case true: {
			return (
				<Container>
					<fieldset>
						{participant !== null ? <div>{participant.summonerName}</div> : ''}
						{'Loading...'}
						<button
							onClick={() => {
								setIsLoading(null);
							}}
						>
							close
						</button>
					</fieldset>
				</Container>
			);
		}
		case false: {
			return (
				<Container>
					<fieldset>
						{participant !== null ? <div>{participant.summonerName}</div> : ''}
						<div>
							<img
								src={require(`../../Images/tierIcons/${tier}.png`).default}
								width={'100'}
								height={'100'}
							/>
							{tier}
							{'   '}
							{rank}
							<div>{kda !== 0 ? kda : ''}</div>
						</div>
						<button
							onClick={() => {
								setIsLoading(null);
							}}
						>
							close
						</button>
					</fieldset>
				</Container>
			);
		}
	}
};

export default MatchingDetail;

participant 변수가 들어오면 axios를 실행해 그 지연시간동안 loading...을 보여줘야했다.

로딩인지 아닌지 확인하기 위해 isLoading 상태를 설정해주었지만 participant 변수가 들어오는 순간에는 isLoading이 기본값인 false로 인식되서 reference 에러가 났다. 생각을 해보니 이것은 세가지의 경우의수가 있는 문제라서 삼항연산자로 해결을 하기 매우 어렵다고 판단해 swtich문을 써서 리턴을 각각 다르게 했다.

경우 1. participant가 안들어 온 경우

경우 2. participant는 들어왔지만 아직 로딩이 안된 경우

경우 3. participant도 들어 오고 로딩이 끝나 데이터가 들어온 경우

따라서 삼항연산자로는 힘들다. 왜냐하면 경우 2번에서 participant가 들어오는 순간에는 로딩 변수의 기본값이 false인데, axios 실행전 setIsLoading(true)를 실행하지만 그것을 실행하기 전에 이미 false로 인식이 되어 로딩이 끝난줄 알고 데이터를 뿌릴려고 했다. 리액트에서 경우가 많아질 때 절대로 삼항 연산자는 피해야 겠다.

:

React img 태그 src={require()}

웹 개발/Problems 2021. 6. 2. 20:08
<img
src={require(경로).default}
/>

require()함수 호출 후 .default 속성으로 불러 와야 이미지가 불러와진다.

구글링해서 검색해보면 사람들은 .default를 추가 안했던데 어떻게 한건진 모르겠다... 

:

윈도우에서 chmod 등 리눅스 명령어가 필요할 때

웹 개발/Problems 2021. 4. 28. 23:49

git bash를 사용하면 된다.

.ps git bash에서 paste기능은 키보드 insert키를 누르면 된다.

:

문자열 안에 html 태그가 있고 그걸 적용 시키기

웹 개발/Problems 2021. 4. 28. 22:43
let str = "안녕하세요 <br> 반갑습니다"

return (<div dangerouslySetInnerHTML={{ __html: str }}></div>)

리액트에서 지원하는 dangerouslySetInnerHTML props를 사용하되, {__html: 문자열} 이라는 객체 형태로 넣어 주면 된다.

:

HTTP CORS 여러개의 origin 관리하기

웹 개발/Problems 2021. 3. 19. 18:19

'Access-Control-Allow-Origin'의 값은 기본적으로 한개의 origin을 입력받던가 모든 오리진을 허용해주는 '*'이라는 와일드카드를 값으로 받을 수 있다.

만약 여러개의 origin을 허용하고 싶다면 따로 배열을 만들고 들어온 request의 origin이 그 배열에 포함이 되있는지 확인 하는방법을 사용할 수 있다. 확인 후에 해당 origin을 현재 'Access-Control-Allow-Origin'의 값으로 넣어주면 된다.

const server = http.createServer((request, response) => {
	let body = [];
	let allowedOrigins = [
		//multiple origin 설정하기
		'http://127.0.0.1:5500',
		'http://14.36.99.81:44949',
		'http://14.36.99.81:35911',
	];
	let origin = request.headers.origin; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@origin 가져오기
	temp = request.headers;
	console.log(
		'defaultCorsHeader[Access-Control-Allow-Origin]: ',
		defaultCorsHeader['Access-Control-Allow-Origin'],
	);
	console.log('origin: ', origin);

	if (allowedOrigins.includes(origin)) {
		defaultCorsHeader['Access-Control-Allow-Origin'] = origin;
	}
}

 

:

Promise.all에서 오류

웹 개발/Problems 2021. 3. 19. 11:44

02_promiseAll.js
0.00MB

function getNewsAndWeatherAll() {
  // TODO: Promise.all을 이용해 작성합니다
  let result = {}
  let arr = []
  return Promise.all([fetch(newsURL),fetch(weatherURL)])
  .then(rawDatas =>{
    //console.log('datas: ',rawDatas)
    arr = rawDatas.map((rawData)=>{
      return rawData.json().then(json=>{
        return json
      })
    })
    return arr
  })
  .then(promiseArr =>{
    let dataArr = []
    promiseArr[0]
    .then(data => {
      dataArr.push(data.data)
      return promiseArr[1]
    })
    .then(data=>{
      dataArr.push(data)      
    })
    //console.log('dataArr: ',dataArr)
    return dataArr
  })
  .then(dataArr =>{
    console.log('length: ',dataArr.length)
    console.log('last then dataArr: ',dataArr)
    console.log('dataArr[0]: ', dataArr[0])
    console.log('dataArr[1]: ', dataArr[1])
    result.news = dataArr[0]
    result.weather = dataArr[1]
    return result
  })
}

여기서 실행을 했을때 이상하게 마지막 then에서 받아온 인자 dataArr를 console.log찍어봤는데 undefined가 나온다.

그냥 undefined라면 모를까 두번째 console.log("last then dataArr:", dataArr) 이부분은 또 잘 나온다... 아마 promise.all사용법을 몰라서 이상하게 꼬아서 생기 문제이긴 하지만 참 신기한 문제였다... json(), fetch()와 같은 비동기 함수를 다룰때에는 조심해야겠다.

실행되는 코드:

var newsURL = 'http://localhost:5000/data/latestNews';
var weatherURL = 'http://localhost:5000/data/weather';

function getNewsAndWeatherAll() {
  // TODO: Promise.all을 이용해 작성합니다
  return Promise.all([ fetch(newsURL), fetch(weatherURL) ])
    .then((responses) => {
      return Promise.all(responses.map((response) => response.json()))
    })
    .then((responses) => {
      let result = {}
      // console.log(responses[0])
      result = { news: responses[0].data, weather: responses[1] }

      return result
    })
}
if (typeof window === 'undefined') {
  module.exports = {
    getNewsAndWeatherAll
  }
}
: